Jump to content
  • Advertisement
Sign in to follow this  
Nibor

Deferred lighting

This topic is 2688 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'm representing point lights as screen aligned quads in my deferred renderer but I have the problem of them not being drawn when the centre of the light is behind the camera (its effects should still be visible).

I understand that I need to "move" the quad to the back of the light's area of effect in relation to the camera but I can't figure out how to do this. Can anyone enlighten me? Thanks!

Share this post


Link to post
Share on other sites
Advertisement
You either use a bounding sphere instead of a screen aligned quad or you change the depth function.

My advice is to use a bounding sphere because its more precise and changing the depth function might be expensive.

Share this post


Link to post
Share on other sites
Just offset the quad's depth by the light source radius. If you *aren't* using billboarding (and if you are, why?) then all you need to do is plop the offset in the vertex shader and call it a day :)

Share this post


Link to post
Share on other sites
Thanks for the replies!

I'm aware that I need to offset the quad's depth by the radius but I can't get it to work correctly for some reason. This is what I'm doing:



Vertex shader:

VS_OUTPUT main( VS_INPUT input )
{
VS_OUTPUT output;

// Transform light position to view space
float4 position_VS = mul( float4( input.position, 1) , view_xform);

// Get the light's z component in view space
float light_z_VS = position_VS.z;

// Transform light position to screen space
output.hPosition = mul( position_VS, proj_xform );

// Determine the screen space dimensions of the quad
float4 quadSize = { input.range, input.range, light_z_VS, 1 }; // I tried adding input.range to light_z_VS here (which I think makes sense as it's in view space), which didn't work.
quadSize = mul( quadSize, proj_xform );
output.quad.x = quadSize.x/quadSize.w;
output.quad.y = quadSize.y/quadSize.w;

// Pass these straight through...
output.colour = input.colour;
output.wPosition = input.position;
output.range = input.range;
output.intensity = input.intensity;

return output;
}

Geometry shader:

{
...
float4 screenPos = input.hPosition;
float2 quadSize = vertex[0].quad*screenPos.w;

float4 quad[] =
{
{ screenPos.x+quad.x, screenPos.y-quad.y, screenPos.z, screenPos.w },
{ screenPos.x+quad.x, screenPos.y+quad.y, screenPos.z, screenPos.w },
{ screenPos.x-quad.x, screenPos.y-quad.y, screenPos.z, screenPos.w },
{ screenPos.x-quad.x, screenPos.y+quad.y, screenPos.z, screenPos.w }
};
...
}


Anything obviously wrong with what I tried? Adding on the radius in any other coordinate space doesn't make sense to me.

Using HLSL with D3D10 BTW.

Share this post


Link to post
Share on other sites
Few bits that stick out for me-- Z does not change in the projection transform. You might be able to optimize your shader for superscalar GPUs (like modern nVidia stuff) by just scaling the radius accordingly instead of going through a whole matrix transformation. Second: define 'doesn't work' here. Though the fault is mine for not asking this initially, are you sure that clipping is your problem? Try enabling wireframe display for your light quads and seeing what's going on.

Share this post


Link to post
Share on other sites
With the radius added, the light still disappears completely when behind the camera. Looking at it again I see that it also icnreases the size of the quad. I'll have a think about what that implies. (The quad is the correct size without adding an offset.)

Share this post


Link to post
Share on other sites
Instead of using a quad, try using a sphere. I suggest checking out Humus' engine. He uses a deferred engine and spheres as point lights. http://humus.name/index.php?page=3D

Download the framework 3 at the top of the page, and check out the deferred shading 2 example.[size="5"]

Share this post


Link to post
Share on other sites
There's definitely research that says the additional precision/'ease' afforded by sphere geometry is in general outweighed by setup overhead-- if you want performance, the quads are the right way to go.
(btw, I believe there's a working quad implementation there, you can try and compare it to what you're doing and see if that helps)

EDIT: Stupid idea but you can also try the Naughty Dog tile trick they discuss in the presentation. That's probably even faster, come to think of it.

Share this post


Link to post
Share on other sites
Sphere's don't really buy you too much over quads, especially for lots of small point lights. Tiled will usually start out slower than quads or volumes for small numbers of lights, but as they scale up into the dozens or hundreds tiled will start to perform significantly better since it uses much less bandwidth.

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!