后期处理是一种在 Unity 中将效果应用于渲染图像的方法。
Any Unity script that uses the OnRenderImage function can act as a post-processing effect. Add it to a Camera GameObject for the script to perform post-processing.
The OnRenderImage Unity Scripting API function receives two arguments:
作为 RenderTexture 的源图像
应该渲染到的目标(也是 RenderTexture)。
后期处理效果通常使用着色器。这些着色器将读取源图像,对其进行一些计算,并将结果渲染到目标中(例如,使用 Graphics.Blit)。后期处理效果将完全替代目标的所有像素。
摄像机可以有多个后期处理效果,每个效果都作为组件。Unity 按照这些效果在 Inspector 中列出的顺序以堆栈形式执行它们;位于 Inspector 顶部的后期处理组件先渲染。在这种情况下,第一个后期处理组件的结果作为“源图像”传递给下一个后期处理组件。在内部,Unity 会创建一个或多个临时渲染纹理以保存这些中间结果。
请注意,后期处理栈中的后期处理组件列表未指定它们的应用顺序。
注意事项:
目标渲染纹理可以是 null,这意味着“渲染到屏幕”(即后缓冲区)。摄像机上的最后一个后期处理效果将发生此情况。
OnRenderImage
完成后,Unity 期望目标渲染纹理是激活的渲染目标。通常情况下,Graphics.Blit 或手动渲染到目标纹理应该是最后的渲染操作。
在后期处理效果着色器中关闭深度缓冲区写入和测试。这样可确保 Graphics.Blit 不会将非预期值写入目标 Z 缓冲区。几乎所有后期处理着色器 pass 都应包含 Cull Off ZWrite Off ZTest Always
状态。
要使用原始场景渲染中的模板或深度缓冲区值,请使用 Graphics.SetRenderTarget 将原始场景渲染中的深度缓冲区显式绑定为深度目标。应传递第一个源图像效果深度缓冲区作为要绑定的深度缓冲区。
默认情况下,Unity 在渲染整个场景后执行后期处理效果。在某些情况下,您可能更希望 Unity 在渲染场景中的所有不透明对象之后但在渲染其他对象之前渲染后期处理效果(例如,在渲染天空盒或透明对象之前)。像景深 (Depth of Field) 这样基于深度的效果经常使用这种方式。
To do this, add an ImageEffectOpaque attribute on the OnRenderImage Unity Scripting API function.
如果后期处理效果一次采样多个不同的屏幕相关纹理,您可能需要了解不同平台如何使用纹理坐标。一种常见的情况是效果“源”纹理和摄像机的深度纹理需要不同的垂直坐标,具体取决于抗锯齿设置。有关更多信息,请参阅 Unity 用户手册平台差异页面。
深度纹理通常用于图像后期处理,以获得屏幕上每个像素距最近不透明表面的距离。
对于 HDR 渲染,ImageEffectTransformsToLDR 属性指示使用色调映射。
还可以使用命令缓冲区来执行后期处理。
使用 RenderTexture.GetTemporary 来获取临时渲染纹理并在后期处理效果中进行计算。
另请参阅 Unity 用户手册的编写着色器程序页面。
2017–05–24 Page published with no editorial review
5.6 中的新功能