GL_DEPTH_CLAMP has no effect (reverse z) 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:


Change clip control to 0/1

glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);

Use a floating point depth buffer.
Clear the depth buffer to 0

glBindFramebuffer(GL_FRAMEBUFFER, fbo);

glClearDepth(0.0f);
glClear(GL_DEPTH_BUFFER_BIT);

Change depth test to grater

glDepthFunc(GL_GREATER);

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:



As you can see in the the first cascade, the near plane clips the geometry, it should be all white.
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.