渲染半透明物体的顺序

3
当渲染半透明物体(使用glBlend)时,建议按照从后到前的z顺序对对象进行排序。
来自opengl docs: 在应用中使用深度缓冲时,需要注意以何种顺序呈现基元。需要首先呈现完全不透明的基元,然后是部分不透明的基元,按照从后向前的顺序。如果不按照此顺序呈现基元,则本来可以通过部分不透明基元看到的基元可能会完全失去深度测试。
所以,每当我在呈现不透明三角形之后呈现半透明物体时,如果我按照“视线方向”相对于后面的顺序呈现半透明三角形,这样做是否正确?这里“从后往前”具体是什么意思?我试图理解,如果我有一个经过mvp变换的场景对象,我是否需要特别查看世界坐标的顺序,并与相机中心相关?
另外,这是否会因混合类型而改变?

这个OpenGL - 如何创建无序透明度?或许会引起你的兴趣。 - Spektre
2个回答

3
无论何时渲染半透明三角形,您都必须按照后到前的顺序绘制它们。这里的后到前意味着,您必须首先绘制距离屏幕更远(具有较高深度值)的三角形。
这样做的原因是,大多数混合方程式根据顺序产生不同的结果。在OpenGL中实现的方程式通常是这样的,当按照后到前的顺序渲染时,可以给出“正确”的结果。

请问您能否详细解释一下这里所说的“从后到前”与屏幕有关的含义?具体来说,是相机中心和世界坐标方面的。大多数解释都缺少一些细节。 - dev_nut
1
定义是:从更高的深度值到更低的深度值。在世界坐标系中,这意味着您必须首先绘制距离相机中心更远的对象。 - BDL
1
@dev_nut 这意味着你需要优先在相机空间中渲染最远的面(而不是在世界空间中)。对于相交的半透明多边形来说,这并不是一件容易的事情。 - Spektre
1
如果多边形相交,那么你需要在交点处对它们进行细分。我猜如果几何图形是静态的,这不是一个问题,因为细分可以在渲染之前完成,但如果它是一些动态网格,那么就需要一些非常好的多边形处理逻辑了。 - dev_nut
@dev_nut 是的,确切地说,有一些解决方法,但请参见我在您问题下面链接的QA中的答案。此外,如果您知道您只有几个透明层,您可以在运行时记住几个深度渲染层(深度排序片段而不是多边形),并在最后组合(但这在GPU上实现非常困难)。如果您不想转向光线追踪,我认为其中一个答案中的nVidia论文是您在这种情况下的最佳选择。 - Spektre

0

我认为顺序的重要性不仅在于您使用的混合函数,还有一点是管线中必须牢记的重要方面。在管线中,z测试发生在混合操作之前。考虑这样一种情况,我们正在绘制两个三角形t1和t2,其中t1在t2的后面。

因此,如果z测试拒绝了所有属于t1的片段,则不会将任何颜色值写入颜色缓冲区。现在,稍后绘制t2片段,它恰好在上一步中被z测试拒绝的t1的前面。因此,理想情况下,t1的颜色应该与t2的颜色混合,但由于t1的z测试失败并且混合操作在z测试之后,t2的颜色不会混合。

因此,如果您没有保持顺序,则禁用z测试,然后使用适当的混合函数绘制对象。这对性能来说并不好,因为许多z测试将失败。

因此,您可以维护多边形的顺序,但是随着多边形数量的增加以及不透明和透明对象的混合,这种解决方案也无法扩展。

因此,提出了使用无序透明度的新解决方案。有不同的实现方式,您不必担心对象的顺序。

我已经在片段着色器中使用每像素链接列表实现了解决方案。您可以在下面找到链接。这不是最佳解决方案,但应该能给您一个公平的想法。

无序透明度


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接