Shadow mapping in large environments

Started by
82 comments, last by Drilian 19 years, 12 months ago
I apologize in advance for the potential rambling nature of this post. Okay, so I'm trying to decide if I can do shadow mapping in large (mostly outdoor) environments. Initially, I would like to do this supporting just the sun (Good ol' directional light sources), but eventually I'd like to maybe have a few point lights as well (at the very least, spotlights). Anyway, working initially with directional lights (lets not mess with cube-shadow-mapped sources just yet), obviously I'd want to use an orthographic projection for the shadow map. Easy enough, and has the added bonus that objects don't really lose resolution as they get far from the light source (lack of projection shrinking and all that). Obviously, second-depth mapping would be a good idea (I can't believe I'd never heard of that before, since it seems so obvious when you think about it). But would projected (projective?) shadow mapping be something that I'd want to do, or is there a better way to ensure that I get decent resolution shadows across the whole scene? I thought about using multiple shadow maps for the sun, but I'd rather not have to use 2 shadow maps on one object (a character, say, that's straddling the boundary between the near shadow map and a far shadow map). Plus I can't figure out a good way to make the jumps in shadow quality from far to near unnoticeable). Basically, I'm hesitant to use projective shadow maps because I've read (somewhere on this forum if I recall correctly) that there are issues when looking directly at the light source (shadows melting away or the like...Actually now that I think about it I'm pretty sure it was Yann that mentioned this). Was there a way around this? Anyone have any advice (things that I'm wrong about, things that I might want to think about, etc)? Edit: Of course, not 2 seconds after posting this, I noted a few similar threads, with some good info. Anyway, I guess my major question after having read a few other threads is whether there's a way around the shadows getting all weird when looking towards the light source in Projective shadow mapping? If not, then what are my alternatives? (Of course, any other general ideas as to how to go about solving my interesting (to me) problem are more than welcome) [edited by - Drilian on September 11, 2003 4:06:56 PM]
Advertisement
The problem of projection mismatch between the eye perspective and the light perspective when looking in the direction of the light source (the so called ''duelling frusta'' problem) only appears with perspective lightsources (spots and pointlights). You don''t have this problem with orthographic lights such as the sun, since the resolution distribution of orthographic lightmaps is distance and direction independent.

I would definitely recommend the use of PSMs (perspective shadow maps) for outdoor lighting. It typically gives you a significant quality boost on near geometry shadowing, and is pretty easy to implement on orthographic lights (as opposed to pointlights, where PSMs are a real pain in the ass to get right). The increased resolution near the eye comes with some drawbacks, as usual. First, the shadowmap becomes view dependent and needs to be recomputed every frame (assuming the camera has moved). In a fully dynamic environment however, this isn''t really an issue since the maps need to be regenerated anyway.

Other drawback is, that your orthographic sunlight will now include a perspective projection. This will make it prone to the duelling frusta problem described above. But it''s not that bad either. The worst case scenario (looking directly into the sun) will essentially cancel out the PSM effect - the quality will revert back to standard orthographic shadowmaps without PSM. And this quality isn''t necessarilly bad, although much more resolution dependent than PSMs.

On the other hand, I would also suggest using multiple view dependent shadowmaps for large scale outdoor environments. Each map will cover a part of the view frustum (with small overlaps to avoid cracks). That way, you can get very good shadow quality near the camera, without requiring huge resolution PSMs. Drawback is, as you mentioned above, potentially multiple shadowmaps per face. You engine should be able to handle that. If you choose your frustum ranges and shadowmap resolutions wisely (ie. compute them beforehand), there won''t be any visible shadow-resolution seams between the maps.

All in all, my experiences with large scale SMs have been very positive, especially on complex geometry. They have some drawbacks, obviously, but much less than eg. stencil volumes. The later ones will simply saturate the hardware from a certain level of complexity on. Both by multiplying the number of faces per frame (especially when using multiple light sources) and by burning invisible fillrate like mad. I personally believe that shadowmaps are the best option for realtime shadowing available to date, assuming a complex environment. That is, until ASMs (adaptive shadowmaps) or realtime GI will be possible
Luckily, none of the point lights that I''m going to have will have a range large enough to warrant perspective maps, so I''m off the hook in that regard...Plus I''m assuming a fully dynamic world so the recalculation thing was pretty much a given.

The main reason why I want to keep the number of shadow maps in check is because I''m aiming for ps1.1 minimum support, and alot of my effects use up three texture units, which gives me one unit extra that I was hoping to use for shadow mapping. If I used four (as an example) shadow textures, I''d need to be able to handle up to four shadow textures at a time (since there''s a chance that an object would be at the intersection of all of them, at least the way I''m envisioning it). Now, with PS2.0 I could do it (and the "engine" does support that), but with ps1.1 I''d have to multipass it. Unless I''m missing something. I suppose it''s not THAT bad. Doom3''s going to be multi-pass out the wazoo and it''s turned out fine. I''d still need a pass per light at this rate (though that''s optimizable, especially when only one of the lights is a large-scale sun, and the rest are going to be small-range point/spotlights). I suppose I''d be able to single-pass the objects that AREN''T on a seam, so that would be significantly less calculation. Hmm...

I guess my next question is how best to divide up the frustum into shadow maps? And how many should I use? And what size?
After having read some older posts, I think you (Yann) said you use four maps. How do you pick what portion of the frustum they cover?

I''m imagining this little project is going to be super cool when I''m done, but it''s definitely feeling difficult right now (lucky, this is the good kind of fun difficult, not the maddening "I just want it to be over so I can stop banging my head into various wall-like substances" difficult).

And thanks for all the help, you''ve probably taken a few weeks out of my "thinking process" at least!

PSM is good, but may have clip problem with huge object.
I solve this by using LOD in PSM.

For normal shadowmap light,
you may have an editor to set the frustum of light.

And calculate the light
frustrum intersection with view frustrum to select those
shadowlights you may see.

and foreach shadow light, simply render the lightview
and shadowmap one by one.

Hi,
I have PSM from directional lights work, and going to implement point lights. I have heard many times that shadow mapping with floating point lights is a big problem (whether using PSM or not). Can someone describe more about how it is typically implemented in a real game (using current hardware)?

Say, do you actually render from the point light 6 times to form 6 shadow cube maps? And as I remember, ps1.3 only have 4 texture registers, so when you render the real scene, how do you decide which shadow map is used in the pixel shader? Or do you render the scene multiple times? (just some random thoughts from me)

I am going to implement it in my school project, so any hints are much appreciated.

Most of current games only support directional or spot
shadow like Splinter Cell.

Support a omni shadow light is a little
more complex than that.

see
http://www.mpi-sb.mpg.de/~brabec/doc/brabec_cgi02.pdf

Ive heard of perspective shadow maps thrown around. Does anyone have an implementation of such?

-ddn
I''m working up one now. I''m actually having trouble working on projecting the directional light into camera space. When the direction of the light has z=0, then the projection of the light direction has w=0, which puts the light at infinity (which it is, since w=0 in the original point), but with a z != 0, the end perspective is NOT at infinity. I''m sure I''m missing something super-obvious, but I haven''t been able to wrap my brain around it (and I''ve reread the relevant part in the Projective Shadow Mapping paper many times and haven''t been able to get any new information from it).

Can anyone help in this regard?

(I know I learned this stuff somewhere along the line, but it seems to have slipped out of the ol'' brain!)

Josh
I haven't implemented PSMs yet, but this is my understanding...
Isn't the post-perspective light position at infinity because post-perspective w is zero ? I thought if post-perspective z is non-zero then that only meant the post-perspective light direction has a component along the z-axis. Actually I thought post-perspective z was zero anyway (which means pre-perspective and post-perspective light directions are the same) because pre-perspective z and w are both zero and that's all post-perspective w depends on. For camera-space directional lights this is the only case (camera_light_z=0) where the post-perspective light is also directional (as opposed to a point light) so I think transforming the camera-space light direction into post-perspective space, so that you can subsequently determine your light projection, needs to be treated specially for this case so that you don't get the perspective divide by zero. I think one way to do this is push your post-perspective light x and y position components some large enough distance and use perspective projection or just use an orthographic projection.

AnonymousPoster: There's a bare-bones of how PSM is done at http://www.tulrich.com/geekstuff/psm/


[edited by - soiled on September 15, 2003 10:35:22 AM]
Let me better explain my issue. I have a perspective matrix:

1 0 0 0
0 1 0 0
0 0 -1.02 -1
0 0 -2.02 0

(Note that this is the transpose of a GL projection matrix - I use D3D)

Now, with a light direction of

-1, 0, 0

we get a point at infinity" light of

1, 0, 0, 0 <- w = 0, it''s at infinity

Run that through the projection matrix and you get the same vector.

Now, with a "point at infinity" light of

0, 0, 1, 0 <- again, w=0

we run it through the projection matrix and get

0, 0, -1.02, -1

This is not at infinity. And in this case, that just seems wrong somehow.

Josh

This topic is closed to new replies.

Advertisement