监视器
高动态范围渲染

编写后期处理效果

后期处理是一种在 Unity 中将效果应用于渲染图像的方法。

任何使用 OnRenderImage 函数的 Unity 脚本都可以用作后期处理效果。必须将其添加到摄像机游戏对象才能使脚本执行后期处理。

OnRenderImage 函数

OnRenderImage Unity Scripting API 函数接受两个参数:

  • 作为 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) 这样基于深度的效果经常使用这种方式。

为此,请在 OnRenderImage Unity Scripting API 函数中添加 ImageEffectOpaque 属性。

不同平台上的纹理坐标

如果后期处理效果一次采样多个不同的屏幕相关纹理,您可能需要了解不同平台如何使用纹理坐标。一种常见的情况是效果“源”纹理和摄像机的深度纹理需要不同的垂直坐标,具体取决于抗锯齿设置。有关更多信息,请参阅 Unity 用户手册平台差异页面。

相关主题


  • 2017–05–24 页面已发布但未经编辑审查

  • 5.6 中的新功能

监视器
高动态范围渲染