How to sample Depth Texture from Compute Shader

Hi, pretty straightforward question but I’m struggling to figure it out.

I’m getting the depth texture in hdrp, which is a Texture2dArray, and passing it to a compute shader. I’m trying to figure out how to sample a mipmap of it, but it has a goofy atlas going on.

It looks like the lod0 is at the bottom and takes up 2/3 the height and 100% width. The remaining are all 1/2 by 1/2 of the remaining space aligned to the bottom left, I think.

Anyways, is there a method for this, or does anyone have a good solution for sampling a mip level of it?

Thanks!!!

we globally bind this buffer in HDRPStructuredBuffer<int2> _DepthPyramidMipLevelOffsets; that you should declare at the top of your compute shader

Then you can do something like this:

int2 mipCoord  = coord.xy >> int(lod);
int2 mipOffset = _DepthPyramidMipLevelOffsets[int(lod)];
LOAD_TEXTURE2D_X(_CameraDepthTexture, mipOffset + mipCoord).r;

Thank you so much. I almost had this working just eyeballing the depth texture and guessing different scales and offsets, lol. Glad you were able to teach me the ways of _DepthPyramidMipLevelOffsets!

I did find that LOAD_TEXTURE2D_X was unavailable in my compute shader, but it works find with _CameraDepthTexture.Load

Here’s a full compute shader that copies the depth texture into another texture (just as a sanity check) for anyone trying to do this in the future:

#pragma kernel CSMain

int MipMapLevel;

Texture2DArray<float> _CameraDepthTexture; // HDRP Depth Texture Array
RWTexture2D<float> _OutputTexture;
StructuredBuffer<int2> _DepthPyramidMipLevelOffsets;

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
// Calculate the pixel coordinates in the output texture
int2 pixelCoord = int2(id.xy);

int scale = 1 << MipMapLevel;

int2 mipCoord = pixelCoord.xy >> int(MipMapLevel);
int2 mipOffset = _DepthPyramidMipLevelOffsets[int(MipMapLevel)];

//float depth = LOAD_TEXTURE2D_X(CameraDepthTexture, mipOffset + mipCoord).r;
float depth = _CameraDepthTexture.Load(int4(mipOffset + mipCoord, 0, 0));

// Write the depth value to the output texture
_OutputTexture[pixelCoord] = depth;
}

The LOAD_TEXTURE2D_X macro is simply to ensure your code will work when XR is enabled.

You will need a few modifications though, mainly add these includes at the top of the file

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl"

Change the way you declare the texture.

TEXTURE2D_X_FLOAT(_CameraDepthTexture);

You will also need to dispatch a thread for each eye on the z index in C#, then at the start of CSMain call that to tell which eye is the current

UNITY_XR_ASSIGN_VIEW_INDEX(id.z);
2 Likes