3DMark06, Cascaded Shadow Maps (CSM)

Started by
34 comments, last by wolf 18 years, 2 months ago
- The center position: I think a good idea would be to put the center of the frustra at 1/3 of the current size of the frustum, in the direction of camera. Like this you waste a lot less SM space. What offset sizes do you think between the different frustum sizes? I tried times 2, but then you get a frustum with 4 divisions such as this:



Is this is a good way to subdivide ? If you start with a shadow map of 32m x 32m, you can cover 'only' 256m / 3 * 2 = 170m .. which perhaps might even not be enough.

The thing I don't like about the multiple shadow maps is that you have to shade your scene also with the subdivided frustums, and this doesn't really work well with deferred shading and feels counterintuitive. You could select the shadow map to render depending on the distance (as wolf suggested I think), but then you have to give all the shadow maps to the shader, have a lot of texture memory swapping (shadow maps are rather big uncompressed textures), and it's always better to avoid branching I think. I tried it before and it works fine. I even increased the PCF when sampling the shadow maps closer to the camera.

I presume (not sure yet, cause I'm writing here as I am thinking :)), that you could do the following:

- cull scene with all object which will be shaded (shadow receiver objects)
- cull all possible object which can contribute shadows into a single visible array (shadow caster objects)
- devide the visible array into different frustra, 4 here
- repeat for each frustra (starting with furthest)
* render shadow caster objects from frustum in a shadow map
* render shadow receiver objects within this frustum, using shadow map to another RGBA texture in screenspace, and only store black and white and perhaps perform some PCF here
- now we have the complete projected shadow map into a single texture for the scene -> blur it.
- render the shadow receiver objects again (all of them), using the RGBA shadow map.

This seams like the easiest method, because you don't really have to modify your shading system to work with multiple frustra.

Someone else posted another very nice link to Variance Shadow Map. But I would only use the Variance Shadow Maps for point and spotlights, cause I think it would work best there.

All comments welcome of course
Advertisement
to magnus:

that's what I though in the beginning as well, but have you already taken a good look at battlefield or battle for middle earth 2. The shadows are bad! With wrong directions you always manage to make them look really really ugly if you use a perspective correction. Perhaps if you would blur them somehow it could work. But I think with method I described above, you only have to render the objects once more, with a cheap shader, and it doesn't consume more texture memory than normal TSM, and it has far less special cases on quality level (at least I think :))
it all depends on the scene/light height/geometry size/height etc but
pick a fixed minimum size, depending on geometry size etc
eg 4meters overlap, so with the original drawing that goes 1-5, between each frustum u have a 4meter overlap, eg frustum 2 may contain fully frustum 1 (if frsutum 1 is 2 meters wide), but by the time u reach frustum 5 (2^5=32meters wide) it only contains a small % of the previous frustum, the problrem with your drawing Guoshima is theres a lot of overlap which equals a lot of wastage

Quote:that's what I though in the beginning as well, but have you already taken a good look at battlefield or battle for middle earth 2. The shadows are bad! With wrong directions you always manage to make them look really really ugly if you use a perspective correction.

theyre not uising CSM i assume then but some sort of perspective shadowmaps (from what ive seen its not possible for the various perspective SM methods to work great from all view angles, sometimes the best u can hope for is just the same as normal SMs )
hmm .. I don't really understand how you subdivide your frustra then. Could you make a quick sketch or explain in a little bit more detail then pls. I have modified my preview a little bit. Each region has its own color, and overlaps the previous and next region.

Image hosting by Photobucket

but like i said it all depends on the scene, one thing to watch out for are tall objects offscreen (eg pylons trees) casting shadows in the screen
I see, but like you mentioned. How do you take care of tall object casting shadows into the scene like this, but not visible in your frustum. That's what I had this big region behind me.
Hi guys,
I have one question. The idea of using a screenspace black and white texture to store intermediate results was mentioned several times so far.
How do you store several lights in a texture like this?
I assume you can not render just four times into this texture. So do you store four point lights for example in the four channels of this texture? If yes, is this fast enough? Is there a way just to render all four lights into the black and white texture?
If I would render only all non-white values into this texture four or more times, shouldn't that work? I would need to render back-to-front. Just an idea. Anyone tried this?

- Wolf
well I haven't been able to test it, but it seams possible to me to render all the lights into the same black and white texture. It basically just the scene shadowed, without shading, so using depth testing, and z-write this should work no? Or am I forgetting something important here again? ;)
I'm probably missing something but, wouldn't storing intermediate results in a texture more or less invalidate any MSAA scheme?
Maybe it's just one of those things that looks good enough, even though you don't get correct results.

Consider a multisampled pixel like this:
 _______| A | B ||---+---|| C | D | -------


The simplified equation for the pixel then becomes something like this:
Output = (ShadowA * LightingA + ShadowB * LightingB + ShadowC * LightingC + ShadowD * LightingD) / 4

Now for the intermediate shadow texture, we can't have AA (right?), so we get:
IntermediateShadow = (ShadowA + ShadowB + ShadowC + ShadowD) / 4

And the output:
Output = (IntermediateShadow * LightingA + IntermediateShadow * LightingB + IntermediateShadow * LightingC + IntermediateShadow * LightingD) / 4

Which is different from the original.

Edit: Should have mentioned that I did the same thing but instead i build the shadow mask using stencil volumes and precomputed shadow maps and I did get artifacts (halos) when using MSAA.
Quote:Original post by Guoshima
I see, but like you mentioned. How do you take care of tall object casting shadows into the scene like this, but not visible in your frustum. That's what I had this big region behind me.


yes its a major hassle (big offscreen objs casting shadows onscreen)
the main reason ive put the high towers in my game is for that, ie test it with the worse possible data,
http://uk.geocities.com/sloppyturds/CC/2005_11_06D.jpg
u can workout the minimum offscreenn dist a SM has to cover by based on max_object height * tan(sun_angle) or something maths aint my strong suit,
then again u can always find some angle thats never gonna work eg having the sun 1 degree above the horizon.
the best bet is to each frame measure the objs around the camera and fit your shadowfrustum to their area as small as possible. one bad side affect with this is u may notice shadow flickering as youre constantly changing the shadow frustum thus a pixel that was in shadow one frame isnt in the next, though PCF etc will help with this

This topic is closed to new replies.

Advertisement