Writing to depth using Compute shader for Checkerboard Rendering

I’m currently trying to implement checkerboard rendering in URP to speed up performance,
I’d reckon drawing the checkerboard pattern using compute shader would be faster since I won’t have to evoke the full graphics pipeline, and could avoid fragment shader branches. I can dispatch the compute shader and get the checkerboard pattern correctly (checked using renderdoc), but I have trouble blitting the resulting texture to the camera’s depth texture (which I access from ScriptableRenderer.cameraDepthTarget)

I do feel like I’m doing something hacky but I can’t seem to find the camera depth target Render target identifier in a ScriptableRenderPass’ Execute function, what I’m doing is:

// Checkerboard Pass
private ScriptableRenderer _renderer;
private ComputeShader _checkerboardShader;
private int _kernelFillIndex = 0;

public void SetScriptableRenderer(ScriptableRenderer renderer)
{
    _renderer = renderer;
}

public CheckerboardPass()
{
   ...
   renderPassEvent = RenderPassEvent.BeforeRenderingOpaques;
   ...
}

public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
    ...
    CommandBuffer cmd = CommandBufferPool.Get();
    cmd.SetComputeTextureParam(_checkerboardShader, _kernelIndex, "DepthBuffer", _renderTexture);
    cmd.DispatchCompute(_checkerboardShader, _kernelIndex, Mathf.CeilToInt(width / 8.0f), Mathf.CeilToInt(height / 8.0f), 1);
    cmd.Blit(_renderTexture, _renderer.cameraDepthTarget);
    context.ExecuteCommandBuffer(cmd);
    CommandBufferPool.Release(cmd);
    ...
}
// Checkerboard Render Feature
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
    _checkerboardPass.SetScriptableRenderer(renderer);
    renderer.EnqueuePass(_checkerboardPass);
}
// Checkerboard Shader
RWTexture2D<half> DepthBuffer;
[numthreads(8, 8, 1)]
void ComputePass(uint3 id : SV_DispatchThreadID)
{
    uint2 scaledID = id.xy / 2;
    DepthBuffer[id.xy] = (scaledID.x + scaledID.y) % 2;
}

This doesn’t work and I’m having trouble finding out why.
Is what I’m trying to do possible?

I’m using Unity 2021.1.15f1; URP11, Thanks!

samilar problem, there is no doc about how to write to the z buffer, the cameraColorTarget works well, but cameraDepthTarget seems doesn’t work.

A tiny progress update: Blitting to a RenderTargetHandle Initialized to “_CameraDepthAttachment” or “_CameraDepthTexture” doesn’t work either (actually produces the same result as the code I posted previously), and binding a new depth buffer using ConfigureTarget doesn’t seem to do anything… or are you not supposed to call ConfigureTarget on Execute?

Well, I’m running out of ideas on ways to write to depth using Compute shader.

Well, I gave up trying to do it using Compute shader. I ended up just writing the to the depth buffer using a Fullscreen Triangle rendered using a fragment shader that writes to SV_Depth. Since if I were to use a Compute shader, I would need a Blit operation anyway (Blitting seems to be done by invoking the full Graphics pipeline), I figured swapping a blit for a full screen render is an acceptable tradeoff. Though the shader would be slowed somewhat by me writing to the fragment depth. (no early Z)

Sidenote, I found out that URP has a “Copy Depth” internal pass, (Class CopyDepthPass | Universal RP | 11.0.0) but it also seems to use the full graphics pipeline so it’s still not exactly what I am looking for. Leaving a note here just in case someone have a similar problem.

1 Like