I'm currently reading from a depth texture in a postprocess depth of field shader using the following GLSL code:
vec4 depthSample = texture2D(sDepthTexture, tcScreen);
float depth = depthSample.x * 255.0 / 256.0 +
depthSample.y * 255.0 / 65536.0 +
depthSample.z * 255.0 / 16777216.0;
And then converting the depth value to a view space distance based on the near and far plane distances:
float zDistance = (zNear * zFar) / (zFar - depth * (zFar - zNear));
This all seems to work fairly well, however I am interested to know how to do the above calculation based only on the current projection matrix without needing separate zNear
and zFar
values.
My initial attempt involved multiplying (vec4(tcscreen.x, tcScreen.y, depth, 1.0) * 2.0 - 1.0)
by the inverse of the projection matrix, dividing the result through by w
, then taking the resulting z
value as the distance, but this didn't seem to work. What's the correct approach here?
Also, when using oblique frustum clipping to shift the near plane onto a chosen clipping plane is the near plane distance now potentially different for every pixel? And if so then does this mean that any shaders that calculate a distance from a depth texture need to be aware of this case and not assume a constant near plane distance?
Thanks!