Some Help with Variance Shadow Maps

Started by
5 comments, last by AndyTX 16 years, 11 months ago
So I've been messing around with VSMs for the past few days when I noticed that my "sphere demo" didn't seem to be shadowing quite right. The demo consists of a bunch of spheres inside a large cube with a light rotating around inside the cube. Ordinary shadow maps project onto the wall of the cube and other spheres quite well, but my VSM implementation seems to miss other spheres completely. I've included an example image below: Free Image Hosting at www.ImageShack.us I've turned off blurring and some hardware filters in the example image to emphasize the problem. Notice how several of the spheres on the bottom layer should be almost completely shadowed yet still seem to be receiving a lot of light. It doesn't seem like it's a depth issue as the floor underneath the bottom layer of spheres seems to be shadowing correctly. Details: DirectX 9 April 2006 SDK Texture Format: D3DFMT_G16R16F (2x 16fp) Running on a NVIDIA 7900GTX GO Any help or comments would be greatly appreciated! Edit: I goofed the URL on the image
Advertisement
Hey Duncan,
you want to use a 16:16:16:16 float buffer. This would work better because it is supported in hardware, while the 16:16 fp is not supported in hardware and emulated by the driver. I believe it does not support filtering or something else is screwed up with it.
The VSM algo is not stable under certain conditions. This is called light bleeding. You might check the forums for pictures of this. Just search for variance shadow maps.

<kidding>
Sidenote: Andy -one of the creators of VSM- will soon appear in this thread and explain more :-). In case he mentions his GPU Gems 3 article, there are also articles in the upcoming ShaderX6 on shadows based on probabililty functions :-)
</kidding>
Actually G16R16F should be fine (and filtered in hardware) on NVIDIA 6/7/8.

I can't actually get to the picture (I think you provided a private link rather than a public one), but I have a few ideas:

1) It's possible that you are clamping variance too aggressively, eliminating all shadows near to casters, etc.

2) If you're blurring a lot, complex multi-penumbra regions may be overly lit due to the upper bound that VSM provides. However you mention that the issue still occurs when you are not filtering, or blurring... that's extremely bizarre because in that case VSM reduces to standard shadow mapping - i.e. variance == 0 and it's just a normal depth compare.

I'll check back for an updated image URL.

Quote:In case he mentions his GPU Gems 3 article, there are also articles in the upcoming ShaderX6 on shadows based on probabililty functions :-)

Perhaps related to this paper? :) It's a nice generalization of variance/opacity/deep shadow map-like techniques with the advantage that you can increase the quality by increasing the number of terms (something which while theoretically possible with VSM involves highly non-trivial math). I have my reservations about the number of terms that would be required to properly shadow a reasonable light-space depth range, but I'm willing to extend the benefit of the doubt until I get to play around with a demo :)
Thanks for the quick response guys. wolf, I was aware of the light bleeding problem although I never expected it to have quite this impact! I've done a few tests including adding some cubes and it looks like it might indeed be a light bleeding problem resulting from some bad clamping. Here are a few more images showing off the problem in more detail (and they should work this time).

High angle shot

Low angle shot

Close up of the shadowing on cubes


Another possibility might be that my distance values are not in the correct space. My understanding was that for spotlights you could use world space values for depth. I then rescale these to [0,1] and output it to the texture. Perhaps these depths should be in light-view space?

Anyway, thanks for the help and quick replies.

DuncanG
Cases like that will be prone to light bleeding, but with the "no filtering" that I see there, there's clearly a problem with the implementation.

Check:

1) Use a linear depth metric. World space distance to light rescaled to [0, 1] is fine, but you can get an extra bit of precision by rescaling to [-1, 1] with fp formats.

2) Get rid of any vsm_epsilon or variance clamping that you have an see if the issue still occurs.

3) Try with fp32.

My guess is that you're clamping the variance far too aggressively (it needs to get pretty near to zero in some cases). If biasing problems occur w/o that aggressive variance clamping, you may need to use a higher-precision texture format (16-bit is pushing it for normal shadow mapping let alone VSM), or more aggressively clamp your light ranges (so that you more uniformly use the [0, 1] space.
Thanks for all the feedback. I finally got it working and yes, I was clamping the variance waaaay too strongly. I also rescaled the entire scene as well as scaling the depth values from [-1, 1] and that seemed to help as well. I can also see why being able to filter 32fp textures will be helpful in DX10 implementations. Anyway, thanks for the help!

DuncanG
No problem; glad you got it working! If you need to use 16-bit textures, you can look into the distributing 2->4 component trick that I used in the original VSM demo. fp32 is of course preferable, but that's of course hardware dependent.

This topic is closed to new replies.

Advertisement