LearnOpengl 半透明顺序无关渲染(OIT)章节翻译

一.理论

1.介绍

在混合的章节介绍了颜色混合的主题,混合是一种在3D空间中实现半透明表面的方式,总之,半透明深入研究了像是计算机图像中的玻璃那样的半固态物体或者全透明物体的绘制的主题,这个想法在这个章节进行了适当的解释,所以如果你不熟悉这个主题,最好先看看混合章节.

在这篇文章中,我们将进一步深入探讨这个主题,因为在3d环境中实现这样一个效果时涉及许多技术。

首先,我们将讨论图形库/硬件的限制及其带来的困难,以及透明性为何是一个棘手的主题的原因。随后,我们将介绍并简要回顾过去二十年与当前硬件相关的一些更为知名的透明性技术。最终,我们将专注于解释和实现其中一种技术,这将成为本文后续部分的主题。

请注意,本文的目标是介绍具有显著更好性能的技术,而不是在“混合”章节中使用的技术。否则,没有真正引人注目的原因来扩展这个问题。

2.图形库和硬件限制

这篇文章存在以及你在阅读它的原因,是因为目前的技术没有直接的方法来绘制透明表面。许多人希望,这就像在图形 API 中打开一个标志那样简单,但这只是一个童话。这是图形库或显卡的限制,这是一个有争议的问题。

正如在混合章节中解释的那样,这个问题的根源在于深度测试和颜色混合的结合。在片段阶段,就像深度缓冲区一样,没有专门用于透明像素的缓冲区,告诉图形库哪些像素是完全可见或半可见的。原因之一可能是,在这样一个缓冲区中高效存储透明像素的信息的方法不存在,而这个缓冲区需要为屏幕上每个坐标保存无限数量的像素。由于每个透明像素可能会显露其底层像素,因此需要一种方法来存储所有屏幕坐标的所有像素的不同层。

这个限制迫使我们考虑一种克服这个问题的方法,既然图形库和硬件都没有提供帮助,所有这些都必须由开发人员用手头的工具完成。我们将研究在这个主题中突出的两种方法。一种是有序透明度,另一种是无序透明度。

3.有序的透明度

克服这个问题的最方便的解决方案是对透明对象进行排序,使他们从离相机最远的物体到离相机最近的物体,正序或者倒序依次绘制。这样,深度测试就不会影响那些在更远/更近的对象之后/之前但在更远/更近的对象上/下绘制的像素的结果。然而,尽管这种方法对 CPU 的开销很大,但在许多早期游戏中都有所使用,而我们中的大多数人可能都玩过这些游戏。

例如,下面的示例图显示了混合顺序的重要性。图像的顶部部分使用无序的 alpha 混合产生不正确的结果,而底部部分对几何图形进行了正确的排序。请注意,在没有正确深度排序的情况下,骨架结构的可见性较低。这张图是来自 ATI Mecha Demo 的:
在这里插入图片描述

到目前为止,我们已经了解到为了克服当前技术绘制透明对象的限制,我们需要对透明对象进行排序,以便它们在屏幕上能够正确显示。排序会从你的应用程序中消耗性能,而由于大多数 3D 应用程序都在实时运行,因此在每一帧进行排序将更为明显。

因此,我们将深入研究无序透明度技术的世界,并找到一种更适合我们的目的以及我们的流程的技术,这样我们就不必在绘制之前对对象进行排序。

4.半透明顺序无关渲染

无序透明度技术,简称OIT,是一种无需以有序方式绘制透明对象的技术。乍一看,这将为我们节省用于对对象进行排序的CPU周期,但与此同时,OIT技术也有其优缺点。

OIT技术的目标是在绘制时消除对透明对象进行排序的需求。根据技术的不同,其中一些必须对片段进行排序以获得准确的结果,但只是在所有绘制调用完成后的较晚阶段进行,而另一些则不需要排序,但结果是近似的。

历史

为了克服渲染透明表面的限制,一些更高级的技术明确使用一个缓冲区(例如链表或3D数组,例如[x][y][z]),该缓冲区可以保存多层像素信息并且可以在 GPU 上对像素进行排序,通常是因为 GPU 具有并行处理能力,与 CPU 相反。

