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

Blurring shadow map

Started by O-san Apr 4, 2009 at 5:05 AM 4 replies 6.2k views
Original Post
O-san
O-san
Hi! I am trying to blur a shadow map but am having some performance issues. The easy solution; sample the neighboring fragments (shadow2D()) as many times as desired and divide the result equally. This causes bad performance with just 4 samples. I have heard about using Gaussian blur in two passes to reduce number of sampling required (one horizontal and one vertical pass). I just can not picture how such a thing would work using shadow mapping. Do I need to render my scene two times using different shaders and then a third shader to combine the result to the final scene? Sorry for any bad English.
samoth
samoth
Are you aware that blurring a shadow map will not give correct results (unless you use VSM)? You can't just run a blur filter over traditional shadow map depth values and get back something meaningful.
O-san
O-san
I've got reasonably good result using a 3x3 blur. I just want to get rid of some of the jaggedness of the shadows. I am not too concerned about umbra and penumbra correctness. Just I haven't figured out a way to do it in two passes to reduce shadow2d calls.
samoth
samoth
Well, ok... you'd do one pass where you sample horizontally (x-dx, x, x+dx) and one where you sample vertically (y-dy, y, y+dy) then. That way, you have 3+3=6 texture fetches instead of 3*3=9.
Google for "separable filter".
samoth
samoth
One thing I forgot to mention: if you place your texture samples intelligently, you can do your 3x3 filter with 2+2 instead of 3+3 texture fetches, thanks to interpolation. Or, you can stay with 3+3 samples, which will effectively give you a 5x5 filter.
The hardware will interpolate "for free" if you sample between texels, and by moving closer to one or the other, you can control how much influence each texel will have.
MJP
MJP
Blurring a shadow map does not make any sense. It's not about getting "correct" penumbras...it won't give you penumbras at all. You don't want your shadow map comparison to be "shadowFactor = avg(shadowMapDepth) >= fragmentDepth", you want it to be "shadowFactor = avg(shadowMapDepth >= fragmentDepth). This is why PCF works: you perform a depth comparison for each sample and then average the results.

What some people do (and I'm not a fan of) is they render out only the result of the shadowmap comparison to a separate texture before doing the main pass. Then they blur this texture, and send it to the main pass so it can sample the texture to get the shadow occlusion factor. This "works" because you've done the depth comparison first, and then you do the filtering. (This is the technique described by by the paper linked to by dpadam450). I'm not a fan of the technique, since it produces an evenly-sized penumbra no matter how far away the surface is from the camera. You can also get "light bleeding" if you don't take depth into account when blurring the occlusion texture.

If you are doing a full-screen blur or guassian blur for any reason, you definitely want to do it in two passes. Like samoth mentioned, you end up with 2*N texture samples instead of N*N (where N is the size of your filter kernel). It's very simple to implement: in the first pass, you only gather samples horizontally or vertically and then average them (or apply guassian weights). Then in the next pass, you sample the results of the first pass either horizontally or vertically (whatever you didn't do in the last pass).


dpadam450
dpadam450
Well as long as you keep the original depth texture and the blurred one, you will be fine. Because the blurred one tells you a little bit about what is around this pixel, you can say first if its in shadow, and if it is, see what the other pixels are like around this shadowed pixel.
NBA2K, Madden, Maneater, Killing Floor, Sims 
O-san
O-san
Thanks for the replies!

I think I'll go with dpadam450 suggestion. I am aware of the drawbacks of blurring the shadow map. However, I'm using an isometric perspective (things do not get smaller with distance) so I think can get away with the shadow blurring not getting smaller with distance.

What I am worried about is that the shadow will bleed into other geometry since it will be sampled in screen space. I can however not see this effect in the dropship scene. Is it possible to avoid it somehow?

[edit]Oh, didn't read the replies thoroughly first time around. Taking depth into account when blurring. I'll try this out. Thanks everyone[/edit]

Topic Locked

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

Sign in to reply to this topic.