1

如何制作自己的 z 缓冲区以正确混合 Alpha 通道?我正在使用glsl。我只有一个想法。这是使用 2 个“缓冲区”,其中一个存储深度分量和另一种颜色(带有 alpha 通道)。我不需要在我的程序中访问缓冲区。我不能使用统一数组,因为 glsl 对统一变量的数量有限制。我不能使用 FBO,因为没有定义有时写入和读取帧缓冲区的行为(并且不在任何卡上工作)。

我该如何解决这个问题?!

或者如何从 glsl 读取实际的实时 z-buffer?(我的意思是对于每个片段着色器调用 z-buffer 必须更新)

4

2 回答 2

3

如何制作自己的 z 缓冲区以正确混合 Alpha 通道?

那是不可能的。为了获得完美的与顺序无关的透明度,您必须摆脱 z-buffer 并用另一种机制替换它以去除隐藏表面。

使用 z-buffer 有两种可能的方法来解决这个问题。

  1. 多层 z 缓冲区(硬件加速不切实际) - 基本上它将存储几层“深度”值并将其用于混合透明表面。会占用大量内存,并且将有最大数量的透明叠加表面,一旦超过限制,就会出现伪影。
  2. 深度剥离(谷歌它)。订购独立透明度,但每个像素的“重叠”透明多边形的最大数量有限制。实际上可以在硬件上实现。

两种方法都有一个限制(每个像素重叠透明多边形的最大数量),一旦超过限制,场景将不再正确渲染。这意味着整个事情毫无用处。

您实际上可以做的(以获得完美的解决方案)是完全删除 zbuffer,并制作一个图形渲染管道,该管道将收集所有要渲染的多边形,剪辑它们,分割它们(当两个多边形相交时),对它们进行排序然后绘制它们以正确的顺序显示在屏幕上,以确保您获得正确的结果。但是,这很难,而且使用硬件加速更难。我认为(我不完全确定它是否发生过)5 或 6 年前,一些 ATI GPU 相关文档提到,他们的一些卡可以通过启用某种扩展来渲染正确的场景,同时禁用 Z-Buffer。然而,他们没有说关于阿尔法混合的事情。从那以后我就再也没有听说过这个功能。也许它没有流行起来并与 TruForm 一样(被遗忘)。

于 2012-03-23T23:31:41.627 回答
2

如果它是与顺序无关的透明度,那么根本问题是深度缓冲区存储每个像素的深度,但是如果您正在组成部分透明几何图形的视图,那么每个像素都会有多个片段。

如果你要稳健地解决问题,你需要一个有序的每像素深度列表,回到最近的不透明片段。然后你会以相反的顺序遍历列表。实际上,OpenGL 不做可变大小数组之类的事情,因此人们通过以从后到前的顺序绘制几何图形来实现这一点。

体现的另一种选择GL_SAMPLE_ALPHA_TO_COVERAGE是切换到纱门透明度,无论是在真正高分辨率还是在多重采样下,这与真正的透明度没有区别。理想情况下,您会随机执行此操作,但这会使 OpenGL 的可重复性规则无效。不过,既然你在 GLSL 中,你可以自己做。您的采样器只需获取输入 alpha 并将其用作输出最终像素的概率。因此,从某处获取 0.0 到 1.0 范围内的随机值,如果它大于 alpha,则丢弃该像素。始终以 1.0 的 alpha 输出并仅使用正常的深度缓冲区。像这样的答案更多地说明了如何在 GLSL 中获取随机数,并且显然您希望尽可能提高多重采样。

Eric Enderton 写了一篇关于随机顺序无关透明度的不错的论文(有幻灯片版),与值得一试的 DirectX 实现一起使用。

于 2012-03-23T20:40:35.993 回答