Sign in to follow this  
JamesMeyer

ShaderX7 Exact Solution to Shadow Map Flickering

Recommended Posts

JamesMeyer    100
Hi
I recently started implementing Cascaded Shadows for a simple scene in DX10, following the guidelines of "Practical Cascaded Shadow Maps" in ShaderX7.

Now looking in particular at the exact solution to the flickering issue, I have a few questions, which I hope someone can answer/explain:

Firstly, I notice that the view frustum is calculated by working backwards from clip space. Then why are the extents (-1,-1,-1) to (1,1,1) used when this space differs depending on the graphics API (DirectX uses a clip space of (-1,-1,0)->(1,1,1)?

Secondly, when the center of the frustum's bounding sphere is calculated in camera space and then transformed into world space, why would the sphere center not by-default be in the center of the shadow map, and needs to be transformed using the lines:
[code]

vec3 target = imodelview * bs.getCenter();
float x = ceilf(dot(target,up) * half_size / bs.getRadius()) * bs.getRadius() / half_size;
float y = ceilf(dot(target,side) * half_size / bs.getRadius()) * bs.getRadius() / half_size;
target = up * x + side * y + direction * dot(target,direction);
[/code]


Obviously it works perfectly as can be seen in the demo, but I don't quite get the reason behind it.

In my implementation the bounding sphere of the frustum is calculated in world space from the start, then transformed into light space to find the min and max coordinates. My frustum BS center is then (min + max) / 2. The only adjustment I make to this point is in the z-component to pull it towards the light in order to capture the whole visible scene. According to my reasoning this sphere is smack bang in the middle of the shadow map, so why do I still have flickering?

Thanks in advance

Share this post


Link to post
Share on other sites
kauna    2922
As far as I understand, the effect of the presented code is to align the frustum bound sphere to full pixels, which will minimize/eliminate flickering.

Consider the case where your camera moves a bit to some direction. Your frustum and your frustum bound will move too, which means that your shadow map is sampled slightly in different place. As the shadowing test is binary (in shadow / in light) it may happen that a pixel that was shadow/lit in the previous position, will be the opposite in the next position. As your camera moves you'll see the flickering effect.

If you snap the bound position to full pixels, the individual shadow map values come (more and less) from the same position when the camera is moving which will produce more consisted results from shadowing.

Good luck!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this