扩展Unity 5渲染管线:命令缓冲区

在Unity 5中,我们增加了许多用户可见的图形功能(新标准着色器、实时全局光照、反射探针、新的光照贴图工作流程等),但我们也进行了内部渲染。除了“优化它”(例如多线程光源剔除)和“使它更一致”(例如线性和伽马颜色空间之间更一致)等典型内容外,我们还研究了如何使它具有更高的扩展性。
在内部和 Beta 测试小组中,我们讨论了各种方法。大家提出了很多想法:更多的脚本回调,组装小的“要做的事情列表”缓冲区,从头开始创建完整的渲染管线的能力,某种可视化树/图渲染管线构建工具等等。对于Unity 5,我们解决了创建“要做的事情列表”缓冲区的能力问题,我们将其称为“命令缓冲区”。
图形中的命令缓冲区是要执行的命令的低级列表。例如,Direct3D 或 OpenGL 等 3D 渲染 API 通常最终会构建一个命令缓冲区,然后由 GPU 执行。Unity 的多线程渲染器还在调用线程和向渲染 API 提交命令的“工作线程”之间构建命令缓冲区。
我们的想法非常相似,但“命令”级别略高。其中不包含“将内部 GPU 寄存器 X 设置为值 Y”等内容,而是包含“使用材质绘制此网格”等命令。
从脚本中,您可以创建命令缓冲区并向其中添加渲染命令 ⁇ “set render target, draw mesh, …”)。然后,可以将这些命令缓冲区设置为在摄像机渲染期间的不同点执行。
例如,您可以在完成所有常规对象后将一些其他对象渲染到 ⁇ 延迟着色 ⁇ G 缓冲区中。或者在绘制天空盒后立即渲染一些云,但要先于任何其他对象。或者,在所有常规光照完成后,将自定义光源(体积光源、负光源等)渲染到延迟着色光源缓冲区中。等等;我们认为有很多有趣的使用方式。
请查看脚本API文档中的CommandBuffer和CameraEvent页面。
好的 好的
例如,我们可以进行模糊折射:

渲染不透明对象和天空盒后,会将当前图像复制到临时渲染目标中,模糊处理并设置为全局着色器属性。然后,玻璃对象上的着色器对模糊的图像进行采样,使用基于法线贴图的 UV 坐标偏移来模拟折射。 这与 ⁇ 着色器 GrabPass 的用法类似,只不过您可以执行更多自定义操作(在本例中为模糊)。
另一个用例:自定义延迟光源。 下面是球状和管状光源:

完成常规延迟着色光传递后,将为每个自定义光源绘制一个球体,并使用着色器计算光照并将其添加到光照缓冲区。
还有一个例子:延迟贴花。

我们的想法是:G 缓冲区完成后,绘制贴花的每个“形状”(一个方框),然后修改 G 缓冲区内容。这非常类似于延迟着色中的光照处理方式,只不过我们不是累积光照,而是修改G缓冲区纹理。

每个贴花在这里实现为一个方框,并影响方框体积内的任何几何体。
实际上,这是一个演示上述所有内容的小型 Unity (5.0 beta 22) 项目文件夹: RenderingCommandBuffers50b22.zip。
您可以看到,上述所有情况的实现都并不复杂 - 脚本大约有数百行代码。
我认为这令人兴奋。迫不及待地想看看你们都用它来做什么!
