为什么我的几何着色器中的OpenGL剪辑基元不能部分位于查看体积之外?

时间:2011-08-02 00:02:47

标签: opengl clipping geometry-shader

http://www.opengl.org/wiki/Rendering_Pipeline_Overview表示在运行几何着色器之后和光栅化片段之前,“位于观看体积内部和外部之间的边界上的图元被分成几个图元”。我读过的关于OpenGL的其他所有内容也以同样的方式描述了剪切过程。但是,通过将碎片着色器中的gl_FragDepth设置为比生成它的三角形上的点的实际深度更接近摄像机的值(以便碎片通过深度测试时,如果我复制固定,它将失败 - 管道功能),我发现即使它与远视平面部分重叠,也会为整个原始三角形生成片段。另一方面,如果所有顶点都在平面后面,则整个三角形被剪切,并且没有片段被发送到片段着色器(我想更技术上你会说它被剔除,而不是剪辑)。

这里发生了什么?我的几何着色器是否会替换某些默认功能?是否需要设置标记/提示或我需要写入的其他内置变量,以便渲染管道的下一步知道如何进行部分裁剪?

我在NVIDIA GeForce 9400M上使用了带有GL_EXT_geometry_shader4扩展名的GLSL 1.2版。

2 个答案:

答案 0 :(得分:1)

这听起来像是一个驱动程序错误。如果您可以看到应该在查看区域之外的片段的结果(即:如果关闭深度写入会导致片段完全消失),那么这就违反了规范的行为。

当然,这是一个极端的案例,我怀疑任何人都会对此采取任何行动。

大多数图形硬件都尽可能地努力避免实际剪切三角形。剪切三角形意味着可能从单个三角形生成3个以上的三角形。这往往会阻碍管道(无论如何都要预先细分)。因此,除非三角形可以轻易地被拒绝(即:在剪辑盒外面)或非常大,现代GPU只是忽略它。他们让片段剔除硬件来处理它。

在这种情况下,因为片段着色器是深度书写着色器,所以它认为在片段着色器完成之前它不能拒绝这些片段。


注意:我意识到如果你打开深度钳位,就会关闭完全的近距离和远距离剪辑。这可能是你想要的。从片段着色器写入的深度值将被钳制到当前glDepthRange

深度钳位是OpenGL 3.2的一项功能,但NVIDIA已经使用NV_depth_clamp支持了近十年。如果您的驱动程序是最新的,即使您没有获得3.2兼容性上下文,也应该能够使用ARB_depth_clamp。

答案 1 :(得分:-1)

如果我理解正确,你会想知道你的三角形没有被夹在远处的平面上 在顶点组装后,Afaik OpenGL只会对4个边界平面进行剪裁。在片段着色器之后完成远近剪辑(通过spec afaik)。即当你极大地放大并且多边形与近平面碰撞时,它们会被渲染到那个点并且不会作为一个整体弹出。
而且我认为规范根本没有注意分裂原语(即使hw可能在屏幕空间中忽略了fragdepth),它只是注意跳过原语作为一个整体(在没有顶点位于视锥体的情况下)。
同样依赖于wiki的单词精确规则总是一个坏主意。

PS:http://fgiesen.wordpress.com/2011/07/05/a-trip-through-the-graphics-pipeline-2011-part-5/解释了实际边界和近距离和远距离剪辑非常好。