Search Unity

Question Raytraced Ambient Occlusion ghosting

Discussion in 'High Definition Render Pipeline' started by shmomo, May 19, 2023.

  1. shmomo

    shmomo

    Joined:
    Oct 11, 2011
    Posts:
    127
    When Im switching meshes on and off to show/hide new characters (like a character select screen), the Raytraced Ambient Occlusion is causing a kind of ghosting / morph effect.

    Is there a setting that will reduce of fix this ghosting / morphing of AA?

    The export is for high resolution stills / movs so I'm not concerned with high frame rate at all, I cant increase quality on anything if that helps.

    Thanks

    Desktop 19-05-2023 13-09-01_1 (1).gif
     
    Last edited: May 19, 2023
  2. chap-unity

    chap-unity

    Unity Technologies

    Joined:
    Nov 4, 2019
    Posts:
    766
    Hey, RTAO denoiser rely on accumulation to be able to have a nice result at a fraction of the cost, meaning the RTAO result of a specific frame depends on the previous frames as well.
    So when you are switching meshes, RTAO still uses the result of the previous meshes and take a few frames to converge to the correct result with this new mesh.
    What needs to be done is basically telling HDRP to discard the history when that happens, there's no API or simple way to do that but one thing you can do is when switching meshes, you can disable the denoiser, and then re-enable it on the next frame, that way, history will be discarded. you will get a "snap", but you won't see any ghosting in theory.
    Here's a snippet of how that could work:

    Code (CSharp):
    1.  
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.HighDefinition;
    4. public class ToggleObject : MonoBehaviour
    5. {
    6.     public Volume m_Volume;
    7.  
    8.     // Update is called once per frame
    9.     void Update()
    10.     {
    11.         VolumeProfile profile = m_Volume.sharedProfile;
    12.         if (!profile.TryGet<ScreenSpaceAmbientOcclusion>(out var ssao))
    13.         {
    14.             ssao = profile.Add<ScreenSpaceAmbientOcclusion>(false);
    15.         }
    16.    
    17.         // Re-enable AO denoiser if set to false
    18.         if(!ssao.denoise) ssao.denoise = true;
    19.    
    20.         // Toggling between meshes
    21.         if(Input.GetKeyDown(KeyCode.T))
    22.         {
    23.             ssao.denoise = false;
    24.         }
    25.     }
    26. }
    27.  
    Hope that helps!
     
    shmomo and Onigiri like this.
  3. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    5,060
    Will this be added in the future? It seems fairly important for many games that you can switch meshes without much ghosting
     
  4. chap-unity

    chap-unity

    Unity Technologies

    Joined:
    Nov 4, 2019
    Posts:
    766
    Clearly not a priority right now, but that's not out of the question.
    There's already some mechanism to discard history automatically when the occluder or the receiver of AO is moving too fast (to avoid having too much ghosting) !

    Also, I just realized there's already functions on the HDCamera class to enable / disable accumulation but they are currently not public API, they are internal to HDRP (could still be accesible via an ASMDEF wrapper), but that mean just setting those function to public would make it even easier for users to disable accumulation (on any effect) when needed, like this:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. using UnityEngine.Rendering;
    6. using UnityEngine.Rendering.HighDefinition;
    7.  
    8. public class ToggleObject : MonoBehaviour
    9. {
    10.     public Camera camera;
    11.     HDCamera hdCamera;
    12.     // public Volume m_Volume;
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         hdcamera = HDCamera.GetOrCreate(camera);
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update()
    21.     {
    22.  
    23.         // Re-enable accumulation on camera if set to false
    24.         if(!hdCamera.ActiveRayTracingAccumulation()) hdCamera.SetRayTracingAccumulation(true);
    25.      
    26.         // Toggling between meshes
    27.         if(Input.GetKeyDown(KeyCode.T))
    28.         {
    29.             hdCamera.SetRayTracingAccumulation(false);
    30.         }
    31.     }
    32. }
    33.  
    I'll see what can be done, thanks for the post !
     
    Onigiri likes this.
  5. shmomo

    shmomo

    Joined:
    Oct 11, 2011
    Posts:
    127
    Thanks for the reply.

    If I generate the new mesh off screen and animated the new mesh to move in from the side and move the old one off to the other side, would that solve the ghosting as a workaround?
     
  6. jjejj87

    jjejj87

    Joined:
    Feb 2, 2013
    Posts:
    1,117
    It would be less noticeable, I think, depending on how you animate it. I think, if you are open to the idea of transition to mitigate temporal effects, rather add animations to the character it self.

    For example, if the character did a quick turn around or settling down animation or even some VFX to take the focus away, then it would be less noticeable. Or a little "boing" type of scale animation.