Strange issue with two CopyDepthPasses in one pipeline

I’m having a strange issue with my scene depth. My URP pipeline looks like this:

  • render objects (a custom terrain mesh) [opaque, WRITES depth]
  • XXX
  • render objects (blob shadows, cube meshes intersecting the terrain) [transparent, SAMPLES depth]
  • render objects (trees and plants as sprites on quads) [opaque, WRITES depth]
  • XXX
  • render objects (a fog effect, as a plane above the terrain) [transparent, SAMPLES depth]

Because this rendering happens in a stacked overlay camera, I need to manually copy over the depth before I can sample it. This happens at the “XXX” above, so twice.

For copying the depth buffer to where ShaderGraph can sample it (the “Scene Depth” node) I’m using a custom ScriptableRenderFeature (posted below).

The strange thing is, that when zooming (thus changing depth) the depth starts ‘lagging’ like in this GIF:

7022167--831577--scene_depth_issue.gif

What’s strange is that this is an effect over multiple frames. To me it looks like some value being relative instead of being absolute, stabilizing only over multiple frames. Or perhaps some other system interfering?

The crux is, that this ONLY happens when I have TWO passes that copy depth. With either one of the depth copies disabled, things work as expected (yet, either the blob shadow or the fog has no depth info).

I’m puzzled and hopefully someone can help me.

This is my ScriptableRenderFeature:

using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.Universal.Internal;
public class CopyDepthRenderFeature : ScriptableRendererFeature
{
    CopyDepthPass _pass;
    RenderTargetHandle _depthDestHandle;
    RenderTargetHandle _depthSourceHandle;
    public RenderPassEvent renderPassEvent;
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        _pass.Setup(_depthSourceHandle, _depthDestHandle);
        renderer.EnqueuePass(_pass);
    }
    public override void Create()
    {
        if (_pass != null)
        {
            _pass = null;
        }
        if (_pass == null)
        {
            _pass = new CopyDepthPass(renderPassEvent, CoreUtils.CreateEngineMaterial("Hidden/Universal Render Pipeline/CopyDepth"));
            _depthDestHandle = new RenderTargetHandle();
            _depthSourceHandle = new RenderTargetHandle();
            _depthSourceHandle.Init("_CameraDepthAttachment");
            _depthDestHandle.Init("_CameraDepthTexture");
        }
    }
}

I’m using 2020.2.4 but I’ve verified that this also happens in 2020.3.3 LTS.

I’ve tried to isolate the issue and have found out that it doesn’t matter whether the camera is an overlay camera or not. There seems to be a delay when sampling the depth buffer.

I have set up a more in-depth test case here, but my issue remains: