After changing my current deferred renderer to use the logarithmic depth buffer , I can’t work, for life, how to reconstruct the depth of world space from the depth buffer values.
When I recorded the default depth of z / w OpenGL, I could easily calculate this value by converting from window space to NDC space, then doing the inverse perspective transformation.
I did it all in the shader of the second pass fragment:
uniform sampler2D depth_tex; uniform mat4 inv_view_proj_mat; in vec2 uv_f; vec3 reconstruct_pos(){ float z = texture(depth_tex, uv_f).r; vec4 pos = vec4(uv_f, z, 1.0) * 2.0 - 1.0; pos = inv_view_proj_mat * pos; return pos.xyz / pos.w; }
and got a result that looked pretty correct:

But now the path to a simple z value is not so simple (it does not seem like it should be so complicated either).
My vertex shader for my first pass with log depth:
#version 330 core
And my fragment shader:
#version 330 core #extension GL_ARB_shading_language_420pack : require
I tried several different approaches to correctly return the z-position, all fail.
If I redefine my reconstruct_pos in the second pass:
vec3 reconstruct_pos(){ vec4 pos = vec4(uv_f, get_depth(), 1.0) * 2.0 - 1.0; pos = inv_view_proj_mat * pos; return pos.xyz / pos.w; }
This is my current attempt to restore Z:
uniform float FC; float get_depth(){ float log2logz_FC_2 = texture(depth_tex, uv_f).r; float logz = pow(2, log2logz_FC_2 / (FC * 0.5)); float pos_z = log2(max(1e-6, logz)) * FC - 1.0;
Explanations:
log2logz_FC_2 : the value written to the depth buffer, so log2(1.0 + gl_Position.w) * (FC / 2)
logz : just 1.0 + gl_Position.w
pos_z : value of gl_Position.z before gl_Position.z perspective
return value: gl_Position.z
Of course, this is just my job. I’m not sure what these values actually hold in the end, because I think I messed up some of the math or misunderstood the transformations that are happening.
What is the right way to get my position in world space from this logarithmic depth buffer?