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.
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:
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
public class ToggleObject : MonoBehaviour
{
public Volume m_Volume;
// Update is called once per frame
void Update()
{
VolumeProfile profile = m_Volume.sharedProfile;
if (!profile.TryGet<ScreenSpaceAmbientOcclusion>(out var ssao))
{
ssao = profile.Add<ScreenSpaceAmbientOcclusion>(false);
}
// Re-enable AO denoiser if set to false
if(!ssao.denoise) ssao.denoise = true;
// Toggling between meshes
if(Input.GetKeyDown(KeyCode.T))
{
ssao.denoise = false;
}
}
}
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:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
public class ToggleObject : MonoBehaviour
{
public Camera camera;
HDCamera hdCamera;
// public Volume m_Volume;
// Start is called before the first frame update
void Start()
{
hdcamera = HDCamera.GetOrCreate(camera);
}
// Update is called once per frame
void Update()
{
// Re-enable accumulation on camera if set to false
if(!hdCamera.ActiveRayTracingAccumulation()) hdCamera.SetRayTracingAccumulation(true);
// Toggling between meshes
if(Input.GetKeyDown(KeyCode.T))
{
hdCamera.SetRayTracingAccumulation(false);
}
}
}
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?
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.