openGL 如何得出公式 F_depth 并且这是 window 视口变换
How does openGL come to the formula F_depth and and is this the window viewport transformation
#point no.1
通过投影矩阵变换点后,我们最终得到 [-1,1],
范围内的点
但是,在深度测试章节中,作者提到
F_depth = 1/z-1/far /(1/near - 1/far) 转换 视图 space 坐标 即 z=zeye 从 [-1,1] 转换为 [0,1] .
I've followed this thread,其中一位成员告诉我公式F_depth
实际上是一系列完成步骤的组合,并概述了这一步:
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
另外一个成员告诉我[-1,1]到[0,1]是window视口变换,它有一个different formula itself.
所以,所有这些对我来说都没有任何意义(有 3 个不同的公式和解释同样适用于 openGL),我将列出查询我对这些相互矛盾的想法有:
- F_depth 是从视图 space 到 window 的转换组合
space.
- 深度范围变换和视口变换是
相同的?为什么他们有不同的论坛(一个在
Point no.1
和
另一个在 this link
- F_depth公式是如何得到的?或者作文怎么样
为将世界 space 指向 [0,1] 所做的转换
结果
F_depth
?
详细信息以及可能的讨论和来源可以是 found here also a huge thanks to @Rabbit76, initial part
概述转换过程的步骤如下:
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) .
所以,从第 3 步开始:
openGL使用a=0,b=1,所以第3步变成:
[ zNDC+1 ]/2
替换第 2 步的值:
[ zclip / wclip + 1 ] /2
代入第 1 步的值并简化您得到:
[1 + n/zeye]/[1-n/f]
现在学习openGL的公式:
F_depth = [1/zeye - 1/n] /[ 1/f - 1/n]
如果 zeye = -zye,我们得到:
-(zeye + n)/(n-f) * nf/[zeye *n]
简化我们得到相同的:
[1 + n/zeye]/[1-n/f]
所以,公式直接从眼睛坐标直接到 window- 视口坐标。
此外,深度范围变换是 z 坐标的 window-视口变换。
@horxCoder 的回答中缺少一些步骤,我想澄清一下。
教程中LearnOpenGL - Depth testing is claimed that the depth at claimed at Perspective projection是
depth = (1/z - 1/n) / (1/f - 1/n)
其中z
是到视点的距离,n
是到近平面的距离,f
是到[=31的远平面的距离=].
问题是为什么上面的公式给出一个片段的深度?
对称透视投影矩阵为(见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
对于深度,我们只对 z
和 w
分量感兴趣。对于输入顶点 (x_eye, y_eye, z_eye, w_eye), 剪辑 space z_clip 和 w_clip 分量计算如下:
z_Clip = C * z_eye + D * W_eye
w_Clip = -z_eye
哪里
C = -(f+n) / (f-n)
D = -2fn / (f-n)
标准化设备spacez坐标由Perspective divide
计算
z_ndc = z_clip / w_clip
归一化设备spacez坐标映射到深度范围[a,b](见glDepthRange
):
depth = a + (a-b) * (z_ndc+1)/2
当我们假设深度范围是 [0, 1] 并且输入顶点是 Cartesian coordinate (x_eye , y_eye, z_eye, 1), 这导致如下:
z_eye * -(f+n) / (f-n) + -2fn / (f-n)
depth = (------------------------------------------ + 1) / 2
-z_eye
并且可以变形
-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)
由于视图 space z 轴指向视口外,因此从视点到顶点的 z
距离为 z = -z_eye
。这导致:
f (n - z) 1/z - 1/n
depth = ----------- = -----------
z (n - f) 1/f - 1/n
#point no.1
通过投影矩阵变换点后,我们最终得到 [-1,1],
范围内的点
但是,在深度测试章节中,作者提到
F_depth = 1/z-1/far /(1/near - 1/far) 转换 视图 space 坐标 即 z=zeye 从 [-1,1] 转换为 [0,1] .
I've followed this thread,其中一位成员告诉我公式F_depth
实际上是一系列完成步骤的组合,并概述了这一步:
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
另外一个成员告诉我[-1,1]到[0,1]是window视口变换,它有一个different formula itself.
所以,所有这些对我来说都没有任何意义(有 3 个不同的公式和解释同样适用于 openGL),我将列出查询我对这些相互矛盾的想法有:
- F_depth 是从视图 space 到 window 的转换组合 space.
- 深度范围变换和视口变换是
相同的?为什么他们有不同的论坛(一个在
Point no.1
和 另一个在 this link - F_depth公式是如何得到的?或者作文怎么样
为将世界 space 指向 [0,1] 所做的转换
结果
F_depth
?
详细信息以及可能的讨论和来源可以是 found here also a huge thanks to @Rabbit76, initial part
概述转换过程的步骤如下:
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) .
所以,从第 3 步开始: openGL使用a=0,b=1,所以第3步变成:
[ zNDC+1 ]/2
替换第 2 步的值:
[ zclip / wclip + 1 ] /2
代入第 1 步的值并简化您得到:
[1 + n/zeye]/[1-n/f]
现在学习openGL的公式:
F_depth = [1/zeye - 1/n] /[ 1/f - 1/n]
如果 zeye = -zye,我们得到:
-(zeye + n)/(n-f) * nf/[zeye *n]
简化我们得到相同的:
[1 + n/zeye]/[1-n/f]
所以,公式直接从眼睛坐标直接到 window- 视口坐标。 此外,深度范围变换是 z 坐标的 window-视口变换。
@horxCoder 的回答中缺少一些步骤,我想澄清一下。
教程中LearnOpenGL - Depth testing is claimed that the depth at claimed at Perspective projection是
depth = (1/z - 1/n) / (1/f - 1/n)
其中z
是到视点的距离,n
是到近平面的距离,f
是到[=31的远平面的距离=].
问题是为什么上面的公式给出一个片段的深度?
对称透视投影矩阵为(见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
对于深度,我们只对 z
和 w
分量感兴趣。对于输入顶点 (x_eye, y_eye, z_eye, w_eye), 剪辑 space z_clip 和 w_clip 分量计算如下:
z_Clip = C * z_eye + D * W_eye
w_Clip = -z_eye
哪里
C = -(f+n) / (f-n)
D = -2fn / (f-n)
标准化设备spacez坐标由Perspective divide
计算z_ndc = z_clip / w_clip
归一化设备spacez坐标映射到深度范围[a,b](见glDepthRange
):
depth = a + (a-b) * (z_ndc+1)/2
当我们假设深度范围是 [0, 1] 并且输入顶点是 Cartesian coordinate (x_eye , y_eye, z_eye, 1), 这导致如下:
z_eye * -(f+n) / (f-n) + -2fn / (f-n)
depth = (------------------------------------------ + 1) / 2
-z_eye
并且可以变形
-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)
由于视图 space z 轴指向视口外,因此从视点到顶点的 z
距离为 z = -z_eye
。这导致:
f (n - z) 1/z - 1/n
depth = ----------- = -----------
z (n - f) 1/f - 1/n