Shadow volume flickering

Started by
7 comments, last by DirectXFreak 18 years, 8 months ago
Greetings, I implemented the shadow volume method very similar to how it's done on the DirectX9 SDK. Now, I got shadows to work, they show up and all, but there's terrible flickering going on. I realize that must be the shadow volume zfighting with the mesh. But the problem is, I'm not sure how to fix it! I tried offsetting the mesh in the vertex shader, via: Pos.xyz *= 0.975f; and this worked on my card, but the offset is quite noticeable (the shadow volume is smaller than the mesh), and on my friends card, it still flickers. What are my options for fixing this?
--m_nPostCount++
Advertisement
I would try to offset the shadow volume along the normals of the current vertex.
Pos.xyz = Pos.xyz - Normal.xyz * 0.05f;

you could also try to add the normal to the position, don´t know what looks better.
You could also try to tweak the values for your near- and far-clipping-plane, as these greatly affect your z-buffer-precision.
But how am I getting ZFighting if it's supposedly all in the stencil buffer?
--m_nPostCount++
I had this exact issue.

If I recall correctly, I had to change my z-func from less to lessequals, or something of the sort. Try messing around with the z-func a bit, till you get it right.
Sirob Yes.» - status: Work-O-Rama.
Well, I messed with the ZFunc values, and nothing seems to improve the problem. Can someone at least explain why this flickering is going on?
--m_nPostCount++
Once again I'm just guessing, because the hardcore theories still elude me :)

When rendering the shadow volume to the stencil you disable ZBuffer writing, but ZBuffer reading is still enabled. Because you probably have rendered the mesh before the shadow volume, the depth information of the mesh is still available and applied when rendering the shadow volume. If I'm correct, this is what could be causing the Depth fighting, even though it's not really an issue.

You might be able to solve this by disabling the ZBuffer completely when rendering the shadow volumes (IF I'm correct), but that'll most likely cause other problems. For my project, I simply translated the shadow volume a short distance (0.1f) along the light vector, which turned out to work fine, so I didn't bother with fiddling around with the RenderState settings.
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
one quite normal issue with shadow-flickering in the zfail algorithm is flickering on the shadowcaster itself due to shader invariance on the near-cap. one (of many) solutions to this is simply to use the polygons facing away from the lightsource instead of those who face towards it.
If I understood the principles of shadow volumes correctly:
First you render the unshadowed scene to the depth buffer only, then you render the shadow volumes without writing to the depth buffer, but comparing to the results from the previous pass. Now the stencil buffer is altered depending on whether the front faces of your shadow volume have been rendered, and it is altered depending on whether the back faces of your shadow volume have been rendered. Therefore, if you disable Z-testing I´d suppose the whole idea of stencil shadows to lose its point, i.e. the algorithm won´t work at all, because the Z-testing is quite a vital part of it. And the Z-testing is also where the flickering has its origin: due to the Z-buffer inaccuracies you might receive different results for a point close to the borders of the shadow volume every frame, which is the same issue as Z-fighting. One frame the result might be that it´s shadowed (i.e. behind the shadow volume´s front faces, but in front of the back faces), next frame it might be lit (perhaps in front of the front faces, perhaps behind the back faces).

I guess you won´t get around altering your shadow volume a bit, so it doesn´t fit the shadowcaster exactly, because exactly same points tend to give different results all the time due to z-fighting, I guess.
Remigius´s approach with moving the volume along the light´s direction vector could help, but wouldn´t do any good with faces parallel to the light´s direction. I would try it out, though, because this should be an extremely rare case, I guess. Downsizing the shadow volume along the normals of the shadowcaster, as I suggested in my previous post, should help, too.
Have you tried fiddling around with the values for near- and far-clipping-plane?
Won´t help when the shadow volume isn´t a small amount larger or smaller than the shadowcaster, but if it is, it should help you to minimize the inaccuracy of the volume.
Hey, thanks for the replies! I'll try implementing a few of your ideas and see if they work.
--m_nPostCount++

This topic is closed to new replies.

Advertisement