Shadow cube map: glPolygonOffset does not help?


I have an omni directional light source with a shadow cube map:

Works fine so far BUT… as you can see there are some artifacts on the front face of the box (marked red in the image).

What I am doing so far…

Creating the shadow cube map:

  • Set FOV 90°
  • Set Z-Far (far clipping plane) to match the light source (attenuation) range
  • Set front face culling (only render back faces)
  • Render the scene into the six 1024x1024 sides of a 24bit GL_TEXTURE_CUBE_MAP (each side is a depth texture attached to a FBO)
    You can see the result in the debug rendering (the six sides of the depth cube map) where I also linearized the depth values.

In the vertex shader:
Convert the world LightToFragment direction vector to a depth buffer compatible depth value in the range of [0,1] as explained here.
For this use the same ZNear and ZFar which was used to create the shadow map.
Pass the result as varying scalar Depth to the fragment shader

In the fragment shader:

float ShadowMapDepth = textureCube(Texture, LightToFragmentDirectionVecWorld).x;

float ShadowFactor = ShadowMapDepth < Depth ? 0.1 : 1.0;

I can remove the artifact on the front face of the box when I add an offset/bias…

float ShadowFactor = ShadowMapDepth + 0.005 < Depth ? 0.1 : 1.0;

…but then at triangles far away from the light source some fragments are wrongly considered as “not shadowed” (marked red again):

This probably happens because the depth precision towards ZFar (close to the wall) is low so that just adding a constant
offset to the shadow map depth value is too much. In other words the depth buffer compatible depth values of the wall
fragments are lower than the shadow_map_depth_values_of_the_star plus the offset.

I also tried to set…

glPolygonOffset(1.1f, 4.0f);

…before creating/rendering the shadow map but it causes similar problems… :confused:

What can I do, to have a good offset without getting this issue in the second image? Or is it more a problem of the cube map, because I noticed the artifacts happen especially when the box (in the middle of the room) overlaps multiple sides in the depth cube map (see first image).

How can I get some “dynamic bias” that adjusts based on the depth?

Help is really appreciated!

I just found a way to get a dynamic bias which seems to reduce the issues:

 float Bias = 0.5 * (1.0 - clamp(Depth, 0.0, 1.0));

edit Hm no not really, the issue is still there for objects close to each other (marked red):

I don’t get how it is supposed to work. As soon as I add some offset I have trouble with this false “not-shadowed” sh…

Thanks god I just found out what I am doing wrong!!! :smiley:

The problem was, that I calculated Depth in the vertex shader and then passed it as varying to the fragment shader!

This of course is wrong. It only works, when all of the 3 vertices of the fragment’s triangle belong to the same cube map side.
As soon as they belong to different cube map sides, the interpolation does not work.

So I moved the calculation of Depth into the fragment shader and now the result is perfect without even using a bias! Yeeeeeeeeeehaaaaaaaaaa!


I hope this helps whoever is reading this in the future ^^