Jump to content
  • Advertisement
Sign in to follow this  
xsirxx

Lighting isnt working under deferred lighting? help pls.

This topic is 4863 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

OK I am running a deferred lighting system and simple ambient lighting working all the way through. I am also using multiple render targets. So my targets are so:
	//position
	htemp = m_pd3dDevice->CreateTexture(m_Camera->uiScreenWidth, m_Camera->uiScreenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_MRTSurf[0].tex, NULL);

    //normal
	htemp = m_pd3dDevice->CreateTexture(m_Camera->uiScreenWidth, m_Camera->uiScreenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_MRTSurf[1].tex, NULL);


    //depth
	htemp = m_pd3dDevice->CreateTexture(m_Camera->uiScreenWidth, m_Camera->uiScreenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &m_MRTSurf[2].tex, NULL);


here are my shaders for the pre render phase:
VS_OUTPUT0 SimpleVS( VS_INPUT0 In )
{
    VS_OUTPUT0 Out;

    Out.Normal		= normalize(mul(In.Normal, World));
    Out.Color		= In.Color;
    float4 tempPos	= mul(In.Position,World);
    Out.Position	= mul(tempPos, WorldViewProj);
    Out.Position2	= mul(tempPos, WorldViewProj);
    Out.TexCoord	= In.TexCoord;

    return Out;
}
vertexfragment DiffuseVertexFragment	= compile_fragment vs_1_1 SimpleVS();

PS_MRT_OUTPUT DiffusePS(VS_OUTPUT0 In)
{
	PS_MRT_OUTPUT Out;
	
	half4 diffuseTex = tex2D( DiffuseTexture, In.TexCoord);
	half3 normal = normalize(In.Normal);

	diffuseTex.w = diffuseTex.w - 0.01;
	clip(diffuseTex.www);

	Out.Color0 = In.Color * float4(diffuseTex.xyz, 1.0f);
	Out.Color1 = float4(normal, 0.0);
	Out.Color2 = float4(In.Position2.w, 0.0f, 0.0f, 0.0f);

	return Out;
}
pixelfragment DiffusePixelFragment	= compile_fragment ps_2_0 DiffusePS();

That pushes everything out to my new textures(surfaces) to be used for this deferred pass:
VS_OUTPUT1 main(VS_INPUT1 IN)
{
    VS_OUTPUT1 Out;

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

    return Out;
}

float4 DirLightingPS(VS_OUTPUT1 In) : COLOR
{
	half4 diffuse  = tex2D(MRT0, In.TexCoord);
	half4 normal   = tex2D(MRT1, In.TexCoord);

	normal = normalize(normal);
	
	return (diffuse * (saturate(dot(LightVector, normal)) + 0.5)); // the 0.5 is just so I can see everything(temp)
}
pixelfragment DirPixelFragment	= compile_fragment ps_2_0 DirLightingPS();

So that is then saved out as a LightTransport (another surface) and that is rendered normally as a plane. Everything comes out fine except there are no lights even though I pushed in about 10 of them. Meaning no lighted areas in the world. Is there something I should be doing or anything I missed? Remember a simple render without lights works fine, I think its somewhere down to the normals? Thanks much, Brad

Share this post


Link to post
Share on other sites
Advertisement
The shaders could be cleaned up a bit but I don't see anything obviously wrong. One way to debug this would be to save your render targets as BMP's after you render the first light. Use D3DXSaveSurfaceToFile to do this. Then you can load up the files and take a look at it to see if you get reasonable results.

That way, you at least have an idea as to where your problem is. If the result after rendering a single light to the temporary render targets seems reasonable, then you can focus more of your efforts in your final pass. If the results from the temporary render targets seem messed up, at least you have an idea as to where to start looking.

Once you know where to look, we might be able to help out a bit more.

neneboricua

Share this post


Link to post
Share on other sites
Quote:
Original post by neneboricua19
The shaders could be cleaned up a bit but I don't see anything obviously wrong. One way to debug this would be to save your render targets as BMP's after you render the first light. Use D3DXSaveSurfaceToFile to do this. Then you can load up the files and take a look at it to see if you get reasonable results.


Yea I did that already and the first surface is fine, displays what i am seeing. The third is fine too, shows the typical white and blue depth. The 2nd which is the normal surface shows all black. This help at all? Yea I know they can be cleaned up quite a bit, i have just changed them so many times trying to figure it out. Thanks

EDIT: Also the light position is what im using for LightVector, in world coords. The Normals are imported from 3dsmax with the rest of the meshs and such under my own exporter. The rest of the info from the meshs are all from object coords. If any of this helps?

