目录 |
1 后处理栈(Post-Processing Stack) 1.1 Asset 1.2 默认栈 1.3 渲染栈 2 渲染目标 2.1 渲染到纹理 2.2 Blitting 2.3 隔离深度纹理 3 全屏三角形 3.1 Mesh 3.2 着色 3.3 绘制 3.4 可变源纹理 4 模糊 4.1 着色器 4.2 过滤(Filtering) 4.3 模糊两次 4.4 可配置模糊 5 使用深度缓存 5.1 深度条纹 5.2 混合深度和颜色 5.3 跳过天空盒 5.4 仅不透明的后处理 5.5 可选条纹 6 逐相机后处理 6.1 相机配置 6.2 场景摄像机 |
本文重点:
创建后处理栈资产
使用渲染纹理(render textures)
绘制全屏三角形
应用多步模糊效果和基于深度的条纹。
逐相机配置栈
这是涵盖Unity的可脚本化渲染管道的教程系列的第11部分。它涵盖了后处理堆栈的创建。
本教程是CatLikeCoding系列的一部分,原文地址见文章底部。“原创”标识意为原创翻译而非原创教程。
本教程使用Unity 2018.4.4f1制作。
(弄乱图像)
1 后处理栈(Post-Processing Stack)
除了渲染构成场景一部分的几何图形之外,还可以随后更改生成的图像。这用于应用全屏效果,例如环境光遮挡,光晕,颜色渐变和景深。通常,多个后处理步骤按特定顺序应用,该顺序是通过一个或多个资产或组件配置的,共同形成一个后处理堆栈。Unity具有此类堆栈的多种实现。
在本教程中,我们将创建一个自己的简单后处理堆栈,并具有两个效果以供实际使用。你可以扩展它以支持更有用的效果,或者更改方法,以便可以连接到现有解决方案。
1.1 Asset
我们将引入MyPostProcessingStack资产类型来控制后处理。给它一个公共的Render方法,并带有一个CommandBuffer参数,它可以用来执行其工作。这个想法是堆栈将用命令填充缓冲区,但是执行和清除缓冲区是管道的责任。最初,只需记录调用堆栈的方法即可。
为我们的堆栈创建资产。它还没有任何配置选项,但是我们稍后再添加。
1.2 默认栈
要使用堆栈,MyPipeline需要对其进行引用。给它一个字段来跟踪默认堆栈,该堆栈是通过其构造函数设置的。
也给MyPipelineAsset一个默认堆栈的配置选项,以便它可以将其传递给管道实例。
将我们的单个堆栈资产设置为默认值。
(分配默认的栈)
1.3 渲染栈
要隔离堆栈的渲染,请向MyPipeline添加专用于后处理效果的命令缓冲区。如果存在默认堆栈,请使用缓冲区渲染它,然后执行并清除缓冲区。后处理发生在常规渲染完成后,因此在Render中调用DrawDefaultPipeline之后。
此时,堆栈应该能记录到每帧渲染时都会被调用。
2 渲染目标
要更改渲染的图像,我们必须先读取它。使之成为可能的最简单,最可靠的方法是将管道渲染为纹理。到现在为止,我们一直渲染到摄影机的目标是帧缓冲区。但也可以是渲染纹理,例如在渲染反射探针的面的时候。选中后,Unity还会始终为场景窗口及其小型相机预览渲染纹理。
2.1 渲染到纹理
在清除渲染目标之前,如果有堆栈,我们必须获取临时渲染纹理。这次,我们将使用CommandBuffer.GetTemporaryRT通过摄影机缓冲区安排纹理的获取。这种方法要求我们提供着色器属性ID,以及纹理的宽度和高度,应与相机的像素尺寸匹配。我们使用_CameraColorTexture作为着色器属性名称。
这将使我们的纹理绑定到提供的ID上。接下来,我们需要使其成为渲染目标。这是通过以ID为参数调用相机缓冲区上的SetRenderTarget来完成的。该ID有一个RenderTargetIdentifier,但假定它是着色器属性ID,则从int隐式转换为该类型。另外,我们可以指定加载和存储操作。假设我们正在使用单个相机,因此不必担心纹理的初始状态,因为接下来我们将对其进行清除。
如果需要,我们必须在后处理之后释放渲染纹理。这是通过在具有相同ID的相机缓冲区上调用ReleaseTemporaryRT来完成的。严格来说这不是必须的,因为一旦相机完成渲染,缓冲区所声明的纹理应自动释放,但是最好尽快进行明确清理。
我们可以缓存RenderTargetIdentifier以便重用吗?
是的,这样转换仅发生一次,因此效率更高。但是,在本教程中我不使用。
2.2 Blitting
此时,我们的场景似乎不再被渲染,因为我们正在渲染到纹理而不是相机的目标。为了解决这个问题,使用MyPostProcessingStack.Render将纹理的内容复制到最终目标。可以通过使用源ID和目标ID作为参数在缓冲区上调用Blit来实现。为此,添加相机纹理的颜色ID作为参数,并使用BuiltinRenderTextureType.CameraTarget作为目标,该目标