Skip to main content
GameDev.net gamedev.net
🔒 Locked

FW: Parallel Split Shadow Maps demo + source

Started by SuperLover Jun 20, 2006 at 3:47 AM 10 replies 6.3k views
Original Post
SuperLover
SuperLover
An interesting demo for shadow mapping provided by asko. ---------Original Post------------ Since I found absolutely no samples using cascaded/split shadow maps, I decided to whip up this small example based on the paper Parallel-Split Shadow Maps http://appsrv.cse.cuhk.edu.hk/~fzhang/pssm_vrcia/. Most noticable difference is that rather than picking shadowmaps in the pixel shader, I re-use a single shadowmap by rendering each split seperately. The demo, source code and more info is at http://hax.fi/asko/PSSM.html. Comments are appreciated. asko
Ravuya
Ravuya
Probably belongs in graphics programming & theory, so I am moving it there.
Zemedelec
Zemedelec
Interesting, thanks for the demo. Actually, this is PSM, or more precisely TSM with a control over splitting distance(s) and the shadowmap used is actually Res*Res*NumSplits. Increased shadowmap size with increased number of passes over the meshes that crosses split planes. One big advantage, is the lack of the tricky math behind other, single shadowmap-pass approaches.
The thing I don't like in it (and in the PSM-crowd) is that all they are very view dependant. Even small, micro-movements of the frustum cause aliasing of edges. Especially vegetation, which is missing the the demo...
So, now is the time to make a demo, where cascades are somehow aligned in the world space so shadowmap doesn't move at every frustum change. Then it can look very good even with 2x2 PCF, imho.
Guoshima
Guoshima
very nice clean demo. Thank you :)

regards,
Kenzo
krausest
krausest
Quote:
Original post by Zemedelec
Interesting, thanks for the demo. Actually, this is PSM, or more precisely TSM with a control over splitting distance(s) and the shadowmap used is actually Res*Res*NumSplits. Increased shadowmap size with increased number of passes over the meshes that crosses split planes. One big advantage, is the lack of the tricky math behind other, single shadowmap-pass approaches.
The thing I don't like in it (and in the PSM-crowd) is that all they are very view dependant. Even small, micro-movements of the frustum cause aliasing of edges. Especially vegetation, which is missing the the demo...
So, now is the time to make a demo, where cascades are somehow aligned in the world space so shadowmap doesn't move at every frustum change. Then it can look very good even with 2x2 PCF, imho.


Maybe I'm missing something, but in what way is this PSM or TSM? I only found it using four SSMs (standard shadow maps), i.e. there's no shadow map parametrization!
And one advantage of PSSM is that it's much less view dependant than methods applying shadow map parametrization like TSM and PSM.

As for the single pass vs. multiple passes debate I'd like to add that my demo using PSSM runs faster with multiple passes than with a single pass. There's no need for a shader to choose the right shadow map and you save video memory.

Yours,
Stefan
Niwak
Niwak
Regarding the multipass vs singlepass ; you can pack your 4 512x512 shadow map in a single 1024x1024 shadow map. The shader then select the shadow map area and perform texture wrapping explicitely. It saves you FBO switches when rendering shadow map, then it saves you 3 texture units when rendering.

I have not yet implemented this (I'm investigating PSSM right now), but it should make the single pass method faster on hardware with dynamic branching, and easier to integrate in an existing engine.

Vincent
Zemedelec
Zemedelec
Quote:
Original post by krausest
Maybe I'm missing something, but in what way is this PSM or TSM? I only found it using four SSMs (standard shadow maps), i.e. there's no shadow map parametrization!

It cuts the frustum into splices, which approximate exactly what PSM/TSM tries to do continiously. In terms of resources, PSM/TSM uses much smaller texture, also (which is the main source of quality when it comes to PSSM and number of splices).

Quote:
Original post by krausest
And one advantage of PSSM is that it's much less view dependant than methods applying shadow map parametrization like TSM and PSM.

It is not, in fact. Every rotation of the camera causes view dependance, as in PSM/TSM. The only difference here is, that the shadomwap samples have more squarish form for PSSM. I would like to see this demo, rendering animated vegetation...

Quote:
Original post by krausest
As for the single pass vs. multiple passes debate I'd like to add that my demo using PSSM runs faster with multiple passes than with a single pass. There's no need for a shader to choose the right shadow map and you save video memory.
Yours,
Stefan


That imho depends on the scene. As the number and size of objects increase, you'll have more vertices to process each splice (more vertices, processed multiple times because of the size of the objects).
Imagine terrain, using splatting - almost all near-by splat will be rendered multiple times.
And the right optimization here, for single pass method is the right set of shaders - always sample only the shadowmaps, that project onto the object, not more. So objects that fall entirely into single splice, should be rendered only with one shadowmap.

Zemedelec
Zemedelec
Quote:
Original post by Niwak
Regarding the multipass vs singlepass ; you can pack your 4 512x512 shadow map in a single 1024x1024 shadow map. The shader then select the shadow map area and perform texture wrapping explicitely. It saves you FBO switches when rendering shadow map, then it saves you 3 texture units when rendering.

I have not yet implemented this (I'm investigating PSSM right now), but it should make the single pass method faster on hardware with dynamic branching, and easier to integrate in an existing engine.

Vincent


You must do the texture offset in the PS, so you get an dependant read. Then, 512^2 effective shadowmap resolution is NOT something you would like to see in reality... :)
1024 is the smallest possible candidate in the world of today, imho. And packing them into 2048... anyway, this is not the thing that will be used on consoles.. :)

