I’ve just updated and refined another code sample from XNA Community, from XNA version 3.1 to 4.0. This one is on variance shadow mapping, which is basically a way to get shadow maps that are filterable- that is, you can apply any kind of texture filter onto the shadow mapping image to give it a smoother look. Optionally, and usually, a Guassian blur filter is applied. Together, variance shadow mapping improves the visual quality of the shadows as well as giving more leeway to the size and number of textures needed to produce good results.
In the sample code, the program uses one 1024×1024 texture to produce the shadow map, and applies a two-pass filtering technique for Gaussian blur. This blur is not done in screen-space, but because the original shadow map can be filtered, it is almost indistinguishable from a screen-space blur, which will produce leaking artifacts if done with normal shadow maps.. Most of the heavy image computation is done in this step.
The shadow uses a 2-channel 32-bit texture for the depth map, in contrast to a single floating-point texture format used in conventional shadow mapping. This allows us to store two “moments”, which are simply the depth and the squared depth stored in the depth texture. From here we are able to calculate the mean depth and variance of the given pixel in the map. One noticeable drawback to variance shadow mapping is light bleeding among shadows where the shadow casters are of very different depths. An easy fix to reduce this effect would be to raise the shadow amount by a certain exponent, but raised too high and the shadows dampen too much.
I plan to use some form of variance shadow mapping to my graphics engine, but in the meantime I’ll try to make improvements on it, in order to remove the light bleeding more effectively. But in the meantime, you can download current sample project here, compatible with XNA 4.0.
- Matt’s Webcorner: http://graphics.stanford.edu/~mdfisher/Shadows.html
- Fabien Sangard’s non-blog: http://fabiensanglard.net/shadowmappingVSM/