为什么在OpenGL中在简单投影的基础上使用平截头体? 让我们简单地考虑一个3D场景,在应用模型和视图矩阵之后,所有顶点都在立方体内[-1,-1,-1 ]…[1,1,1]。

为什么在OpenGL中在简单投影的基础上使用平截头体? 让我们简单地考虑一个3D场景,在应用模型和视图矩阵之后,所有顶点都在立方体内[-1,-1,-1 ]…[1,1,1]。,opengl,shader,frustum,projective-geometry,Opengl,Shader,Frustum,Projective Geometry,根据下图所示的几何设置,可以得出空间点(X,Y,Z)在平面Z=D上投影坐标(Xs,Ys)的公式: 由Xs/D=X/Z可知 Xs=X/(Z/D),类似地 Ys=Y/(Z/D) 从这里我们可以构造一个齐次坐标(x,y,z,w)=(x,y,z,z/D),当转换回欧几里德空间时,将得到(Xs,Ys,D) 在这种情况下,投影矩阵p仅为: 1, 0, 0, 0 0, 1, 0, 0 0, 0, 1, 0 0, 0, 1/D, 0 p*(X,Y,Z,1)=(X,Y,Z,w) 要使z-test在

根据下图所示的几何设置,可以得出空间点(X,Y,Z)在平面Z=D上投影坐标(Xs,Ys)的公式:

由Xs/D=X/Z可知

Xs=X/(Z/D),类似地 Ys=Y/(Z/D)

从这里我们可以构造一个齐次坐标(x,y,z,w)=(x,y,z,z/D),当转换回欧几里德空间时,将得到(Xs,Ys,D)

在这种情况下,投影矩阵p仅为:

1, 0, 0,   0
0, 1, 0,   0
0, 0, 1,   0
0, 0, 1/D, 0
p*(X,Y,Z,1)=(X,Y,Z,w)

要使z-test在片段着色器中工作,可以通过指定以下内容来恢复z-test信息:

gl_FragDepth = gl_FragCoord.z / gl_FragCoord.w;
上面的代码和矩阵p似乎足以让所有的射影几何工作

还可以使用缩放矩阵和p来说明视口纵横比,并在必要时将原始场景缩放到[-1,-1,-1]…[1,1,1]空间

那么为什么要使用平截头体呢

截锥体到剪辑空间的变形相当复杂,不需要创建透视图


它只是为了模拟一个有观察锥的物理相机,还是有其他原因?

你指的是哪一个额外的平截头体?您的矩阵(加上缩放矩阵)基本上就是glFrustum计算的矩阵。我能看到的唯一区别是,通常归一化z值的重构也被压缩到矩阵中。另外请记住,除非可以确保投影空间外没有几何图形,否则不能在剪切之前执行透视分割。必须注意深度缓冲区的有限精度(通常为24或32位)。z坐标必须由深度缓冲区中存储的值表示。在透视投影中,z坐标到深度值的映射不是线性的。因此,在近平面上的精度高于远平面上的精度。看,我没有提到任何“额外的”平截体,但平截体,这里没有平截体。像这里这样的计算似乎很长,而且不必要,结果是一个不同的矩阵。我还读到,将平截头体转换为剪辑空间会产生看起来不正确的透视图。透视图是由P矩阵创建的,平截头体与透视图无关。此外,平截头体变换切断了视锥外的几何体,在这里,它自然地被切割到立方体空间外,这更简单,因此,再次说明为什么要使用平截头体?@user1481126:您描述的立方体无法完全映射到投影平面上。[0,D]之间总会有区域投影到图像外,[D,1]中总会有点不在单位立方体中,但在图像中有投影。如果你用一个立方体而不是一个平截头体,你会错过图像中应该出现的点。