Jump to content
  • Advertisement
Sign in to follow this  
mancubit

Deferred Rendering and Culling of Lightvolumes

This topic is 2831 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 often read that when you are doing deferred lightning by using lightvolumes, you have to test if you are inside this volume to decide if you render backfaces or frontfaces. Thats no problem so far, but i am experiencing artifacts when the near plane of the viewport intersects the lightvolume so that parts of the backfaces and frontfaces are seen at the same time. The easiest solution would be to turn of culling at all for this case, but i wonder why this is never mentioned in any text? The downside is, that the lighting calculations need to be done twice then, and usually if this problem happens the calculations are applied to many pixels as the volume is at the nearplane.

Are there any better solutions? I have attached an image to clarify the problem..

thanks for your help!

[attachment=1584:deferred-culling.gif]

Share this post


Link to post
Share on other sites
Advertisement
I did this recently and I came up with a method that seems to work no matter how the camera is positioned in relation to the light volume. It uses two passes, first to fill the stencil buffer and then to light the affected scenery (like you probably already has). Pass one renders *both* front and back faces with stencil fail op INVERT and color/depth writing disabled, the second pass renders fragments which has a non-zero stencil value. I can't take credit for this method, I worked it out from a thread here on GameDev, try searching for light volumes. You can also try googling for stencil shadow techniques, the methods are basically the same.

The stencil setup for pass 1:
desc.DepthEnable = true;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = D3D11_COMPARISON_LESS;
desc.StencilEnable = true;
desc.StencilReadMask = 0xFF;
desc.StencilWriteMask = 0xFF;
desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INVERT;
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_INVERT;
desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;


The setup for pass 2:
desc.DepthEnable = false;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
desc.StencilEnable = true;
desc.StencilReadMask = 0xFF;
desc.StencilWriteMask = 0xFF;
desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL;
desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL;

Share this post


Link to post
Share on other sites
thanks! stenciling is a great solution - dont know why i never thought of that..

as for inverting - i dont understand why exactly you are inverting - but i try to get my head around

Share this post


Link to post
Share on other sites
The "quick and dirty" solution (without stencil) is to render only the back faces of the light volume, inverting the z test. This lights every pixel that is in front of the back side of your volume, rather than all the pixels behind the front side (which might get clipped), thus solving the camera inter-penetration problem.

Share this post


Link to post
Share on other sites

The "quick and dirty" solution (without stencil) is to render only the back faces of the light volume, inverting the z test. This lights every pixel that is in front of the back side of your volume, rather than all the pixels behind the front side (which might get clipped), thus solving the camera inter-penetration problem.


works great - but why is it dirty? like the simplicity of it :)

Share this post


Link to post
Share on other sites
Because it ends up calculating lighting fragments "outside" (potentially far in front of) the volume. This can be an advantage for more realistic specular, but it's obviously not as efficient as a two-pass stencil approach that effectively culls all fragments outside the volume.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!