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

Variance Shadow Maps - light bleeding

Started by Porkwich Jul 3, 2007 at 6:20 PM 5 replies 2.4k views
Original Post
Porkwich
Porkwich
Hi all- I've been implementing basic VSM lately, but I'm having a hard time with the classic light bleeding problem. The main problem is that the light bleeds VERY strongly. Using p_max = linstep(min,max,p_max) from this thread, I have to set min to 0.8 (even 0.9 in cases) to get rid of the bleeding, which, predictably, has undesirable results. I'm just trying to figure out why the bleed is so strong in my implementation. It's nowhere near as bad in the 1-30-07 VSM demo, for example, so the linstep works well. The immediate idea is probably that I have one occluder near the light, then other occluders and receivers far away from the light but near each other. This is really not the case, though. The light is supposed to be the sun, so it's far away from everything. It may be intersting to note that the bleed tends to be very strong close to the second occluder, and weakens as the distance from the occluder increases. Has anyone seen this before or any ideas what I might be doing wrong? Some details that may be relevant: -Map format is currently G32R32F. 16 bit formats were basically unusable. -GPU is a Radeon X1900. -I'm doing a bilinear filter in the pixel shader, as well as a single-pass guassian on the map. I've tried with only one of these at a time, and the bleed behavior is the same with either. -I'm using a tiny vsm_epsilon as a minimum variance. -I switched to a linear depth metric: distance(world_position, light_position) * (1.0 / (far_clip - near_clip)) Any suggestions would be welcome. :)
AndyTX
AndyTX
The severity of light bleeding is proportional to the distances between the three involved occluders/receivers.

Suppose object 1 is at distance d_1, and so forth for objects 2 and 3 (where object 1 casts a shadow edge on object 2, which fully occludes object 3, but due to light bleeding there is some light on object 3). Then the severity of the light bleeding is proportional to the ratio (d_2-d_1):(d3-d2). In particular, if the distance between objects 1 and 2 is large, but 2 and 3 are close together, the light bleeding can be quite severe.

Unfortunately there is no perfect solution without taking more samples (period - not just with VSM). The options are to play with the light bleeding reduction stuff (as you have done), use a hybrid PCF/VSM implementation where multiple VSM samples are taken and averaged, use VSM as an oracle for PCF, use an adaptive VSM algorithm (if in a penumbrae, subdivide and recurse), and/or accept the artifact and try to minimize it in your scene. (Note that the unfortunate consequence of falling back on a PCF-like algorithm is that biasing problems with be reintroduced which is highly undesirable IMHO.)

One other options are to look into "convolution shadow maps" which are similar to VSM and Deep Shadow Maps, except they represent the visibility function using Fourier terms. Unfortunately quite a few terms are needed to make them usable even in "toy" scenes (16+) and I anticipate even greater trouble in "real" scenes.

The final option is to wait a bit - I'm currently working on some methods of scaling up the number of terms in VSM which should result in more accurate shadows (less light bleeding) at the cost of more storage and memory bandwidth (but very little compute most likely). The research is very promising so far, but I need some more time to mess around with it before I determine whether it is robust and suitable for production environments.

I hope that helps a bit. Please let me know if you have any further questions.

PS: Your implementation details look just fine - great even. Hopefully we can address your light bleeding problems.
wolf
wolf
what you also might try are the Markov inequalities and Chernoff bounds .. so the idea is just to use a different probability function.
Porkwich
Porkwich
Quote:
Original post by AndyTX
The severity of light bleeding is proportional to the distances between the three involved occluders/receivers.

Suppose object 1 is at distance d_1, and so forth for objects 2 and 3 (where object 1 casts a shadow edge on object 2, which fully occludes object 3, but due to light bleeding there is some light on object 3). Then the severity of the light bleeding is proportional to the ratio (d_2-d_1):(d3-d2). In particular, if the distance between objects 1 and 2 is large, but 2 and 3 are close together, the light bleeding can be quite severe.


Ah ha. That explains it, then. I was under the impression from previous posts that the distance from the light was part of the ratio, which would have meant there would be no significant light bleeding from sun light.

