我一直在学习OpenGL,而另一个让我感到困惑的主题是远剪裁平面。虽然我可以理解近剪裁平面背后的原因,以及侧面剪裁平面(由于它们外面的物体永远不会被渲染,但它们从来没有任何实际效果),远剪裁平面似乎只是一种烦恼。
由于OpenGL背后的人显然已经想到这一点,我知道必须有一些我遗漏的东西。为什么OpenGL有一个远剪裁平面?更重要的是,因为你无法将其关闭,在远距离绘制物体时使用的推荐成语和做法是什么(对于诸如太空游戏,天空盒等数千个单位之外的星星等物体)?您是否希望将剪裁平面放得很远,还是有更优雅的解决方案?这是如何在生产软件中完成的?
答案 0 :(得分:20)
唯一的原因是深度精度。由于深度缓冲区中只有有限的位数,因此您也可以用它来表示有限的深度。
但是,您可以将远平面设置为无限远:请参阅this。它对深度缓冲区效果不佳 - 如果你有很远的遮挡,你会看到很多文物。
因此,由于这围绕深度缓冲区,只要你不使用它,你就不会有处理更远的东西的问题。例如,一种常见的技术是在“平板”中渲染场景,每个场景仅在内部使用深度缓冲区(对于一个平板中的所有东西),但在外部使用某种形式的画家算法(对于平板,因此您绘制最远的一个)第一)
答案 1 :(得分:9)
为什么OpenGL有一个远剪裁平面?
因为计算机有限。
通常有两种方法可以尝试解决这个问题。一种方法是通过将极限设为z-far接近无穷大来构建投影。这将收敛于有限值,但它会对远距离物体的深度精度造成严重破坏。
另一种选择(如果你愿意让超过一定距离的物体完全无法正确深度测试)是用glEnable(GL_DEPTH_CLAMP)
开启深度钳制。这样可以防止近距离和远距离平面的削波;只是在[-1,1]范围之外将标准化z坐标的任何片段都会被限制在该范围内。如前所述,它会在被夹住的碎片之间拧紧深度测试,但通常这些物体很远。
答案 2 :(得分:0)
它只是"事实" OpenGL 深度测试是在Window Space Coordinates中执行的(标准化设备坐标在[-1,1] ^ 3中。额外缩放glViewport和glDepthRange)。
因此,从我的观点来看,这是OpenGL库的设计观点之一。
如果在OpenGL版本中可用,则消除此OpenGL扩展/ OpenGL核心功能https://www.opengl.org/registry/specs/ARB/depth_clamp.txt的方法之一。
我想描述一下,在透视投影中,没有关于"远剪裁平面"。
3.1对于透视投影,您需要将point \ vec {c}设置为投影中心和将在其上执行投影的平面。我们称之为 图像平面T:(\ vec {r} - \ vec {r_0},\ vec {n})
3.2让我们假设投影平面T分裂任意点\ vec {r}和\ vec {c}投影的中心。在其他情况下,\ vec {r}和\ vec {c}位于一个hafe-space中,而point \ 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模型。
P.S。我不知道如何以正确的方式输入乳胶配方,s.t。他们将被渲染。