Conceptual questions on shadow mapping

Started by
4 comments, last by Geri 1 year ago

Hi there,

I have a couple of questions with respect to shadow mapping that I struggle to find the answers for. I understand the core process of shadow mapping. However, I'm still kind of uncertain about some implementation details.

  1. I'm assuming that you don't have to have an empty pixel shader for the light pass. You could attach a R32 Texture as the render target and write the depth values there. Is that correct?
  2. In the light pass, when manually transforming the light projected fragments from projection space to texture space, the xy coordinates should never lie outside the range [0, 1]. Is that correct?
  3. How do developers typically fix perspective aliasing? I understand that CSM can alleviate the problem by providing the correct resolution texture for the view distance. However, a very high resolution shadowmap is still required for up-close fragments. Rasterizing the scene and writing to the texture seems costly. Is that cost simply accepted, because there are no better alternatives?
  4. When using an orthographic projection for the light, how are the bounds of the frustum computed? It seems like you want to have the tightest bound possible to avoid precision related problems.

If anyone has resources or direct answers for some of these questions I'd appreciate it a lot. Thanks!

Advertisement
  1. Nope, an empty fragment shader is pretty typical.
  2. Usually the environment is considered to be not in shadow at all if the shadowmap coordinate is outside of 0-1 range.
  3. Yeah there are no real good ways to get around the shadow aliasing issue other than higher resolution shadow maps or soft shadows (or use a shadow technique other than shadow mapping like ray tracing or shadow volumes), neither of which are cheap. However, high resolution shadow maps are not nearly as expensive as you might think, since it's only rendering depth and often doesn't need to run an expensive fragment shader. One could even re-use the same command buffer (only updating the constant buffer data to use a different camera transformation) from the first shadow cascade to render more cascades which would minimise the CPU cost as well.
  4. There are a lot of ways. If you're using cascaded shadow maps, the view frustum is split into however many cascades there are and then the orthographic projections are fit around each segment of the frustum. This can also be done without CSM, you just fit one orthographic projection around the entire view frustum. For small scenes (for example an indoor house/apartment scene or a desert island scene), it may be possible to compute an AABB of the entire scene and transform that to use as the orthographic projection.

Thanks for the reply!

  1. What is the problem with the R32 texture conceptually? Why can't you just transition the fragments into texture space and write the dept of the fragment to the R32 texture? I get that it is less efficient probably, but it should produce the same results. I'm more asking conceptually, I wouldn't write such a fragment shader.
  2. I'm an idiot. I forgot that the light projected fragments are not clipped. Would you use a sampler that clamps to a depth value of 1 for out-of-bound texels?
  3. Thanks!
  4. Hmm interesting. Definitely something I need to look into more.

Sorry, I misread your question - I thought you were saying that there would be a problem with having an empty fragment shader. You're right though, you could absolutely generate a shadow texture by hand if you wanted to. Just as long as you have some some kind of way of figuring out if an object is behind another object based on a coordinate, any texture could work (could be rainbow coloured if you really wanted!).

All what i can say is i had like 20 ifs in my shadow map code back then, because it was looking differently on every video cards. Sometimes, it looked a bit differently even after driver update... Especially with early radeon cards, which had less precisity of Z buffer than their nvidia counterparts, causing a lot of artifacting. I dont think their z buffer was actually 24 bit precise. More like 22 at best.

But this was in the fixed function opengl times with gl_arb_shadow.

Now you can even compute the shadow map without any api-assisted features, so as i - assume - you want to write and read your texture data with the shader, with whatever precisity you want, however, for a shadow map bigger than 2048x2048 you will still likely need a strong 256 bit gpu with at least 1 gb ram to play safe, as this is not going to be your only thing to hog the rendering speed.

This topic is closed to new replies.

Advertisement