#How to access depth buffers in a compute shader?

1 messages · Page 1 of 1 (latest)

orchid prawn
#

Hello,
I need to count for each vertex from which cameras it is visible.
I have 8 million vertexes and 1000 cameras.

The only possible option is usage of compute shader. It is pretty fast.

Currently I only check if vertex is in camera frustrum. I need to also check if the vertex is visible - if it is not obscured by any mesh part. I thought I could use each camera's depth buffer and check whether the point projected onto the depth buffer is farther away than the depth buffer would indicate.

I can't figure out how to render the depth buffer for each camera and how to pass it (preferably as an array) to the compute shader.

ancient shoal
orchid prawn
ancient shoal
orchid prawn
# ancient shoal Should be, yes. How are you doing it? It needs to be bound as a texture.
   Texture2DArray depthArray = new Texture2DArray(
    virtualCameras[0].pixelWidth,
    virtualCameras[0].pixelHeight,
    cCount,
    TextureFormat.RFloat,
    false
);

        RenderTexture tempRT = new RenderTexture(
            virtualCameras[0].pixelWidth,
            virtualCameras[0].pixelHeight,
            0,
            RenderTextureFormat.RFloat
        );

        for (int i = 0; i < cCount; i++)
        {
            RenderTexture depthRT = GetDepthRT(virtualCameras[i]);
            virtualCameras[i].Render();

            SaveDepthTexture(depthRT, Application.dataPath + "/depth_cam_" + i + ".png");


            // Blit depth -> RFloat
            Graphics.Blit(depthRT, tempRT, depthCopyMat);

            // Copy into array slice
            Graphics.CopyTexture(tempRT, 0, 0, depthArray, i, 0);
        }

        tempRT.Release();

        visibilityCompute.SetTexture(kernel, "_DepthTextures", depthArray);

        visibilityCompute.SetInt("_DepthTexWidth", depthArray.width);
        visibilityCompute.SetInt("_DepthTexHeight", depthArray.height);
 RenderTexture GetDepthRT(Camera cam)
    {
        if (depthRTs.TryGetValue(cam, out var rt))
            return rt;

        rt = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 24, RenderTextureFormat.Depth);
        rt.Create();

        cam.targetTexture = rt;
        cam.depthTextureMode = DepthTextureMode.Depth;

        depthRTs[cam] = rt;
        return rt;
    }

And in shader:

Texture2DArray _DepthTextures;
int _DepthTexWidth;
int _DepthTexHeight;
#
 void SaveDepthTexture(RenderTexture srcRFloat, string path)
    {
        Texture2D tex = new Texture2D(srcRFloat.width, srcRFloat.height, TextureFormat.RFloat, false, true);

        RenderTexture prev = RenderTexture.active; 
        RenderTexture.active = srcRFloat;

        tex.ReadPixels(new Rect(0, 0, srcRFloat.width, srcRFloat.height), 0, 0);
        tex.Apply();

        RenderTexture.active = prev;     

        byte[] bytes = tex.EncodeToPNG();
        System.IO.File.WriteAllBytes(path, bytes);

        Debug.Log("Saved depth texture to: " + path);
    }
ancient shoal
orchid prawn
# ancient shoal 1. I don't think setting camera target texture is enough. It would probably just...
 cam.depthTextureMode |= DepthTextureMode.Depth;

 [...]

Texture depth = Shader.GetGlobalTexture("_CameraDepthTexture");
if (depth == null)
  Debug.LogError("Depth is null");
visibilityCompute.SetTexture(kernel, "_CameraDepthTexture", depth);

In compute shader:

Texture2D _CameraDepthTexture;

It looks like _CameraDepthTexture is all black - it has the same value everywhere.
In the rendering debugger, Depth looks correct.

ancient shoal
#

It's very likely that the range of values is very small and the rendering debugger just beautifies it to make it easy to see. I'd check in the frame debugger for the real preview.

orchid prawn
# ancient shoal How do you know it's all black?
  1. There is some method that checks texture type and said that it is "black". I don't remember how it was called.
  2. I wrote a method that transforms render texture to texture 2D and checks for unique values.
  3. I set my compute shader to color model vertices based on distances red from depth buffer and all vertices had the same color = the same value.
#

Frame debugger shows correct depth texture

#

It looks related to my problem, I'll check if my code works on Unity 2021

ancient shoal
#

Yeah, I've seen that too. That's why I suggested render graph in my reply.

#

I'm just not 100% other ways are invalid.

orchid prawn