Monday, December 21, 2009

Stable Shadows

this time i worked on stabilizing the flickering when doing cascaded/pssm shadow maps.
if you had the chance to do cssm/pssm you know what i'm talking about, you can't ignore those flickering when you move your camera (panning/rotating).
the first game i know who solve this problem was kill zone 2, nothing to say about this game!
i'v a lot of respect to those guys :)
anyway, if you don't know what i'm talking about and what those flickers are, let me explain (i can't promise you will understand it but i will still try...)
i will talk about cssm from now, the same idea works for pssm.
when you render your shadows you are creating/generating your shadow matrix whenever the view changes (your camera view), if this change is very small and almost smooth you are fine but if not, the shadows boundaries are rendered or more correctly rasterized differently which cause visible flickering of the shadow edges.
the more area your farther shadows (farther cascaded) will cover the more you will notice it.
ok, get the idea, how do i solve it? well, i split it into 2 cases:
1. rotation problem
2. moving/panning problem
case 1: can be solved by eliminating the rotation of the shadow maps when our camera is rotated (this cause our shadow map to be rasterized differently) , we can use smallest enclosing sphere of the cascaded frustum and use it to generate our cascaded matrices, using the center as the lookat target and the radius to generate the orthogonal projection matrix.
this assure that your shadow maps will not rotate with the camera.
case 2: can be solved by canceling the movement in sub-texel level, this can be archived by multiplying a fixed world position with our cascaded matrix, round the result and see how much it differs from your fixed world position, note that this must be calculated in shadow map space in order to get the right offset. we now use this offset to translate our cascaded matrix.
note that my implementation is different, i use bounding box slice selection and different flickering solution which is very sable (can't give info about that because we are working on a big project so i need to keep few tricks inside)
here is a video to show the translation of all those words in action :)

The resolution of the shadow maps are low to make the problem more noticeable