可以启用Alpha混合以使表面透明,如下所示:

glDisable(GL_DEPTH_TEST); //or glDepthMask(GL_FALSE)? depth tests break blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


,但这仅在对象以从前到后的顺序渲染时有效。否则,背景中的物体会出现在较近的物体之前,例如下图的地板。对于粒子和GUI元素,可以进行排序,但是对于三角形网格,似乎需要太多的努力和速度,如此处所述:https://www.opengl.org/wiki/Transparency_Sorting。

处理此问题的常用方法是什么?我知道这是相当广泛的内容,不需要深入的实现细节,而只是对一些方法及其可能涉及的内容进行了简要说明。



评论

我不确定这是否应该作为答案,但是图像中的错误是由未对所有基元进行深度测试的渲染引起的。您应该分两步渲染场景:首先通常渲染所有实体几何。然后,禁用深度写入(不是GL_DEPTH_TEST),并以从后到前的顺序渲染半透明几何体。这样可以确保不会在透明几何图形的前面绘制透明几何图形。

@yuriks在这种情况下,这对我来说可能是一个糟糕的例子,但所有内容都是透明的。我想要一些东西来说明如果做得不好,透明性会看起来如何。另一个例子是很难对几何进行排序(例如,这里的地板是一个巨大的多边形,并且覆盖了整个深度范围)。

#1 楼

避免显式排序的一组技术以“顺序独立透明性”(简称“ OIT”)命名。

有很多OIT技术。

从历史上讲,深度剥离是一种。在这种方法中,您首先渲染最前面的片段/像素,然后找到最接近上一步中的片段/像素,依此类推,然后根据需要进行“层”的操作。
之所以称为深度剥离,是因为每次通过时,您都会“剥离”一层深度。然后,通常可以从后到前重新组合所有图层。
要实现此算法,您需要拥有深度缓冲区的副本。

另一套技术是blendend OIT技术。 McGuire和Bavoil提出的一种加权混合OIT是最新,最有趣的一种。它基本上将加权总和应用于占据给定片段的所有表面。他们提出的加权方案基于摄影机空间Z(作为遮挡的近似值)和不透明度。
想法是,如果您可以将问题减少到加权总和,则您实际上并不关心排序。

除原始论文外,Matt Pettineo的博客中提供了有关实施细节和加权混合OIT问题的重要资源。从他的帖子中可以看出,这种技术不是万灵丹。主要问题是加权方案是中心方案,需要根据您的场景/内容进行调整。
从他的实验中可以看出,虽然该技术对于相对较低和中等的不透明性似乎可以很好地工作,但是当不透明性接近1时它就失败了,因此不能用于表面大部分不透明的材料中(他举例说明)叶子)。

同样,所有这些都取决于您如何调整深度权重,找到适合您的用例的深度权重不一定很简单。

至于加权混合OIT所需的功能,无非就是两个额外的渲染目标。用预乘的Alpha颜色(color * alpha)和Alpha填充的颜色,都将相应地加权。另一个仅用于权重。

#2 楼

一种选择是使用深度剥离。

基本上,一个场景处理场景一定次数(例如n次),以便确定最接近,第二近的,一直到n的场景的最接近片段。

首先通过对整个场景进行常规深度测试(自然返回最接近的表面)来完成此处理。然后,通过忽略深度小于深度测试返回值的所有内容,使用深度测试结果过滤掉第一层。

再次应用深度测试将返回第二层。根据需要重复。

一旦有了图层,就可以按照相反的顺序绘制所有图层(假设您跟踪每个图层的RGBA颜色),正常混合,因为这些图层位于前后顺序。

评论


$ \ begingroup $
谢谢!看来我需要两个深度缓冲区。即一个用于存储和过滤出最后的深度,另一个用于对当前渲染进行深度测试。如果我错了,请纠正我,但我想我需要为FBO使用两个深度纹理,并在每次剥皮过程之间交换。
$ \ endgroup $
– jozxyqk
15年8月9日在9:07

$ \ begingroup $
@jozxyqk正确,此过程需要两个深度缓冲区。
$ \ endgroup $
–es1024
15年8月9日在9:09

#3 楼

单次通过(没有(或很少))的奶油不会损害OpenGL中的透明性,它是A缓冲区。使用现代OpenGL,可以实现:

http://blog.icare3d.org/2010/06/fast-and-accurate-single-pass-buffer.html

避免了多次深度剥离,并且不需要繁琐的分拣。

评论


$ \ begingroup $
理想情况下,答案应该是独立的,并且在很大程度上取决于外部链接。拥有链接非常适合作为补充材料,但是答案不应该仅由关键字组成。如果您可以提供有关什么是A缓冲区及其工作原理的详细信息,那将大大改善您的答案。
$ \ endgroup $
–马丁·恩德(Martin Ender)
15年8月12日在9:38