我正在寻找一种使用 OpenGL 和 C++ 进行反向透视的方法。目前,我使用 glFrustum 来获得经典视角,但我想知道此处介绍的反向视角(https://en.wikipedia.org/wiki/Reverse_perspective及以下)是否可能?如果没有,OpenGL还有其他方法可以做到这一点吗?
1 回答
这个问题真的让我很感兴趣。我不完全相信我现在将要称为“拜占庭视角”的内容可以通过类似于(预核心配置文件)glFrustum 提供的转换来适应。Computer Graphics: Principles and Practice (2nd Ed)
不过,受OpenGL CCS / NDCS的推导和公式的启发,我已经做了一些工作。
不幸的是,原来的 SO 网站不允许嵌入 LaTeX,所以矩阵不会很漂亮。认为这个答案正在进行中
到目前为止,我已经导出了矩阵变换,导致有时被称为“归一化截锥体”。位于 的远平面Z = -1
,位于 的近平面Z = - N / F
,以及R, L, T, B
具有单位斜率的平面。(如果有一个好的图表,这将非常清楚)
[ 2N / (R - L) 0 (R + L) / (R - L) 0 ]
[ 0 2N / (T - B) (T + B) / (T - B) 0 ]
[ 0 0 1 0 ]
[ 0 0 0 F ]
称这个矩阵:[F.p]
。对于任意点:P = (x, y, - N, 1)^T
在近平面上,很容易证明变换后的齐次点位于Z = - N / F
平面上。(注意:^T
是“转置”运算符,以明确这实际上是一个列向量。)
同样,给定一个点:P = (x, y, - F, 1)^T
在远平面上,平面上变换后的齐次点线Z = -1
。
拜占庭视角需要另一个约束 - 我们将使用变量D
,其中Z = - D
是类似于 '眼睛' 处的点Z = 0
,或 '投影参考点' ( PRP )。
正如您已经从您提供的图像中收集的那样,平行线会聚在Z = - D
,而不是在“眼睛”处。但是,您不希望从收敛点获得图像。您想从“正面”可视化效果。问题是——我们能否构造一个类似于glFrustum
产生拜占庭视角的 OpenGL 矩阵?它可以适应 GL 管道吗?
到目前为止,我得出的是“标准化拜占庭截头锥”。同样,远平面位于Z = -1
,近平面位于Z = - N / F
,并且R, L, T, B
平面具有单位斜率——尽管是正平截头体的负斜率。(再次清晰的图片在这里值得一千字)
[ 2N / (R - L) 0 (R + L) / (R - L) 0 ]
[ 0 2N / (T - B) (T + B) / (T - B) 0 ]
[ 0 0 N / F 0 ]
[ 0 0 0 N ]
称这个矩阵:[F.b]
。坐标变换是相同的X,Y
,但Z,W
分量变换不同。这有点直观,因为从某种意义上说,这是正统视图体积的“反转”。
再次,给定一个点:P = (x, y, - N, 1)^T
在近平面上,变换后的齐次点位于Z = - N / F
平面上,点的齐次变换:P = (x, y, - F, 1)^T
在远平面上位于Z = -1
平面上。
考虑到矩阵的相似性,以及只需要简单的透视变换(以及一些简单的缩放和平移矩阵)来产生符合 OpenGL 剪辑坐标空间 (CCS) 及其 NDCS 投影的平行投影矩阵,似乎可能会使OpenGL“拜占庭”投影起作用。我只是需要更多的时间来处理它...