[Edited by - xsirxx on July 21, 2005 7:20:57 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by xsirxx
The 2nd which is the normal surface shows all black.

Ok, this is definately a problem. If your normal texture is coming out all black, then in your final rendering pass, when you fetch the normal of a particular pixel, that normal will be (0,0,0).

So in your equation for calculating the light, you'll get this:
(diffuse * (saturate(dot(LightVector, normal)) + 0.5))
=(diffuse * (saturate(dot(LightVector, (0,0,0))) + 0.5))
=(diffuse * (saturate( (0,0,0) ) + 0.5))
=(diffuse * ( (0,0,0) + 0.5) )
=(diffuse * ( (0.5, 0.5, 0.5) )

So in the end, the color being output is just your diffuse color multiplied by 0.5.

Most of the time, lighting problems come down to incorrect use of normal vectors. In this case, I would double check to make sure that the matrix you're using to transform the normal vector is correct. You can use the world matrix to transform your normal vector only if your matrix is affine; that is, your transformation is composed of only rotations and uniform scales. If this is not the case, then you cannot use your world matrix to transform your normal vector.

As a quick check, use this line in the vertex shader for your pre-render pass:

Out.Normal = normalize(In.Normal);

I know its not the correct normal vector, but at least the texture you render normals into should now have something visible, even if it is not correct. If this render target does indeed have something visible, that looks like the normals from your model, then you know the problem is in the way you're transforming those normals. Otherwise, you can eliminate that as a possibility.

neneboricua

Share this post


Link to post
Share on other sites
Thanks for the help on this, I will hafta work on it tommorow. Im outta the office for the weekend, thanks for the reply ALOT ill post a new one tommorow with some outcomes. That said, you are saying to replace,

Out.Normal = normalize(mul(In.Normal, World));

with:

Out.Normal = normalzie(In.Normal);

And I should be seeing something besides black granted that the normals should not be 0,0,0. I can say before the normals enter the shader they not all 0,0,0 :). So you are most likely correct. The 0.5 was just added on there so I could see what was going on in the game. Meaning if the 0.5 wasnt in there the screen outcome would be black and I could test where the lights were placed(quick-broken-temporary-fix) heh. Ohh, and the World does contain rotations, scales, and most importantly translations. So this means it cannot work?

Thanks for the help, ill post back on monday with hopefully some better news.

UPDATE: I managed to VPN the updated code over, im an idiot. I somehow messed up the normal output from the 3ds exporter(rewrite.) So they are all 0.0. Heh so thats definitly the start of the problem. Ill fix that and update ya with where its at.

UPDATE2: Withg the normals changed, the normal target now renders green and black. Green being where the objects are.

[Edited by - xsirxx on July 24, 2005 5:47:26 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by xsirxx
Ohh, and the World does contain rotations, scales, and most importantly translations. So this means it cannot work?

Not necessarily. Translations do not affect vector direction, so you can perform any number of translations without affecting the normal. Double check to make sure that the scales you are using are uniform. If they are not, you cannot use the world matrix to transform the normal vector. Instead, you must use the transpose of the inverse of the world matrix. In the form of a pseudo-math equation, it would look like this:

N = transpose(inverse(W)),
where N is the matrix you transform normals with and W is your world matrix.

It's pretty quick to try this out. You can compute this matrix in your application and pass it along to your vertex shader just like you do the regular world matrix.

Quote:
Original post by xsirxx
UPDATE2: Withg the normals changed, the normal target now renders green and black. Green being where the objects are.

Do you mean that the objects appear totally green in the normal target? If so, that indicates that the normals are (0,1,0). I'm not sure about your input geometry, but does that seem reasonable to you? I don't think your normals should all be pointing up for every single object, unless all you're rendering is the floor.

neneboricua

Share this post


Link to post
Share on other sites

Quote:

Do you mean that the objects appear totally green in the normal target? If so, that indicates that the normals are (0,1,0). I'm not sure about your input geometry, but does that seem reasonable to you? I don't think your normals should all be pointing up for every single object, unless all you're rendering is the floor.

neneboricua


Yea it is resonable, it is rendering now :). They are just simple boxes placed throughout the world. Im not the best artist when it comes to building worlds :(. Yea so basically with the boxes it renders light where the lights are hiting it, and it renders black where you cant see them, so perfect :). As far as scaling goes it is working fine with scaling so that came out to be pretty nice.

Hey I appreciate your help alot! Im not to keen when it comes to making shaders so I assumed ALL my problems were there, and that was a stupid assumption. But again, thanks for walkin me through it, always helps to have someone who can slow ya down and point out some options and give answers.

Thanks,
Brad

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!