Quote:
Original post by AndyTX
Unfortunately there is no perfect solution without taking more samples (period - not just with VSM). The options are to play with the light bleeding reduction stuff (as you have done), use a hybrid PCF/VSM implementation where multiple VSM samples are taken and averaged, use VSM as an oracle for PCF, use an adaptive VSM algorithm (if in a penumbrae, subdivide and recurse), and/or accept the artifact and try to minimize it in your scene. (Note that the unfortunate consequence of falling back on a PCF-like algorithm is that biasing problems with be reintroduced which is highly undesirable IMHO.)


Any ideas on a good method of detecting penumbrae with a filtered map?

Quote:
Original post by AndyTX
One other options are to look into "convolution shadow maps" which are similar to VSM and Deep Shadow Maps, except they represent the visibility function using Fourier terms. Unfortunately quite a few terms are needed to make them usable even in "toy" scenes (16+) and I anticipate even greater trouble in "real" scenes.


I did read the CSM paper before implementing VSM. It didn't seem workable for my situation. (I can't remember the exact reason off the top of my head)

Quote:
Original post by AndyTX
The final option is to wait a bit - I'm currently working on some methods of scaling up the number of terms in VSM which should result in more accurate shadows (less light bleeding) at the cost of more storage and memory bandwidth (but very little compute most likely). The research is very promising so far, but I need some more time to mess around with it before I determine whether it is robust and suitable for production environments.


Sounds good. The only mentions I've read of attempts at using higher moments did not improve results...

Quote:
Original post by AndyTX
I hope that helps a bit. Please let me know if you have any further questions.


Absolutely. If nothing else, I know that I'm not doing anything wrong and that I have to shift gears.

Quote:
Original post by wolf
what you also might try are the Markov inequalities and Chernoff bounds .. so the idea is just to use a different probability function.


Thanks, this is the first thing I'll look into. :)
AndyTX
AndyTX
Quote:
Original post by Porkwich
Any ideas on a good method of detecting penumbrae with a filtered map?

Yeah actually VSM can do that fairly readily: each "tail" of Chebyshev's inequality gives a bound on the probability "p" of light getting to the given surface point. Using both of the tails (or basically just the standard two-tailed Chebyshev's inequality), you can get upper and lower bounds on "p" from which one can decide if the surface is suitably guaranteed to be fully in light or in shadow. I know of one person who implemented such a scheme, falling back on PCF in penumbrae regions and using summed-area tables to eliminate huge portions of shadow map at a time and who was quite happy with the results. This was in an offline renderer though so it may be overkill for real-time, depending on how much of your screen you expect to contain high-frequency shadows.

Quote:
Original post by Porkwich
Sounds good. The only mentions I've read of attempts at using higher moments did not improve results...

Yeah higher moments doesn't seem like a good solution, but what I'm working on actually extends VSM in a different way that makes better use of the data and doesn't require ridiculously high precision formats (you though the 2nd moment was unstable?? :)).

Quote:
Original post by Porkwich
Absolutely. If nothing else, I know that I'm not doing anything wrong and that I have to shift gears.

Fair enough - let me know how it goes.

Quote:
Original post by Porkwich
Quote:
Original post by wolf
what you also might try are the Markov inequalities and Chernoff bounds .. so the idea is just to use a different probability function.

Thanks, this is the first thing I'll look into. :)

I'd be interested in hearing more details about this. I briefly looked into different ways to reconstruct the probability function (Chebyshev's inequality isn't necessarily the best approximation although it does happen to be exact in the most common case), but didn't have enough time to do it justice. Do you actually know of a better way to reconstruct the function, or do you just feel that looking into Markov inequalities might be a useful area for further research (I agree)?
Porkwich
Porkwich
Quote:
Original post by AndyTX
Quote:
Original post by Porkwich
Any ideas on a good method of detecting penumbrae with a filtered map?

Yeah actually VSM can do that fairly readily: each "tail" of Chebyshev's inequality gives a bound on the probability "p" of light getting to the given surface point. Using both of the tails (or basically just the standard two-tailed Chebyshev's inequality), you can get upper and lower bounds on "p" from which one can decide if the surface is suitably guaranteed to be fully in light or in shadow. I know of one person who implemented such a scheme, falling back on PCF in penumbrae regions and using summed-area tables to eliminate huge portions of shadow map at a time and who was quite happy with the results. This was in an offline renderer though so it may be overkill for real-time, depending on how much of your screen you expect to contain high-frequency shadows.


