# Failing to move exponential depth term to depth shader in exponential shadow mapping

I'm playing around in my little toy project to see if I can understand how exponential shadow mapping works. To begin, I have the following two fragment shaders:

layout(location = 0) out float fragmentdepth;

void main(){
fragmentdepth = gl_FragCoord.z;
}


...
float visibility = clamp(exp(-70 * shadowDiv.z) * exp(70 * lightDepth), 0, 1);
...


This works fine - I have shadows where I expect them, and I'm using the approximation to the boolean function by taking the product of exponentials, as shown in the ESM paper.

However, my understanding is that the whole point of this, is that I can move exp(70 * lightDepth) out of this shader, and into the shader when I generate the depth texture at the light. That is:

### New light depth texture shader

layout(location = 0) out float fragmentdepth;

void main(){
fragmentdepth = exp(70 * gl_FragCoord.z);
}


...
float visibility = clamp(exp(-70 * shadowDiv.z) * lightDepth, 0, 1);
...


When I make this change, the entire scene becomes shadowed. I'm sure I'm misunderstanding something somewhere, but I'm not sure where. I have tried varying the constant term (70) between 1 and 70, though this doesn't appear to make a difference. I have no errors reported by KHR_debug

I am creating my light depth texture as:

genLightDepthMap :: IO GLTextureObject
genLightDepthMap =
do lightDepthMap <- overPtr (glGenTextures 1)
glBindTexture GL_TEXTURE_2D lightDepthMap
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_LINEAR
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_LINEAR
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_CLAMP_TO_EDGE
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_CLAMP_TO_EDGE
glTexImage2D GL_TEXTURE_2D
0
GL_DEPTH_COMPONENT24
0
GL_DEPTH_COMPONENT
GL_FLOAT
nullPtr


You are using GL_DEPTH_COMPONENT24 which is a fixed-point format clamped to the range [0, 1] inclusively.

The floating point formats are GL_DEPTH_COMPONENT32F and DEPTH32F_STENCIL8.

 glTexImage2D GL_TEXTURE_2D
0
GL_DEPTH_COMPONENT32F
0
GL_DEPTH_COMPONENT
GL_FLOAT
nullPtr


You also need to call glDepthRange(-1, 1); to disable scaling & offsetting of the depth values.

It is unclear if you can call glClearDepth(INFINITY) or need to clear the depth using a full-screen quad as the ARB_depth_buffer_float extension says "ClearDepth takes a floating-point value that is clamped to the range[0, 1]."

I don't know how supported it would be to clear the depth with a quad at depth near-infinity regarding clipping against the far plane: The clipping calculation might go nuts with rounding errors.

Your best bet is to draw a fullscreen quad at a reasonable depth (1.0) with depth-test disabled and FORCE the depth at INFINITY (or a very large non-infinity value) in the pixel shader so this will happen after primitive clipping.

Cheers,

• Thanks, I'll be sure to look into this! I literally just found another solution, which is to render into a GL_R32F texture, as a color texture rather than depth. I'm curious if that has drawbacks against using GL_DEPTH_COMPONENT Dec 10 '14 at 22:35
• Its essentially the same thing, except that you ALSO need a depth buffer to do depth test. So on one hand you're doubling the memory requirement, on the other hand you're not modifying the fragment depth value anymore which is good as changing the fragment depth value can incur a huge performance cost as depth-test cannot happen before the fragment shader has run disabling early-Z test and hi-Z test. Dec 10 '14 at 22:49