A-Buffer是一项在1984年被引入的计算机图形技术,,它在一种软件光栅化器REYES中存储每个像素的片段数据列表(包括微多边形信息),最初设计用于抗锯齿,同时也支持透明度。

同时,也有硬件能够通过在硬件尚执行计算来简化这个任务,这是开发人员方便获得透明性的最直接的方式.

SEGA Dreamcast是为数不多的一些具有硬件实现的自动逐像素半透明排序的游戏主机之一。

通常,OIT技术分为两类,即精确和近似。精确的技术将产生更为准确透明度的良好图像,适用于各种场景,而近似的技术虽然能够生成外观良好的图像,但在复杂场景中缺乏准确性。

精确的OIT

这些技术精确计算最终颜色,需要对所有片段进行排序。对于深度复杂度高的场景,排序成为瓶颈。

在排序阶段的一个问题是本地内存有限的占用率,这与GPU的吞吐量和操作延迟隐藏相关的单指令多线程属性有关。尽管可以通过BMA(反向内存分配)将像素按深度复杂度分组,并批量排序它们,以提高低深度复杂度像素在潜在高深度复杂度场景中的占用率和性能。据报道,整体OIT性能增加了3倍。

排序阶段在着色器中需要相当大量的临时内存,通常是以最大值保守分配的,这会影响内存占用和性能。

通常在本地数组中进行排序,但通过利用GPU的内存层次结构,并在寄存器中进行排序性能可以进一步提高,特别是与BMA一起使用,类似于外部归并排序.

近似OIT

近似的OIT技术放宽了对准确渲染的约束,以提供更快的结果。不必存储所有片段或仅部分排序几何体可以获得更高的性能。一些技术还对片段数据进行压缩或减少。这些技术包括:

  • 随机透明度:以全不透明度更高的分辨率绘制,但丢弃一些片段。然后进行降采样将产生透明度。
  • 自适应透明度:一种两步技术,第一步构建一个在飞行中压缩的可见性函数(此压缩避免了对片段的完全排序),第二步使用此数据来合成无序片段。英特尔的像素同步避免了存储所有片段的需求,消除了许多其他OIT技术的无限制内存要求。

技术

一些行业常用的OIT技术包括:

  • 深度剥离(Depth peeling):于2001年引入,描述了一种利用深度缓冲区在每次传递时剥离一层像素的硬件加速的OIT技术。由于图形硬件的限制,必须多次渲染场景的几何体。
  • 双重深度剥离(Dual depth peeling):于2008年引入,改进了深度剥离的性能,仍然有多次渲染的限制。
  • 权重混合(Weighted, blended):于2013年发布,利用权重函数和两个缓冲区进行像素颜色和像素揭示阈值的最终合成传递。在复杂场景中产生一个具有良好质量的近似图像。

实现

在3D应用程序中执行OIT的通常方式是进行多次渲染。执行OIT技术至少需要三个渲染过程,因此为了实现这一点,您必须对OpenGL中的帧缓冲的工作原理有很好的理解。一旦熟悉了帧缓冲,一切都取决于您尝试实现的技术的实现复杂性。

简要解释一下,涉及的三个渲染过程如下:

  • 第一次渲染是绘制所有实体对象的地方,这意味着任何不让光线穿过其几何体的对象。
  • 第二次渲染是绘制所有半透明对象的地方。需要进行Alpha丢弃的对象可以在第一次渲染中渲染。
  • 第三次渲染是合成两个前面过程产生的图像并将该图像绘制到后备缓冲区上的地方。

这个例程在所有不同的渲染流水线中几乎是相同的,实现OIT技术。

在本文的下一部分,我们将实现加权混合OIT,这是过去十年来在视频游戏行业中使用的一种简单而高性能的OIT技术。

5.进一步阅读

二.实现权重混合无序透明度渲染

1.介绍

2.理论

3.限制

4.实现

总览

细节

5.延伸阅读

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值