shadow mapping using directional light

Started by
5 comments, last by dietrich 5 years, 3 months ago

Hello, as far as i can understand , a directional light is considered at an infinite distance, so , basically it lights up the entire scene, not only waht the viewer is actually seeing.Since this could impact performance i was wondering if there is a best practice for rendering a scene using a directional light, is it possibile to cull objects which do not contribute to casting shadows ? how is it acutally implemented in games ?

thanks

Advertisement

Directional light doesn't mean you are doing calculations for  the 'entire scene', although if a pixel is processed by the pixel shader then yes you would be doing calculations. Perhaps you are visualising some kind of ray tracing, or maybe mixing this up with real-time shadow mapping. Directional light just means that light is based on a constant directional vector as opposed to say a spot light. The traditional method would be to have a normal for the mesh, do a dot of the normal to the light direction vector and that is your light value. This is not actually physically correct and doesn't consider the light being occluded (blocked) by something but that was the standard technique for real-time rendering up until 15 years ago or so. There are better people than me to explain all of the modern techniques from ambient occlusion to the latest ray tracing methods.

If this question was about shadow mapping, then yes your question is valid. What the shadow mapped frustum sees is processed, imagine rendering the scene twice, once for the camera, once for the light. Google cascading shadow maps for a start there. 

OK, so my question is : are objects or chunks of map usually culled against the shadow mapped frustum ? is there a 'correct' way to handle directional light shadow mapping according to the number of objects contained in its frutusm ?

I don't know how it's done usually, but I would suggest you to do it the same way as you do with a normal camera. What I mean by this - when you render your scene normally on the screen (using a perspective camera), do you draw everything (and just rely on the GPU clipping) or are you checking every object against the camera frustum? If yes, then just implement it in a similar way for the shadowmapping camera (= the light camera), because that camera also has a view frustum, even when it's an orthogonal camera.

The quesiton is how to set up the light camera, because if you use just one small fixed light view volume, only objects in one part of the world will be casting shadows. If you use just one fixed view volume that covers the entire world, then you have the easiest possible solution, but you'll probably require a really huge shadowmap resolution (depends on your scene). Or, you can implement something more complicated, like cascading shadow maps mentioned by TeaTreeTim.

OK, thanks now its more clear, and yes I frustum cull objects against view camera

You can definitely cull parts of your scene for directional shadow mapping, and as TomKQT mentions, the problem is to find the correct view frustum (which in this case will just be a box due to the orthographic projection) to cull against. 

One option is indeed to render the entire scene, in which case the view volume will be a light-space oriented bounding box of the scene. While not very optimal, I've found this to be a good starting point to check if everything is working as expected.

Another is to actually compute a tight bounding box around objects required for shadow rendering. Basically, the view volume should enclose only the part of the scene, that is currently visible (i.e. whatever is inside the main camera's view frustum), plus whatever objects can cast a shadow into it. With this approach you compute a light-space bounding box around main camera's view frustum, but shift its near plane all the way back to the scene bound, repeating the process every frame to account for the main view changes.

A few more pointers:

  • cascaded shadow mapping mentioned above uses that approach, but you don't actually need to implement the cascades - or you can view it as single-cascade CSM. Anyway, it should be easy enough to extend to cascades form that point, if the need arises.
  • the volume produced by this technique is conservative - there may be optimizations to further reduce the rendered object count, that I don't know of.
  • the fact, that the light view volume is now shifting whenever the main view moves or rotates, and that there's no 1:1 correlation between the screen pixels and shadowmap texels, causes artifacts with shadow stability. You overcome those by making sure that your shadow map is translation and rotation invariant. It's a fairly big topic, again covered by many CSM descriptions.
  • same artifacts are produced whenever the shadow casting light moves (think dynamic day-night cycle). I believe this one is more complicated (if possible) to solve. I saw several games move the sun/moon in short bursts, to limit the time when the effect is visible, but don't recall any other ways to improve this, apart from increasing shadow resolution.

This topic is closed to new replies.

Advertisement