2
votes

I've written a simple OpenGL test application about basic shadow mapping technique.

I have removed most artifacts except for the one on the occluder back face. This back face is concerned by artifacts because during the first rendering pass (shadow depth map filling) I enable the front face culling. Consequently I have self-shadowing z-fighting artifacts.

To solve this kind of problem it said on several tutorials the depth of the vertex position in light space need to be biased with a very small offset like 0.0005f.

Here's a screenshot of my problem (for a sake of visibility I have increased the ambient light value for the box). Here without depth offset:

enter image description here

As you can see there is a strong self-shadowing.

Here's a piece of code I use in my fragment shader:

if (ShadowCoords.w > 0.0f)
{
    vec4 tmp_shadow_coords = ShadowCoords;

    tmp_shadow_coords.z -= 0.0000f; //DEPTH OFFSET DISABLE HERE 
    shadowFactor = textureProj(ShadowMap, tmp_shadow_coords);
}

Now let's see what happen when using an offset equal to 0.0002f:

tmp_shadow_coords.z -= 0.0002f;

The screenshot:

enter image description here

As you can see the self-shadowing is decreased. Now let's try with an offset equal to 0.0003f :

tmp_shadow_coords.z -= 0.0003f;

The screeshot:

enter image description here

As you can see self-shadowinh has disappeared! But if I zoom towards the limit between the occluder and the shadow we can see an unshaded area. This artifact is called Peter Panning artifact.

So it's a strange situation : to avoid self-shadowing artifact I need to modify the vertex depth value in light space. But this modification of the depth value trains causes a Peter Panning artifact!

enter image description here

The problem is worse if I increase the offset value.

UPDATE

I also tried adding an offset. For example:

tmp_shadow_coords.z += 0.0002f;

Screenshot:

enter image description here

There's less self-shadowing but no Peter Panning artifact. But unfortunatly it appears some artifacts on the front faces of the cube. There's an overflow of the shadow on the front faces.

If I increase the offset:

tmp_shadow_coords.z += 0.0003f;

Screenshot:

enter image description here

The self-shadowing artifacts have completely disappeared but the shadow overflow in front faces is worse.

So I wonder if it's possible to have a render without both self-shadowing artifact and no Peter Panning artifact ?

1
You can disable front face culling again, it will fix the partial self-shadow (the entire back face will be in darkness) and the peter-panratchet freak
During the first pass I enable front face culling with the calls glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); ... shadow mapping filling ... and at the end (before second pass) I call glDisable(GL_CULL_FACE); to disable face culling. Where can I disable front face culling again ? I don't understand, sorry.user1364743
I have updated my post. I have already tried to do this but others artifacts appear on the front faces of the cube this time (like an overflow). See my update please.user1364743

1 Answers

2
votes

enter image description here

This works pretty well. There is a small gap where the casting surface is very close to the receiving surface.

The main thing to get right in the shader is how a shadow is applied. Scale just the added direct light, diffuse and specular terms, by the shadow/occlusion value (ambient terms should be left alone). An easy check is that surfaces in shadow should look exactly the same as surfaces facing away from the light with shadowing disabled. Shadows should not just make things darker (i.e. finalColour *= 1.0-shadowScale or finalColour -= shadow), instead they are the absence of direct light. This becomes very important when multiple lights are involved.