Jump to content
  • Advertisement
Sign in to follow this  
xsirxx

Point Light shader problems, still.

This topic is 4763 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been trying to implement point shaders. This is deferred lighting not that it matters, as long as ya know its pixel lighting. Here are the shaders:

float  LightRange		= {1.0};
float4 LightVector              = {0.0f,0.0f,0.0f,0.0f};

VS_OUTPUT1 main(VS_INPUT1 IN)
{
    VS_OUTPUT1 Out;

    Out.Position = mul(IN.Position, WorldViewProj);
    Out.Position2 = mul(IN.Position, WorldViewProj);
   
    // pass texture coordinates for fetching the diffuse map
    Out.TexCoord = IN.TexCoord;//.xy;

	return Out;
}
vertexfragment MRTVS	= compile_fragment vs_1_1 main();


float4 OmniLightingPS(VS_OUTPUT1 In) : COLOR
{
	half4 diffuse		= tex2D(MRT0, In.TexCoord);
	float4 Att			=(LightVector * 400 );// * LightRange;
	float4 Attenuation	= 1 - mul(Att , Att);
	return (diffuse * Attenuation) + 0.2;
}
pixelfragment OmniPixelFragment	= compile_fragment ps_2_0 OmniLightingPS();


So basically on the PS the 400 is because the it wont let me multiply the lightvector against the lightrange float(it bombs on compiling the shader(ingame)). I think its stupid but who know prolly something I did. The 0.2 is just so I can see what the hell is goin on. That being said, I get the depth of the screen being red and the objects that should be red are black. They are inversed? I have tried doing the pixel position * Lightvector and that didnt work. Ive tried almost everything I can think of. So if you have any ideas how to get this damn point light working please respond. Thanks much guys, Brad

Share this post


Link to post
Share on other sites
Advertisement
Thats the article I have used for my diffuse lighting and am going on for this. I tried doing (LightVector - In.Position2) instead of LightVector. And that doesnt do anything at all

Share this post


Link to post
Share on other sites
I thought point lights didnt need a direction, only I guess a direction straight to the vertex or point in space? With that is there a way to do this without using tangents? I thought this should work but its not...

Share this post


Link to post
Share on other sites
When debugging a pixel shader, it's important to verify each of the components of the equation you're trying to compute. In your case, try outputing just your "diffuse" value to see if you get what you expect.

Assuming that works fine, the next suspicious part in that code looks to me to be the "LightVector". Remember, light attenuation is a single float value, not a vector quantity. Since you said you were doing deferred rendering, then you most likely have a texture available with the 3D position of the pixel you're dealing with. You also need the location of the lightsource as a 3D position.

To compute the distance, you can either use the HLSL intrinsic instruction of the same name, or compute it yourself.

Once you've got the distance to the light source, you can attenuate the color accordingly. In shader code, it would look like this:

// Main application sets this to be the lights position.
float3 g_vLightPosition = float3(0.0f, 0.0f, 0.0f);

// Color of light source. Default is white.
float3 g_vLightColor = float3(1.0f, 1.0f, 1.0f);

// Range of light source. Default is 1.0f
float g_fLightRange = 1.0f;

float4 OmniLightingPS(VS_OUTPUT1 In) : COLOR
{
float3 vPosition = tex2D( positionTexture, In.TexCoord );
half4 vDiffuse = tex2D(MRT0, In.TexCoord);
float fLightDistance = distance( vPosition, g_vLightPosition );
float3 vLightColor = g_vLightColor * g_fLightRange;
return vDiffuse * float4( vLightColor * (1.0f - fLightDistance*fLightDistance), 1.0f );
}


The shader could be made a little more efficient but you should get the idea.

Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites
Hey thanks for the reply, and sorry about my lateness to it. I tried some other stuff using Nvidia's example and I cant seem to get anything to work... Here is what I used from yer example:


float LightRange = {1.0f};
float3 LightVector = {5.0f,5.0f,5.0f};
float3 LightColor = {1.0f,1.0f,1.0f};

float4 OmniLightingPS(VS_OUTPUT1 In) : COLOR
{
half4 diffuse = tex2D(MRT0, In.TexCoord);
float fLightDistance = distance( In.Position2, LightVector );
float3 vLightColor = LightColor * LightRange;
return ( (diffuse) * float4( vLightColor * (1.0f - fLightDistance*fLightDistance), 1.0f) );
}
pixelfragment OmniPixelFragment = compile_fragment ps_2_0 OmniLightingPS();




My screen shows nothing now. My VS for this is:

VS_OUTPUT1 main(VS_INPUT1 IN)
{
VS_OUTPUT1 Out;

Out.Position = mul(IN.Position, WorldViewProj);
Out.Position2 = mul(IN.Position, WorldViewProj);

// pass texture coordinates for fetching the diffuse map
Out.TexCoord = IN.TexCoord;//.xy;

return Out;
}
vertexfragment MRTVS = compile_fragment vs_1_1 main();




I am starting to really hate shaders heh. But your example mathematicly makes complete sense. where am I going wrong you think?

[Edited by - xsirxx on August 1, 2005 1:49:46 PM]

Share this post


Link to post
Share on other sites
Ok, the first thing you need to understand about debugging shaders is that you have to verify that each component you're using has a reasonable value.

So in the case of your pixel shader, the first thing you need to do is make sure it is even being run. You can do this by simply returning pure white from the pixel shader. This will make your mesh look totally white. It at least lets you know that your mesh is being transformed correctly and that the pixel shader is being run.

The next step is to make your pixel shader output just the raw diffuse color and see if you get something reasonable.

Next output just the light color to see if you get what you expect.

You can split the final equation into a few parts for verification purposes. The final equation you have is
return ( (diffuse) * float4( vLightColor * (1.0f - fLightDistance*fLightDistance), 1.0f) );

Split this up so that your shader returns just (1.0f- fLightDistance*fLightDistance) and see if you get something reasonable. Then start adding terms to this equation one by one to see if everything stays normal.

Somewhere along these steps, you'll get a result that doesn't seem correct. That will at least let you know where to look for other mistakes.

neneboricua


Share this post


Link to post
Share on other sites
The shader has been tested already, so its running. Next the diffuse color is absolutely fine(outputs.) Ill run the other tests to see more,
Thanks very much!
UPDATE:

returning...
float3 vLightColor = LightColor * LightRange;
return ( diffuse * float4(vLightColor, 1.0));

...is all black

returning...
return ( diffuse * (1.0f - fLightDistance*fLightDistance) );
...is all black

ALSO... i was wondering the position has to be in world coords right? and the light vector? or same coords that is... but I have them in world, I also changed the setupa lil. I put the position into a new render target to make sure it wasnt being messed with at all. And then I pull that back out. Any other stuff I should look out for that could be changing this?

Also every render I check the light transport to make sure that the blending is working. I both DESTS set to blend one.




--Brad

[Edited by - xsirxx on August 1, 2005 6:35:48 PM]

Share this post


Link to post
Share on other sites
As a side note, when you do some of these tests, it might be better to just output the value on its own and not multiply it by the diffuse color. The reason for this is that multiplying by the diffsue color might make everything "look" black when it just might be very, very dark.

Quote:
Original post by xsirxx
returning...
float3 vLightColor = LightColor * LightRange;
return ( diffuse * float4(vLightColor, 1.0));

...is all black

Are you initializing the "LightColor" or "LightRange" variables from inside your application or are you leaving them at the default values the shader sets up? My guess is that your application is initializing them with something. It seems like the values your application is initializing them with might be messed up.
Quote:
Original post by xsirxx
returning...
return ( diffuse * (1.0f - fLightDistance*fLightDistance) );
...is all black

ALSO... i was wondering the position has to be in world coords right? and the light vector? or same coords that is... but I have them in world, I also changed the setupa lil. I put the position into a new render target to make sure it wasnt being messed with at all. And then I pull that back out. Any other stuff I should look out for that could be changing this?

All of your position data should be in the same space for the math to work out. So make sure everything is in a consistant space (whether it be World, Tangent, Light, or whatever space).

Take it one step at a time and you'll see where the problems are. Avoid combining results in the shader until you're sure those results are valid. There's a section in the DX SDK docs on debugging shaders with Visual Studio .NET. If that's what you're using, it would be beneficial to setup your environment so that you can step through your shader code like you can normal code and see the variables in your Watch window.

neneboricua

Share this post


Link to post
Share on other sites
Ok I uploaded a picture of the position texture. I store the 3D world positions in a render target to use to compare the light distance.... This is what directx outputs:



Now remember thats not just a 8 vert box. There each of the 2 boxes the near and the far(the blue and pink do not indicate different boxes, they are seperated by depth(not side by side)), have about 1000 verts each. So how do all these verts have the same position it thinks?

UPDATE: This is the position normalized then put into the target(texture).




UPDATE2: NM I know why the colors are seperated like that, directx colors goto 1.0 not 255. Still doesnt explain the shader though :(.

[Edited by - xsirxx on August 2, 2005 8:58:01 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!