2
$\begingroup$

In an effort to improve cascaded shadow maps, I have looked into using GL_DEPTH_CLAMP and moving the near and far plane just around the actual view frustum instead of the global bounding box. But the use of GL_DEPTH_CLAMP appears to have no effect and the near plane clips the geometry.

I use reverse z as per Reversed-Z in OpenGL:

The tl/dr version is:

  1. Change clip control to 0/1

    glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
    
  2. Use a floating point depth buffer.

  3. Clear the depth buffer to 0

    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    
    glClearDepth(0.0f);
    glClear(GL_DEPTH_BUFFER_BIT);
    
  4. Change depth test to grater

    glDepthFunc(GL_GREATER);
    
  5. Change the projection matrix to match

The reverse z works really fine, but apparently it messes with GL_DEPTH_CLAMP. If I switch off reverse z GL_DEPTH_CLAMP appears to work as designed; but many other bits in the code get messed up. (It's just not switchable anymore.)

If you look at the documentation of GL_DEPTH_CLAMP it states the following:

If enabled, the -wc ≤ zc ≤ wc plane equation is ignored by view volume clipping (effectively, there is no near or far plane clipping).

My guess is that GL_DEPTH_CLAMP's implementation is just not compatible with reverse z. But I feel like I am missing something. Any idea on how to get GL_DEPTH_CLAMP to working with reverse z?

See the following image of the depth buffers:

enter image description here

As you can see in the the first cascade, the near plane clips the geometry, it should be all white.

$\endgroup$
1
$\begingroup$

It is compatible, but instead of clipping it now clamps (hence the name). If the depth of your primitives is outside the [0,1] range it ends up behaving as if you have no depth-test at all. The only way to mitigate that is to either scale down the depth range so it fits in [0,1] or to use GL_NV_depth_buffer_float to disable clipping and clamping completely.

$\endgroup$
  • $\begingroup$ I can live with clamping. My current solution is to extend the near clipping plane outside of the global bounding box, but that looses precision, which can be quite visible with large scenes. Yet, if you see the pictures they are sill clipped. $\endgroup$ – rioki May 6 at 7:36
  • $\begingroup$ @rioki: So your solution is to scale the depth range to fit in [0,1]. But that doesn't loose precision if you have a floating point depth buffer. This is the entire point behind reverse-Z and floating point buffers. Also I'm sorry, but it's hard to understand what's that in the posted picture. Using a simpler scene can help. $\endgroup$ – ybungalobill May 6 at 18:54
  • $\begingroup$ If you look at paroj.github.io/gltut/Positioning/Tut05%20Depth%20Clamping.html You will see clipping vs clamping. With clipping all values that fall behind the near plane are rejected, but with clipping they are treated in the depth test as having the value of the near plane. The pictures are the the shadow maps and you can see they are clipped. not clamped... $\endgroup$ – rioki May 10 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.