Interesting is, that 3DMark guys switched from two-sliced PSM, to multiple-sliced cascaded shadows. I don't know if their cascades are world space, or are aligned to frustum slices, however.
I think that 2-sliced PSM is superior, but never tested it.
weary
weary
In either multi-pass or single pass, does everyone just let the depth determine the shadow map used? Or are there other schemes out there like doing it on a object basis?

One interesting addition I tried is to fmod the XY coordinates by the width of one shadow texel in world space ( radius*2 / shadow resolution ). This insures that the shadow texels don't move in world space, and always stay the same size. Unfortunately you also need to use a bounding sphere around each frustum splice to insure the texel sizes don't change.

What I found is that in order to get adequate resolution using this technique I would need something like 6+ 1024^2 maps or 4+ 2048^2 maps.

Also, while locking pixels in world space fixes the shimmering pixel problem, it makes the transitions between splices much more noticable (even more so with bigger PCF kernels). Has anyone addressed some kind of blending for this? If each map was exactly 2x or 3x the size of the last it might help, but I haven't tried that yet; I was also thinking of varying the size of the PCF kernel based on the slice.

In any event, due to the shear number of shadow maps and resolution required I think I may have to resort back to LiPSMs or TSMs in the end. I'll follow this up in parallel and let you know how it goes

Eric

weary
weary
Hey.. I figured since you made a nice demo with source that I would add my changes (locking shadow pixels in world space) to your source and see how it compared.

Viola:

http://www.cpsc.ucalgary.ca/~pennere/projects/pssm_demo_penner_mod.zip

I just hacked it in quickly so no comments on my code ;)

In the end I think its really a toss up between shadow resolution and the typical "shimmer" you see with adaptive approaches. If you get enough resolution with an adaptive approach you will get nice hard shadows and not notice the shimmer. However, if your screen resolution gets too big or your shadow-map resolution gets too small, you see the shadow pixels flying around and it can be distracting.

To lock the shadow texels in world space I had to using a bounding sphere around each frustum slice as in the worst possible case (dueling frusta with the camera frustum rotated 45 degrees around the light axis) that is the size the shadow map will be. To keep the shadows static, I just fmod the sphere center by the size of a shadow-map pixel in world space. Unfortunately this is a huge waste of space compared to the original technique in some cases (worst case it is the same).

Interestingly, you start to see all the different shadow map resolutions pop-in now, since otherwise the shadow pixels are static. I have some ideas for removing those transitions which I mentioned in my last post.

I think what would look really nice is to start at some sphere size and keep doubling or trippling it, each time taking off the biggest piece of camera frustum that you can. Instead of letting the frustum slice size determine the sphere size, I think the resolution should determine the amount of frustum you can bite off next. This way shadow pixels will be aligned much like mip-maps degrading in powers of 2 or 3.

Anyway its a great demo, and was nice to play around with. Let me know what you think of the changes,

Eric

[Edited by - weary on July 4, 2006 1:45:26 AM]
Zemedelec
Zemedelec
Quote:
Original post by weary
In any event, due to the shear number of shadow maps and resolution required I think I may have to resort back to LiPSMs or TSMs in the end. I'll follow this up in parallel and let you know how it goes


What about cascaded PSM/TSM ? :)
Two cascades, and the quality is very good.
weary
weary
Question for Asko:

I noticed you linearize your depth buffer by using the suggestions in this article:

http://www.mvps.org/directx/articles/linear_z/linearz.htm

What I was wondering was if this works for shadow buffers. My thinking is that for a projective transform the depth values would no longer be interpolated correctly per pixel which would result in incorrect shadows over large triangles. Maybe I'm wrong though in which case I will definately use it.

Let me know your thoughts,

Eric

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.