I'm not following here (probably due to my slowness with the math)... Isn't it only going to suitably guarantee that I'm in shadow in the region where light bleeding isn't occuring? Otherwise there wouldn't be a problem to begin with? If I'm missing something here, could you explain in terms of variance, mean and depth?

Quote:
Original post by AndyTX
Quote:
Original post by Porkwich
Sounds good. The only mentions I've read of attempts at using higher moments did not improve results...

Yeah higher moments doesn't seem like a good solution, but what I'm working on actually extends VSM in a different way that makes better use of the data and doesn't require ridiculously high precision formats (you though the 2nd moment was unstable?? :)).


Very interesting... Can't wait to see the results of this.

Quote:
Original post by AndyTX
Quote:
Original post by Porkwich
Absolutely. If nothing else, I know that I'm not doing anything wrong and that I have to shift gears.

Fair enough - let me know how it goes.


Presently, I'm attempting to determine if a point should be in full shadow, and for those points clipping most of the tail. If this can be made to work, the light bleeding would only occur in penumbra regions and likely be hard to notice, while still getting rid of the aliasing/acne problem that I wanted to solve to begin with.

I think right now I just need to find a decent solution, then wait for Gems3, ShaderX6, and results of further research before doing another pass to see if things can be optimized.
AndyTX
AndyTX
Quote:
Original post by Porkwich
I'm not following here (probably due to my slowness with the math)... Isn't it only going to suitably guarantee that I'm in shadow in the region where light bleeding isn't occuring? Otherwise there wouldn't be a problem to begin with? If I'm missing something here, could you explain in terms of variance, mean and depth?

Each of the bounds will provide a conservative "estimate" as to whether that region is entirely in shadow (or conversely entirely in light). Similar to how the current Chebyshev upper bound is often far too loose (i.e. in light bleeding regions), the other tail will be too loose in some cases as well. So basically the two tails will be able to quickly dismiss many of the "simple" regions of all light/all shadow, but in some cases they will be inconclusive and more samples must be taken. This isn't a problem with VSM per se - it's actually a fundamental complexity difficulty with visibility determination. Otherwise GI would be easy ;)

So basically there are tons of options. One can use VSM just as an "oracle" and use PCF when the results are inconclusive. One can use VSM and when inconclusive, subdivide the region down to some level (basically "adaptive" VSM), or even further hybrids like subdividing a few times, then falling back on PCF.

Quote:
Original post by AndyTX
Very interesting... Can't wait to see the results of this.

Yeah I'm excited with my initial tests - I just haven't had much time to pursue it further in the last few weeks since I've been busy with SIGGRAPH stuff. I'll certainly keep people informed on progress though.

Quote:
Original post by AndyTX
Presently, I'm attempting to determine if a point should be in full shadow, and for those points clipping most of the tail. If this can be made to work, the light bleeding would only occur in penumbra regions and likely be hard to notice, while still getting rid of the aliasing/acne problem that I wanted to solve to begin with.

My recommendation is to either use a really aggressive light bleeding reduction function (you'll lose shadow detail, but that may or may not be important to you), or to use a hybrid strategy as discussed above.

Quote:
Original post by AndyTX
I think right now I just need to find a decent solution, then wait for Gems3, ShaderX6, and results of further research before doing another pass to see if things can be optimized.

Makes sense. I'm hoping that VSM is just the beginning of some better ways to tackled shadows and visibility in general. Convolution shadow maps are interesting to me for several reasons, but they're probably not suitable for game usage yet. There are many ways to store, combined and reconstruct the visibility function (piecewise-linear as in Deep Shadow Maps, moments as in VSM, fourier series as in CSM, etc), but not so many that are linear. The big advantage of a linear representation of course is that you can use hardware filtering and arguably more importantly: multi-sampling.

In any case, good luck with your application!

Topic Locked

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

Sign in to reply to this topic.