安静如鸡

  • Home
  • About Me
  • Contact Me
  • 东京女子篮球活动记录
一个博客
  1. 首页
  2. Tech
  3. 正文

【Unity小贴士】Motion Vector

2024-07-08 0人点赞 0条评论

前提:用户说实现了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

  1. Shader的SubShader区块里需要包涵MotionVectors pass
  2. Mesh需要满足下面任意一个条件
    • SkinnedMeshRenderer.
    • MeshRenderer, 并且 Motion Vectors 没有设置为 Camera Motion Only.
    • 用下面几个API的时候: Graphics.RenderMesh, Graphics.RenderMeshInstanced 或者 Graphics.RenderMeshIndirect, RenderParams的MotionVectorMode属性没有被设置成Camera.
  3. 下面任意一个条件为真
    • MeshRenderer上的 MotionVectorGenerationMode 属性被设置成ForceNoMotion 或者Grphics.Render等API的RenderParams.MotionVectorMode 结构成员被设置成ForceNoMotion 。注意:ForceNoMotion 选项要求每帧渲染每个对象的运动矢量通道,以便相机运动矢量对于此类对象可以用零覆盖。
    • 材质上的 MotionVectors pass已经被启用
    • 如果材质上的 MotionVectors pass 没有启用,但前一帧和当前帧的模型矩阵不匹配,或者对象是否具有骨骼动画。静止的渲染并且没有骨骼动画的时候即使shader含有MotionVerctorPass但没有在材质里启用的话也不会被渲染。

关于内置的shader和shader graph的设置:

  1. 关于内置的shader,必须在材质上check Alembic Motion Vectors。
  2. 关于内置的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。

我真的服了

参考:https://www.sardinefish.com/blog/458

标签: 暂无
最后更新:2024-07-28

Ellison

什么都懂点,什么都不精。属于混吃等死,享受生活,过一天算一天的享乐主义。喜欢电影,阅读,以及游戏和美食。

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2024 安静如鸡. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang