How does openGL come to the formula F_depth and and is this the window viewport transformation

a 夏天 提交于 2020-08-09 13:59:56

问题


#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?

回答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



回答2:


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.



来源:https://stackoverflow.com/questions/63096579/how-does-opengl-come-to-the-formula-f-depth-and-and-is-this-the-window-viewport

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!