1
#point no.1

after transforming points via the projection matrix , we end up with the point in the range [-1,1],
but, in the depth testing chapter , the author mentions that
F_depth = 1/z-1/far /(1/near - 1/far) converts the view space coordinates i.e. z=zeye is transformed from [-1,1] to [0,1] .

I've followed this thread, and one of the members tell me that the formula F_depth is actually a composition for a series of steps done, and outlines this step:

    z_Clip = C*z_eye+D*W_eye
    w_Clip = -z_eye
    where C=-(f+n)/(f-n), D=-2fn/(f-n).
    Projective division:
    z_ndc = z_clip/w_clip
    Depth range:
    depth = a + (a-b)*(z_ndc+1)/2
    where glDepthRange(a,b) .

I tried composing the formula as he had suggested, but this is completely different from the F_depth formula given in learnopenGL.

#point no. 2

Also another member tells me that [-1,1] to [0,1] is the window viewport transformation, which has a different formula itself.

So, all of this is not making any sense to me(having 3 different formulas and explanations for the same thing that also for openGL), I'll bullet the queries I have regarding these contradicting ideas:

  • Is F_depth a composition of transformations from view space to window space.
  • Are the depth range transformation and viewport transformation the same? Why do they have different forumulas(one in Point no.1 and another in this link
  • How is the F_depth formula obtained? Or how is does the composition of transformations done to convert the world space point to [0,1] result in F_depth?
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
horxCoder
  • 165
  • 8
  • I just found out the derivation this formula actually seems to be a composition directly from eye space to window coordinate directly. The author should had explained that. – horxCoder Jul 26 '20 at 09:07
  • No it is not. It is just an approximation – Rabbid76 Jul 26 '20 at 09:08
  • @Rabbid76 , um... I always doubt my understanding which only clear off after weeks. It may be that I am thinking that I understand something. Could you take a look at my derivation below? – horxCoder Jul 26 '20 at 09:12
  • I still need to stress a point here: "after transforming points via the projection matrix , we end up with the point in the range `[-1,1]`". no we do not. we also do not end up in the range `[-w,w]`. Clip space is infinite. The _viewing volume_ is just a chosen, finite sub-volume of that space, and that one is mapped to the `[-1,1]` NDC cube (by default in OpenGL at least, there are different conventions to chose from). However, between clip space and NDC lies not only the perspective divide, but also the _clipping_ itself. – derhass Jul 26 '20 at 14:45
  • Hence, specifying a formula which describes the transformation from clip or eye space to NDC or window space is only valid for points which lie in the viewing volume. If you use a perspective projection, you will get bogus results for points behind the "camera", and you will even get a division by zero for points in the camera plane - both cases which never occur during the rendering by the GPU because those cases are eliminated by the clipping before they get to the perspective divide. – derhass Jul 26 '20 at 14:48

2 Answers2

1

Details and possible discussion and credit can be found here also a huge thanks to @Rabbit76, initial part of the question was here

The steps outlined how the transformation goes are:

    1.The projection transformation:
    zclip = Czeye+Dweye
    wclip = -zeye
    where C=-(f+n)/(f-n), D=-2fn/(f-n).
    2.Projective division:
    zNDC = zclip/wclip
    3.Depth range transformation:
    depth = a + (b-a)*(zNDC+1)/2
    where glDepthRange(a,b) .

so, start from step 3: openGL uses a=0, b=1, so step 3 becomes:

[ zNDC+1 ]/2

substitue value from step 2:

[ zclip / wclip   +  1 ] /2

substitue value from step 1 and simplify you get:

[1 + n/zeye]/[1-n/f]  

Now for the formula from learnopenGL:

F_depth = [1/zeye - 1/n] /[ 1/f - 1/n]  

if zeye = -zye, we get:

-(zeye + n)/(n-f) * nf/[zeye *n]  

simplifying we get the same:

[1 + n/zeye]/[1-n/f]  

So, the formula goes directly from the eye coordinate directly to the window-viewport coordinates. Also, the depth range transformation is the window-viewport transformation for the z coordinate.

horxCoder
  • 165
  • 8
  • @Rabbid76 , I thought I did it correctly.... I don't see mistakes, here's a GIMPed derivation: https://pasteboard.co/JjnUtwz.jpg – horxCoder Jul 26 '20 at 09:44
1

In the answer of @horxCoder are missing some steps, which I want to clarify.

In the tutorial LearnOpenGL - Depth testing is claimed that the depth at claimed at Perspective projection is

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

where z is the distance to the point of view, n is the distance to the near plane and f is the distance to the far plane of the Viewing frustum.

The question is why the depth of a fragment is given by the above formula?


The symmetrically perspective projection matrix is (see OpenGL Projection Matrix):

1/(ta*a)  0      0              0
0         1/ta   0              0
0         0     -(f+n)/(f-n)   -2fn/(f-n)
0         0     -1              0

For the depth we are just interested in the z and w component. For an input vertex (x_eye, y_eye, z_eye, w_eye), the clip space z_clip and w_clip components are computed by:

z_Clip = C * z_eye + D * W_eye
w_Clip = -z_eye

where

C = -(f+n) / (f-n)
D = -2fn / (f-n)

The normalized device space z coordinate is computed by a Perspective divide

z_ndc = z_clip / w_clip

The normalized device space z coordinate is mapped to the depth range [a, b] (see glDepthRange):

depth = a + (a-b) * (z_ndc+1)/2

When we assume tha the depth range is [0, 1] and the input vertex is a Cartesian coordinate (x_eye, y_eye, z_eye, 1), this leads to the following:

             z_eye * -(f+n) / (f-n)  +  -2fn / (f-n)
depth  =  (------------------------------------------ + 1) / 2
                          -z_eye

And can be transformed

             -z_eye * (f+n)  -  2fn
depth  =  (-------------------------- + 1) / 2
               -z_eye  *  (f-n)
             -z_eye * (f+n)  -  2fn  +  -z_eye * (f-n)
depth  =  ---------------------------------------------
                      -z_eye  *  (f-n)  * 2
             -z_eye * (f+n+f-n)  -  2fn
depth  =  -------------------------------
               -z_eye  *  (f-n)  * 2
             -z_eye * f  -  fn           -f (n + z_eye)  
depth  =  -----------------------   =   ----------------
               -z_eye * (f-n)             z_eye (n - f)

Since the view space z axis points out of the viewport, the z distance from the point of view to the vertex is z = -z_eye. This leads to:

          f (n - z)        1/z - 1/n
depth  =  -----------  =  -----------
          z (n - f)        1/f - 1/n
Rabbid76
  • 202,892
  • 27
  • 131
  • 174