问题
#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