2

我正在尝试在 OpenGL 中实现透明度,从我读过的内容来看,有必要首先渲染所有不透明对象,然后以正确的顺序渲染透明对象。

我的问题是如何在场景图中将不透明对象与透明对象分开,以便我可以首先渲染不透明对象。我的场景图由一堆节点组成,这些节点可以附加实体,每个实体可以由多个具有不同材质的网格组成,每个网格都有一个或多个纹理。

如果我将一个场景加载到我的图表中,我需要知道哪些材质是部分或完全透明的,这意味着我需要检查加载的纹理是否有任何小于 1 的 alpha 值。我目前正在使用 Assimp 来处理加载模型/场景和 SOiL 来读取纹理,我还没有找到任何简单的方法来区分透明材料和不透明材料。

这可能有一个非常简单的解决方案,因为我还没有找到其他人有同样的问题,但我仍然从 OpenGL 开始,过去几个小时我一直坚持这个问题。

透明度通常是如何完成的,不透明对象如何与部分或完全透明的对象分开,以便可以首先渲染它们?

4

1 回答 1

1

对于大多数渲染方法,您不必严格将不透明对象与透明对象分开。如果您考虑一下,透明度(或不透明度)是一种持续的质量。在 OpenGL 中,alpha 组件通常用于定义不透明度。不透明物体的 alpha 值为 1.0,但这只是连续光谱中的一个值。能够正确处理所有 alpha 值的方法不会因为 alpha 值恰好是 1.0 而突然失败。

换一种说法:alpha 值为 0.9 的对象是否不透明?如果 alpha 值为 0.99,你能证明它与 alpha 值 1.0 不同吗?它实际上是连续的,而不是二元决策。

话虽如此,但对不透明对象进行不同处理是有原因的。我能想到的主要有:

  1. 由于必须为常用的简单透明度渲染方法对非透明对象进行排序,因此您可以通过仅对非透明对象进行排序来节省工作。排序并不便宜,而且您可以通过这种方式减少处理时间。对于这些方法中的大多数,您可以通过对所有对象进行排序来获得非常好的结果,但代价是效率较低。

  2. 很多时候,对象不能被完美地排序,或者至少这样做并不容易。一个明显的问题是对象重叠时,但挑战超出了这种情况(有关有问题的情况的更深入说明,请参见我的答案:关于 OpenGL 透明度的一些问题)。在这些情况下,您会从不正确的排序中获得工件。通过在启用深度测试的情况下绘制不透明对象,您可以避免这些对象出现伪影的可能性,并减少明显伪影的总体发生率。

您不知道哪些对象包含透明度的情况似乎有些不寻常。在大多数情况下,您知道哪些对象是不透明的,因为您可以控制渲染和内容。因此,拥有一个指定对象是否不透明的属性通常是免费的。

如果您真的无法定义哪些对象是不透明的,那么您可以想到几个选项。第一个是您对所有对象进行排序,并按顺序呈现它们。根据上面的解释,您可能会遇到性能或质量下降,但值得尝试。

有一些方法可以在不需要排序或分离不透明和透明对象的情况下进行透明渲染。一个简单的想法是 alpha-to-coverage。特别是如果您使用 MSAA 进行渲染,则不会产生任何开销。缺点是质量可能很一般,具体取决于场景的性质。但同样,值得一试。

你可以在我对这个问题的回答中找到关于 alpha-to-coverage 的基本解释,以及其他一些简单的透明度渲染方法:OpenGL ES2 Alpha test questions 。

有更高级的透明度渲染方法部分依赖于最近的硬件功能。涵盖它们超出了此处帖子的范围(并且在很大程度上超出了我的知识...),但是您应该能够通过搜索“与订单无关的透明度”来找到材料。

于 2015-12-29T06:31:43.000 回答