我试图理解在OpenGL中使用glFrustum()
创建的投影矩阵,以及将其带入 x = [ - 的规范化设备坐标的转换1,1] , y = [ - 1,1] , z = [ - 1,1] 和 4x4矩阵序列发生的乘法导致
我理解最终结果(在NDC中)是在应用连续变换后通过除以 w 组件获得的,但那些连续变换是什么?< / p>
这就是矩阵 T (就近,远,左,中的 这样每个 T 仅代表比例,翻译,轮换或剪切< / strong>运营/转型? 我读了一篇关于Is OpenGL LH or RH和Projection Matrix tutorial的相关帖子,但我仍然对基本操作(即 scale ,< em>翻译,轮换或剪切操作)。
答案 0 :(得分:4)
透视变换矩阵不能分解为仅缩放,平移旋转和剪切操作。这些操作都是仿射,而透视转换是投影(这不是仿射;特别是透视不会保留线的并行性)。
“目标体积”是标准化设备空间中的轴对齐立方体。在标准的OpenGL中,它在所有维度中从-1到1(Direct3D,还有Vulkan,使用稍微不同的约定:[-1,1]表示x和y,但[0,1]表示z。这意味着矩阵的第三行看起来有点不同,但概念是相同的。)
构造投影矩阵,使得金字塔平截头体转换为该标准化体积。 OpenGL还使用了在眼睛空间中,相机朝向-z
的惯例。要创建透视效果,您只需将每个点投影到一个平面上,方法是将投影中心和相关点的光线与实际观察平面相交。
上面的透视矩阵假设图像平面与xy平面平行(如果你想要一个不同的平面,你可以应用一些仿射旋转)。在OpenGL眼睛空间中,投影中心始终位于原点。当你进行数学运算时,你会发现透视可以归结为截距定理的一个简单实例。如果您想将所有点投影到位于中心前方1个单位的平面(“相机”),您最终会将x
和y
除以-z
。
这可以用矩阵形式写成
( 1 0 0 0 )
( 0 1 0 0 )
( 0 0 1 0 )
( 0 0 -1 0 )
通过设置w_clip = -z_eye
来工作,所以当按剪辑空间w
进行划分时,我们得到:
x_ndc = x_clip / w_clip = - x_eye / z_eye
y_ndc = y_clip / w_clip = - y_eye / z_eye
请注意,这也适用于z:
z_ndc = z_clip / w_clip = - z_eye / z_eye = 1
这样的矩阵通常不用于渲染,因为深度信息丢失 - 所有点实际上都被投射到单个平面上。通常,我们希望保留深度(可能以某种非线性偏离的方式)。
为此,我们可以调整z(第三行)的公式。由于我们不希望z对x和y有任何依赖性,因此我们只能调整最后一个元素。通过使用表格的一行
(0 0 A B)
,我们得到以下等式:
z_ndc = - A * z_eye / z_eye - B / z_eye = -A - B / z_eye
这只是眼睛空间z值的双曲线变换变体 - 深度仍然保留 - 并且矩阵变得可逆。我们只需要计算A和B.
让我们只调用z_ndc(z_eye) = -A - B / z_eye
函数Z(z_eye)
。
由于观察体积受z_ndc = -1
(前平面)和z_ndc = 1
的限制,并且眼睛空间中近和远平面的距离作为参数给出,我们必须映射近平面{{1 }到-1,远平面z_eye=-n
到1.要选择A和B,我们必须求解一个由2(非线性)方程组成的系统:
z_eye=-f
这将导致您在矩阵的第三行中找到的两个系数。
对于x和y,我们想要控制两件事:视角的角度和视锥的不对称性(类似于投影仪已知的“镜头移位”)。视场由图像平面上的x和y范围定义,该范围映射到NDC中的[-1,1]。因此,您可以想象在与图像平面平行的任意平面上的轴对齐矩形。此矩形描述了场景中映射到可见视口的部分,距离摄像机的距离。更改视野仅意味着在x和y中缩放该矩形。
从概念上讲,镜头移位只是一种翻译,所以你可能会认为它应该放在最后一栏。但是,由于Z(-n) = -1
Z(-f) = 1
之后的除法将在矩阵乘法之后执行,因此我们必须首先乘以<{em}乘以<{1}}。这意味着翻译部分现在位于第三列,我们有一个格式
w=-z
对于x,这给出了:
-z
现在我们只需要找到正确的系数C和D,它将( C 0 D 0 )
( 0 E F 0 )
( 0 0 A B )
( 0 0 -1 0 )
映射到x_clip = (x_eye * C + D * z_eye ) / (-z_eye) = -x_eye / z_eye - D
和x_eye=l
映射到x_ndc=-1
。请注意,经典的GL视锥体函数将x_eye=r
和x_ndc=1
的值解释为近平面上的距离,因此我们必须为l
计算所有这些值。求解2个方程的新系统,您将得到在平截头体矩阵中看到的那些系数。