我一直在学习OpenGL,一个继续困扰我的话题是远距离剪切平面。 虽然我可以理解近剪裁平面和侧面剪裁平面背后的原因(它们永远不会有任何实际效果,因为它们外面的对象无论如何都不会被渲染),但远剪裁平面似乎只是一个烦恼。
既然OpenGL背后的人显然已经考虑过这一点,我知道我一定错过了什么。 为什么OpenGL有一个远的剪切平面? 更重要的是,因为您无法将其关闭,因此在远距离绘制事物时(对于太空游戏中数千个单位外的恒星、天空盒等物体)时,推荐使用哪些习语和做法? 您是期望将剪切平面做得很远,还是有更优雅的解决方案? 这在生产软件中是如何完成的?
唯一的原因是深度精度。由于深度缓冲区中只有有限数量的位,因此也可以使用它只表示有限数量的深度。
但是,您可以将远平面设置为无限远:请参阅此处。它不能很好地与深度缓冲区配合使用 - 如果你在很远的地方有遮挡,你会看到很多伪影。
因此,由于这是围绕深度缓冲区展开的,因此只要您不使用它,处理更远的东西就不会有问题。例如,一种常见的技术是在"平板"中渲染场景,每个"平板"仅在内部使用深度缓冲区(对于一个平板中的所有内容),但在外部使用某种形式的画家算法(对于平板,因此您首先绘制最远的)。
为什么OpenGL有一个远的剪切平面?
因为计算机是有限的。
通常有两种方法可以尝试处理此问题。一种方法是在 z 远接近无穷大时采用极限来构建投影。这将收敛于有限值,但它可能会对远距离物体的深度精度造成严重破坏。
另一种选择(如果您愿意让超过一定距离的物体根本无法正确进行深度测试)是使用 glEnable(GL_DEPTH_CLAMP)
打开深度钳制。这将防止对近平面和远平面进行剪裁;只是任何将 Z 坐标归一化在 [-1, 1] 范围之外的片段都将被钳制到该范围。如前所述,它会在被夹紧的碎片之间搞砸深度测试,但通常这些物体离得很远。
OpenGL 深度测试是在窗口空间坐标([-1,1]^3 中的规范化设备坐标)中执行的只是"事实"。具有额外的缩放 glViewport 和 glDepthRange)。
所以从我的角度来看,这是OpenGL库的设计观点之一。
消除此OpenGL
扩展/OpenGL核心功能的方法之一 https://www.opengl.org/registry/specs/ARB/depth_clamp.txt OpenGL版本中是否可用。
我想描述一下,在透视投影中,没有关于"远剪切平面"的内容。
3.1 对于透视投影,您需要将点 \vec{c} 设置为投影中心和将在其上执行投影的平面。我们称之为Image plane T: (\vec{r}-\vec{r_0},\vec{n})
3.2 假设投影平面 T 拆分投影中心的任意点 \vec{r} 和 \vec{c}。在其他情况下,\vec{r} 和 \vec{c} 在一个 hafe 空间中,点 \vec{r} 应该被丢弃。
3.4 投影的思想是找到与平面 T 的交集 \vec{i}\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 模型。
附言我不知道如何以正确的方式输入乳胶配方,s.t. 它们将被渲染。