0

According to the thread on this page, The equation given for calculating the depth buffer:

F_depth = 1/z - 1/n/(1/f - 1/n)   

is non-linear only because of the perspective divide.(Note that this is a combination of from the view-space z coord to window coord directly)

So, as per my understanding:
to convert it to a linear depth buffer, the only thing we would do is to remove the perspective divide(?) and then perform the glDepthRange(a,b) given here.

In that case, the equation would be like this:

z_linear = z_NDC * W_clip = -(f+n)/(f-n)*z_eye + ( 2fn/(f-n) )

and, with depth range transformation:

z_[0,1] = ( z_linear + 1 ) /2
= ( (f+n)*z_eye - 2fn + f - n )/ ( 2(f-n) )

but, in the learnopenGL site for depth testing this is done:

First we transform the depth value to NDC which is not too difficult:

float ndc = depth * 2.0 - 1.0; 

We then take the resulting ndc value and apply the inverse transformation to retrieve its linear depth value:

float linearDepth = (2.0 * near * far) / (far + near - ndc * (far - near)

how is the non-linear to linear depth-buffer being computed?(i.e. equation being formed)?

horxCoder
  • 165
  • 8
  • "how is the non-linear to linear depth-buffer being computed?" To achieve _what_? Multiplying by `w_clip` will give you just the clip space `z` value, but at the expense of knowing `w_clip` - which in the typical situations one would not have, but apart from that, it is also a nonsensical operation because `w_clip` then already _is_ a non-linear depth value, and `z_clip` while also being linear in `z_eye` is quite useless because it does not map near and far to a useful normalized interval. – derhass Jul 28 '20 at 17:54
  • So there are only 2 cases where you want to go from hyperbolic depth value to linear: you want to reconstruct the eye space z value `z_eye`, so that it represents the actual euclidean distance to the image plane (for using it in calculations like lighting), or you want to linearize the depth buffer and need to transform it to so that `[-n,-f]` is mapped to `[0,1]` while still being a linear function of `z_eye`. – derhass Jul 28 '20 at 17:58
  • see [How to correctly linearize depth in OpenGL ES in iOS?](https://stackoverflow.com/a/42515399/2521214) – Spektre Jul 29 '20 at 06:54

1 Answers1

0

Using glm in a right handed system I found the following solutions for converting from ndc depth [-1, 1] to eye depth [0-far].

perspective projection:

float screen_to_eye_depth_perspective(float d, float zNear, float zFar)
{
    // [0; 1] -> [-1; 1]
    float depth = d * 2.0 - 1.0;
    return  (2.0 * zNear * zFar) / (zFar + zNear - depth * (zFar - zNear));
}

orthographic projection:

float screen_to_eye_depth_ortho(float d, float zNear, float zFar)
{
    // [0; 1] -> [-1; 1]
    float depth = d * 2.0 - 1.0;
    return (depth * (zFar - zNear) + (zFar + zNear)) / 2.0;
}

I advise you to test with your own near and far value to check the final result.

n = 10;
f = 100;
// -------------
z = 2 * f * n  / (f + n) - ndc * (f - n);
z = 2000 / (110 - ndc * 90);
// -------------
ndc = -1;
z = 2000 / (110 + 90) = 10;
ndc = 1;
z = 2000 / (110 - 90) = 100;
Paltoquet
  • 1,184
  • 1
  • 10
  • 18