c++ - OpenGL如何反向透视?

标签 c++ opengl glfrustum

我正在寻找一种使用OpenGL和C++进行反向透视的方法。目前,我正在使用glFrustum进行经典透视,但是我想知道是否有可能出现此处介绍的反向透 View (https://en.wikipedia.org/wiki/Reverse_perspective及以下)?如果没有,OpenGL还有其他方法吗?

enter image description here

最佳答案

这个问题真的让我很感兴趣。我并不完全相信我现在要称为“拜占庭式透 View ”的内容可以通过类似于(核心前配置文件)glFrustum提供的转换来容纳。不过,受 Computer Graphics: Principles and Practice (2nd Ed) 派生以及OpenGL CCS / NDCS的启发,我已经做了一些工作。

不幸的是,原始的S.O.该网站不允许使用嵌入式LaTeX,因此矩阵不会很漂亮。 认为此答案正在进行中

到目前为止,我已经得出了矩阵变换,导致有时称为“归一化frustum”。 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是'transpose'运算符,以明确表明它实际上是列 vector 。)

同样,在远平面上给定一个点:P = (x, y, - F, 1)^T,在Z = -1平面上变换后的同质点线。

拜占庭式透 View 还需要另一个约束-我们将使用变量D,其中Z = - D是类似于Z = 0上的“眼睛”或“投影引用点”( PRP )的点。

从提供的图像中收集数据后,平行线会聚在Z = - D处,而不是在“眼睛”处会聚。但是,您不希望从融合的 Angular 出发获得形象。您想从“前端”形象化效果。问题是-我们可以构造类似于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分量转换是不同的。从某种意义上说,这是对正统 View 体积的“反转”,这在某种程度上是直观的。

同样,给定一个点:近平面上的P = (x, y, - N, 1)^T,变换后的同质点位于Z = - N / F平面上,而一个点的同质变换:P = (x, y, - F, 1)^T在远平面上位于Z = -1平面上。

考虑到矩阵的相似性,并且只需要简单的透视变换(以及一些琐碎的缩放和平移矩阵)就可以产生符合OpenGL剪辑坐标空间(CCS)及其NDCS投影的并行投影矩阵,这一事实似乎可能可以使OpenGL“拜占庭”投影起作用。我只需要更多时间来做...

关于c++ - OpenGL如何反向透视?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60827377/

相关文章:

c++ - 为什么这个算法(Floyd Warshall 算法)只适用于 100000007?

c++ - 如何在 udp 连接中绕过 NAT/防火墙

c++ - boost::lexical_cast<signed char> 无法处理负数?

c++ - 虚函数破坏私有(private)访问

opengl - 如何在着色器中旋转和平移矩形纹理

performance - 避免使用 OpenGL 顶点数组在屏幕外绘制

opengl - 如果我使用 early_fragment_tests 丢弃着色器中的片段,深度缓冲区会发生什么?

c++ - 我如何计算 glFrustum 参数?