在Unity 5中,我们已经添加了许多用户可见的图形功能(全新的标准shader,实时的全局照明,反射探针,全新的光照贴图工作流等等),但我们也做了渲染的内部构件。除了典型的像“优化它”的功能(例如,多线程光照遮挡剔除处理)和“更具持续性”的功能(例如,在线性颜色空间和伽马颜色空间增加更多的一贯性),我们还探讨如何使它具有更多的可扩展性。
在测试组内部,我们已讨论过多种方法。提出了许多想法:更多的脚本调回,整合出更小的“尚待完成的工作列表”的缓冲区,可以从头开始创建出完全渲染的工作流,并带有某种渲染构建工具功能的视觉树或图形。对于Unity 5而言,我们可能创建出“工作列表”的缓冲区,我们把它称之为“Command Buffers”。
图形中的命令缓冲区表示要执行的命令的低级列表。例如,像Direct3D 或OpenGL一样的3D渲染API,通常会结束创建一个命令缓冲区,最终由GPU完成。Unity的多线程渲染器也会在调回线程和“工作线程”之间创建一个命令缓冲区,从而提交命令给渲染中的API。
在我们的例子中,与上述想法相似。但“命令”却是更高的水准。不采取“内部的GPU寄存器,把X值赋值到Y值上”。取而代之的执行命令是“用材料绘制网格”等等。
从你的脚本来看,你能够创建命令缓冲区,并在其中添加渲染命令(“设定渲染目标,绘制网格……”)。随后,这些命令缓冲区可以在相机渲染时的不同点位处执行操作。
例如,所有的常用对象完成后,你可以渲染一些额外的对象到延迟渲染的G-buffer中。或者是天空盒拖动后,立刻渲染一些云层。再或者是在所有普通灯完成之后,渲染自定义光照(体积光、负光等等)到延迟渲染灯光缓冲区中。
在API文档脚本中,请看CommandBuffer和CameraEvent的界面。http://docs.unity3d.com/500/Documentation/ScriptReference/Rendering.Comm...
好吧,来举个例子。我们可以做blurry refractions(模糊反射)。
不透明的物体及天空盒都渲染之后,我们把当前图像复制到一个临时渲染目标上,使其模糊化,然后再设定全局shader属性。玻璃对象上的shader随后以模糊图像作为样本,基于法线贴图的UV坐标偏移量来进行模拟反射。这与shader GrabPass does完成的操作类似,除非你能做出更多初始化的操作(在这种情况下是模糊化)。
另一个用例:custom deferred lights(自定义延迟光照)。下面的图片是球形灯光效果和试管形状的灯光效果:
常规延迟shading光照完成后,每个自定义光照都绘制出一个带有shader的球形,计算光照并添加它到光照缓冲区内。
我们的想法是:在G-buffer完成之后,为每个贴花纸(盒子)“形状”的东西做绘制,并修改G-buffer的内容。这与光照如何在延迟shading中的操作如出一辙。除了去叠加光照,我们取而代之的是修改G-buffer的纹理。
每一个贴花纸在此作为一个盒子来实现的,并影响着盒子内部的任意几何体。
实际上,这里有一个小的Unity (5.0 beta 22)项目文件夹,它演示了一切内容:(请看链接:)http://docs.unity3d.com/500/Documentation/ScriptReference/Rendering.Came...。
你能看到所有这些案例实现起来并不复杂——脚本只有区区几百行。