Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Feature Request [URP 14+] Custom Motion Vectors Injection Point

Discussion in 'Universal Render Pipeline' started by wwWwwwW1, Feb 14, 2023.

  1. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    761
    I tried setting the RenderPassEvent to BeforeRenderingPostProcessing. But the motion vectors texture will be cleared before executing URP's motion vectors pass.
    URP_MotionVectors.jpg

    If I set the RenderPassEvent of my custom pass to after post-processing, it will be executed after TAA.

    Will there be injection points like "Before TAA"?
     
  2. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    761
  3. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    761
    Bump, this is not a problem in Built-in or HDRP.
     
  4. OccaSoftware

    OccaSoftware

    Joined:
    May 24, 2019
    Posts:
    29
    +1, I am also experiencing this issue.
    When requesting the Motion Vector Texture in a Renderer Feature, I expect Unity URP to generate and provide a current and accurate Motion Vector Texture for that feature. URP is not doing this. Instead, URP queues the Motion Vector pass in the normal pipeline sequence during the PostProcessing passes. As a result, the Motion Vectors are always one frame out of date. In addition, these Motion Vectors work inconsistently when using multiple cameras. For example, Camera 2 will pick up the Motion Vectors from Camera 1 in the same frame. Then, Camera 1 picks up the Motion Vectors from Camera 2 from the previous frame.
     
  5. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    267
    How are you requesting the texture? Are you using ConfigureInput (flags) on your current pass to set what buffers you require in time for the execution of that pass?
     
  6. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    761
    My current solution is to enqueue the custom pass in
    AfterRenderingPostProcessing
    . The limitation is that it can't work well with "distortion" effects (DoF, motion blur, ...).

    I don't understand why doesn't URP choose to render motion vectors earlier.

    Reminder:

    In 2023.2 (and above), it seems that there's a bug with these injection points.

    The
    AfterRenderingPostProcessing
    should be changed to
    AfterRenderingPostProcessing - 1
    if FXAA is enabled (scene view won't enable FXAA), or your custom pass will be applied after scene rendering and won't be displayed on screen.
     
  7. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    267
    More specifically, have you added
    Code (csharp):
    1. yourPass.ConfigureInput(ConfigureScriptableRenderPassInput.Motion)
    in your scriptable render features AddRenderPasses function?
     
  8. OccaSoftware

    OccaSoftware

    Joined:
    May 24, 2019
    Posts:
    29
    Yes.
    Here's a complete example of a Feature + Pass with pass.ConfigureInput(...) from AddRenderPasses.
    This is in 2022.3.0f1.
    The pass ("Motion Vectors Test") executes before the Motion Vector texture is created ("MotionVectors").

    Are you having a different experience?

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.Profiling;
    4. using UnityEngine.Rendering;
    5. using UnityEngine.Rendering.Universal;
    6. public class MotionVectorTexture : ScriptableRendererFeature
    7. {
    8.     class CustomRenderPass : ScriptableRenderPass
    9.     {
    10.         // This method is called before executing the render pass.
    11.         // It can be used to configure render targets and their clear state. Also to create temporary render target textures.
    12.         // When empty this render pass will render to the active camera render target.
    13.         // You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
    14.         // The render pipeline will ensure target setup and clearing happens in a performant manner.
    15.         public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { }
    16.         // Here you can implement the rendering logic.
    17.         // Use <c>ScriptableRenderContext</c> to issue drawing commands or execute command buffers
    18.         // https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html
    19.         // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline.
    20.         public override void Execute(
    21.             ScriptableRenderContext context,
    22.             ref RenderingData renderingData
    23.         )
    24.         {
    25.             Profiler.BeginSample("Motion Vector Test");
    26.             CommandBuffer cmd = CommandBufferPool.Get("Motion Vector Test");
    27.             Blitter.BlitCameraTexture(
    28.                 cmd,
    29.                 renderingData.cameraData.renderer.cameraColorTargetHandle,
    30.                 renderingData.cameraData.renderer.cameraColorTargetHandle
    31.             );
    32.             context.ExecuteCommandBuffer(cmd);
    33.             cmd.Clear();
    34.             CommandBufferPool.Release(cmd);
    35.             Profiler.EndSample();
    36.         }
    37.         // Cleanup any allocated resources that were created during the execution of this render pass.
    38.         public override void OnCameraCleanup(CommandBuffer cmd) { }
    39.     }
    40.     CustomRenderPass m_ScriptablePass;
    41.     /// <inheritdoc/>
    42.     public override void Create()
    43.     {
    44.         m_ScriptablePass = new CustomRenderPass();
    45.         // Configures where the render pass should be injected.
    46.         m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
    47.     }
    48.     // Here you can inject one or multiple render passes in the renderer.
    49.     // This method is called when setting up the renderer once per-camera.
    50.     public override void AddRenderPasses(
    51.         ScriptableRenderer renderer,
    52.         ref RenderingData renderingData
    53.     )
    54.     {
    55.         renderer.EnqueuePass(m_ScriptablePass);
    56.         m_ScriptablePass.ConfigureInput(
    57.             ScriptableRenderPassInput.Motion | ScriptableRenderPassInput.Depth
    58.         );
    59.     }
    60. }
    61.  
     

    Attached Files: