前提:用户说实现了motion vector之后framedebugger里没有显示出pass。只有用SkinnedMeshRenderer或者MeshRenderer设置成ForceNoMotion
才有pass
URP16里面对Motion Vector如何实现进行了详细的介绍,参见:
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@16.0/manual/features/motion-vectors.html
对于物体,如果要使用这个功能需要达到下面的条件:
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@16.0/manual/features/motion-vectors.html#cases-when-motion-vectors
- Shader的SubShader区块里需要包涵MotionVectors pass
- Mesh需要满足下面任意一个条件
- SkinnedMeshRenderer.
- MeshRenderer, 并且 Motion Vectors 没有设置为
Camera Motion Only
. - 用下面几个API的时候: Graphics.RenderMesh, Graphics.RenderMeshInstanced 或者 Graphics.RenderMeshIndirect,
RenderParams
的MotionVectorMode
属性没有被设置成Camera
.
- 下面任意一个条件为真
MeshRenderer
上的MotionVectorGenerationMode
属性被设置成ForceNoMotion
或者Grphics.Render
等API的RenderParams.MotionVectorMode
结构成员被设置成ForceNoMotion
。注意:ForceNoMotion 选项要求每帧渲染每个对象的运动矢量通道,以便相机运动矢量对于此类对象可以用零覆盖。- 材质上的 MotionVectors pass已经被启用
- 如果材质上的 MotionVectors pass 没有启用,但前一帧和当前帧的模型矩阵不匹配,或者对象是否具有骨骼动画。静止的渲染并且没有骨骼动画的时候即使shader含有MotionVerctorPass但没有在材质里启用的话也不会被渲染。
关于内置的shader和shader graph的设置:
- 关于内置的shader,必须在材质上check Alembic Motion Vectors。
- 关于内置的Shader Graph的话必须在Graph的界面里
- 启用Alembic Motion Vectors
- Additional Motion Vectors 属性设置成 TimeBased 或者 Custom.
上面条件满足后就只需要加一个FeaturePass了:
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@16.0/manual/renderer-features/custom-rendering-pass-workflow-in-urp.html
首先需要添加一个Render pass 然后在这个pass里面利用ScriptableRenderPass.ConfigureInput(ScriptableRenderPassInput.Motion);来设置MotionVection模式。
public class ObjectMotionBlurFeature : ScriptableRendererFeature
{
class CustomRenderPass : ScriptableRenderPass
{
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
}
public override void OnCameraCleanup(CommandBuffer cmd)
{
}
}
CustomRenderPass m_ScriptablePass;
public override void Create()
{
m_ScriptablePass = new CustomRenderPass();
m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
m_ScriptablePass.ConfigureInput(ScriptableRenderPassInput.Motion);
renderer.EnqueuePass(m_ScriptablePass);
}
}
C#最后在当前的pipeline asset下面加上上面写好的的Pass就可以了。
按照文档一套设置下来没什么问题
用自己写的shader一定要有MotionVector这个Tag
Tags { "LightMode" = "MotionVectors" }
可以参照官方的Lit.shader
https://github.com/Unity-Technologies/Graphics/blob/master/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader#L480
用内置的shader建立新的material,再check上这个选项后一切正常,用户应该是shader没设置好。
更新:
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@16.0/manual/features/motion-vectors.html#motion-vectors-in-shaderlab
根据Document,2023.2以前应该是会有一个自动的fallback material,可以渲染Motion Vector。就算什么都不设置,应该也会渲染Object Per Motion。但用Framedebugger却一直没有发现这个pass被渲染。查了半天,发现是Frame Debugger的问题,因为frame debugger 在cache的时候会暂停Unity Editor,导致MotionVector的pass消失,换成RenderDoc就会有这个Pass。
我真的服了
文章评论