URP 使用运动矢量渲染通道计算表面片元的帧到帧屏幕空间移动。URP 将运动数据存储在全屏纹理中,存储的每像素值称为运动矢量。
仅在帧中存在活动的功能且渲染通道请求运动矢量渲染通道时,Unity 才运行运动矢量渲染通道。例如,以下 URP 功能会请求运动矢量通道:时间抗锯齿和运动模糊。有关如何在自定义通道中请求运动矢量通道的信息,请参阅在通道中使用运动矢量纹理部分。
如果运动矢量不正确或缺失,可能导致依赖它们的效果出现视觉瑕疵。请按照本页面上的说明进行操作,确保对象渲染器、材质和着色器已正确设置以支持运动矢量。
URP 仅支持不透明材质(包括 Alpha 裁剪材质)的运动矢量。URP 不支持透明材质的运行矢量。
本节介绍 URP 如何实现运动矢量。
运动矢量是 2D 矢量,表示自上一帧以来表面片元相对于摄像机的运动,投影到摄像机近裁剪面上。运动矢量纹理使用 2 个通道(R 和 G)。每个纹素存储每个可见表面片元的 UV 偏移。如果从给定纹素的当前 UV 坐标中减去该纹素的运动矢量,您将获得该纹理像素上一帧在屏幕上的位置的 UV 坐标。计算的最后一帧 UV 坐标可以在屏幕边界之外。
运动矢量分为两类:
摄像机运动矢量:仅由摄像机自身运动引起的运动矢量。
对象运动矢量:由摄像机运动和片元所属对象的世界空间运动组合引起的运动矢量。
仅靠给定运动矢量纹理无法推断片元在屏幕上的运动是仅由摄像机运动、对象运动还是两者的组合所致。
单个全屏通道足以计算摄像机运动矢量。此类通道具有独立于场景复杂性的固定每帧计算负载。只需知道屏幕上所有像素的当前 3D 位置以及摄像机的移动方式,这些可从深度缓冲区以及当前帧和先前帧的摄像机矩阵推断出来。
对象运动矢量具有计算负载,这取决于场景中移动对象的数量和复杂性,因为需要为每个对象绘制一个图形来考虑每个对象的运动。每次绘制也需要应用摄像机的运动贡献。
当满足以下三个条件时,Unity 会为帧中的网格渲染对象运动矢量:
与网格关联的着色器在激活的子着色器代码块中具有 MotionVectors 通道。
网格正在通过以下任何渲染器进行渲染:
SkinnedMeshRenderer。
当运动矢量 (Motion Vectors) 属性未设置为 Camera Motion Only 时,为 MeshRenderer。
使用以下 API:Graphics.RenderMesh、Graphics.RenderMeshInstanced 或 Graphics.RenderMeshIndirect,RenderParams 结构的 MotionVectorMode 成员未设置为 Camera。
如果以下任何条件为 true:
MotionVectorGenerationMode 属性在 MeshRenderer 或 Grphics.Render... API 的 RenderParams.MotionVectorMode 结构成员上设置为 ForceNoMotion。
注意:ForceNoMotion 选项要求每帧渲染一个每对象运动矢量通道,以便此类对象的摄像机运动矢量可以用零覆盖。
在材质上启用 MotionVectors 通道(例如,当材质在 Shader Graph 中具有顶点动画或 Alembic 动画时)。
在材质上禁用 MotionVectors 通道,但前一帧和当前帧的模型矩阵不匹配,或者对象具有骨骼动画。如果着色器具有 MotionVectors 通道但在材质上禁用了该通道,则没有骨骼动画的固定渲染器不会使用对象运动矢量通道进行渲染。
为预构建的着色器启用 MotionVectors 通道时,Unity 会为网格渲染器渲染对象运动矢量,即使它们不移动。
当以下条件为 true 时,Unity 会在预构建的 URP 着色器中启用 MotionVectors 通道:
URP__ ShaderLab__Unity 用于定义着色器对象结构的语言。更多信息
See in Glossary 着色器:在材质上,在高级选项 (Advanced Options) 部分中启用了 Alembic 运动矢量 (Alembic Motion Vectors) 属性。
URP 光照和无光照 Shader Graph 着色器:在图表检视面板 (Graph Inspector) 中,设置以下任何属性: