🔒 Locked
Blurring shadow map
Advertisement
Original Post
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.
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.
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.
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).
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).
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.
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]
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.
Advertisement