10

我一直在学习 OpenGL,而一直困扰我的一个主题是远剪裁平面。虽然我可以理解近剪裁平面和侧剪裁平面背后的原因(它们永远不会产生任何实际效果,因为它们之外的对象无论如何都不会被渲染),远剪裁平面似乎只是一个烦恼。

由于 OpenGL 背后的人显然已经考虑到这一点,我知道我肯定缺少一些东西。为什么OpenGL有一个远裁剪平面?更重要的是,由于您无法将其关闭,因此在远距离绘制事物时(例如太空游戏中数千单位外的星星、天空盒等对象),推荐使用哪些习惯用法和做法?您是否希望将剪裁平面制作得非常远,还是有更优雅的解决方案?这是如何在生产软件中完成的?

4

3 回答 3

19

唯一的原因是深度精度。由于深度缓冲区中只有有限数量的位,因此您也可以只用它来表示有限的深度。

但是,您可以将远平面设置为无限远:请参阅。它不能很好地与深度缓冲区一起工作——如果你有很远的遮挡,你会看到很多伪影。

因此,由于这围绕深度缓冲区,只要您不使用它,您就不会遇到处理更远的东西的问题。例如,一种常见的技术是在“slabs”中渲染场景,每个slabs只在内部使用深度缓冲区(对于一个slab中的所有东西)但在外部使用某种形式的画家算法(对于slabs,所以你画最远的一个第一的)

于 2012-08-14T09:19:50.600 回答
8

为什么OpenGL有一个远裁剪平面?

因为计算机是有限的。

通常有两种方法可以尝试处理这个问题。一种方法是通过在 z-far 接近无穷大时取极限来构造投影。这将收敛于有限值,但它可能会严重破坏您对远处物体的深度精度。

另一种选择(如果您愿意让超过一定距离的物体根本无法正确进行深度测试)是使用glEnable(GL_DEPTH_CLAMP). 这将防止夹在近平面和远平面上;只是任何将在 [-1, 1] 范围之外归一化 z 坐标的片段都将被限制在该范围内。如前所述,它会在被夹住的碎片之间搞砸深度测试,但通常这些物体距离很远。

于 2012-08-14T09:45:35.393 回答
0

这只是“事实”,OpenGL深度测试是在窗口空间坐标中执行的(在 [-1,1]^3 中的标准化设备坐标。具有额外的缩放 glViewport 和 glDepthRange)。

所以从我的角度来看,这是 OpenGL 库的设计观点之一。


消除此 OpenGL 扩展/OpenGL 核心功能的一种方法https://www.opengl.org/registry/specs/ARB/depth_clamp.txt如果它在您的 OpenGL 版本中可用。


我想描述的是,在透视投影中,没有关于“远裁剪平面”的内容。

3.1 对于透视投影,您需要将点 \vec{c} 设置为投影中心和将在其上执行投影的平面。我们称它为图像平面 T: (\vec{r}-\vec{r_0},\vec{n})

3.2 假设投影平面 T 分裂任意点 \vec{r} 和 \vec{c} 投影中心。在其他情况下,\vec{r} 和 \vec{c} 在一个 hafe-space 中,点 \vec{r} 应该被丢弃。

3.4 投影的思想是求\vec{i}与平面T的交点\vec{i}=(1-t)\vec{c}+t\vec{r}

3.5 原样 (\vec{i}-\vec{r_0},\vec{n})=0

=>

( (1-t)\vec{c}+t\vec{r}-\vec{r_0},\vec{n})=0

=>

( \vec{c}+t(\vec{r}-\vec{c})-\vec{r_0},\vec{n})=0

3.6. 从“3.5”派生的 t 可以代入“3.4”,您将收到到平面 T 的投影。

3.7. 投影后,您的点将位于平面内。但是如果假设图像平面与 OXY 平面平行,那么我可以建议在投影后使用原始“深度”作为点。

所以从几何的角度来看,根本不使用远平面是可能的。也根本不使用 [-1,1]^3 模型。

ps 我不知道如何以正确的方式输入乳胶公式,它们将被渲染。

于 2016-02-07T21:14:01.610 回答