Search Unity

Custom Motion Blur struggle with ScriptableRendererFeature

Discussion in 'Universal Render Pipeline' started by MadreDeDios, Nov 12, 2019.

  1. MadreDeDios

    MadreDeDios

    Joined:
    Apr 24, 2017
    Posts:
    9
    Hi all,

    The motion blur currently builtin the URP seems to be based on the camera motion.
    In my current project, my camera will stay static, therefore cannot benefit from the motion blur.

    Here is a screenshot of a successful attempt unfortunately working only in editor scene view:
    Screenshot 2019-11-12 at 11.14.05.png

    It seems like creating custom PP effects with URP is still not a thing. (omg why.......)
    So I want to do it with a custom renderer feature.
    My content itself is not animated, but as a whole, moves around. So I'm happy to do a simple blit of the current frame a few times with an offset + blur, as a solution (meaning I don't need to save the last (few) frame(s)).

    My issue seems to be choosing the source and destination of my Blit. I just can't seem to find the one that works in editor, scene view and game view as well as in a build.

    I tried
    Code (CSharp):
    1. cmd.Blit(BuiltinRenderTextureType.CameraTarget, BuiltinRenderTextureType.CameraTarget, material);
    2. cmd.Blit(RenderTargetHandle.CameraTarget.Identifier(), RenderTargetHandle.CameraTarget.Identifier(), material);
    And a lot of other options, but none seem to be working for me...

    I am attaching my file with most of the solutions I tested. Including my offset+blur shader if you have any comment on that.

    I have one remaining trail I'm unable to bring to a close, and I believe it could be related.
    If I change my event from
    Code (CSharp):
    1. RenderPassEvent.AfterRenderingPostProcessing
    2. to
    3. RenderPassEvent.BeforeRenderingPostProcessing
    which I would like to do, to benefit from things like anti-aliasing, my custom render pass no longer has any effect whatsoever...
    Could it be because the PostProcessingPass implemented by the ForwardRenderer takes as a source the exact texture I need, and therefore my pass gets overridden?

    Feel free to give any piece of advice even if you're not sure, I'm also trying to learn and I'm happy to test your stuff and let you know if it worked for me.

    Thanks for your help!
     

    Attached Files:

    Last edited: Nov 12, 2019
    olli_vrcoaster likes this.
  2. laurienash

    laurienash

    Joined:
    Mar 15, 2013
    Posts:
    61
    Hiya, I'm looking to do the same thing - did you ever resolve this?
     
  3. MadreDeDios

    MadreDeDios

    Joined:
    Apr 24, 2017
    Posts:
    9
    I did end up making a working motion blur that's not based on the camera! Though it is extremely specific to my project. Though maybe my solution may help you come up with your own:

    First, I render the layers I'm interested in, then I copy the camera texture (custom grab pass, as I want transparents too).

    Second, I have a pass that applies the motion blur on the whole camera texture (not the one grabbed).
    Main difference from my code above is that I no longer blit the CameraTarget onto itself with my blur material, instead I use a temporary texture, and 2 blits:

    Code (CSharp):
    1.  
    2. // NOT that
    3. cmd.Blit(BuiltinRenderTextureType.CameraTarget, BuiltinRenderTextureType.CameraTarget, material);
    4.  
    5. // That instead
    6. cmd.Blit(source, temporary, motionBlur);
    7. cmd.Blit(temporary, source);
    8.  
    Seems to work much better. But now the whole screen is blurred.

    So finally I have yet another pass that applies the earlier grab pass onto the camera target. My camera clear colour is fully black transparent, so my blur is not fully overridden by this pass.

    I'd be curious to know what you end up doing if you want to share in this thread too, it might help more people in the future! Good luck
     
  4. oleg_v

    oleg_v

    Joined:
    Nov 10, 2017
    Posts:
    68
    SRP is still like a magic =) So i leave a note about source solution bugs:
    1. Blit is allowed only between different textures, not the same
    2. Active Blit source can be differ from RenderTargetHandle.CameraTarget.Identifier. I used ScriptableRenderer.cameraColorTarget from ScriptableRendererFeature.AddRenderPasses
    Pass with simple blit and pass with DrawRenderers: https://gist.github.com/Refsa/54da34a9e2fc8e45472286572216ad17

    Else one note - it's better to check whether source == target or not. If so, it's required to cmd.GetTemporaryRT, double Blit and release tmp RT.