Depth texture shows pure red when using CameraFrame / RenderPassDepthGrab

Following this older discussion, I’ve been trying to access the scene depth texture (will be used later).

I tested both approaches:

  • RenderPassDepthGrab
  • CameraFrame.rendering.sceneDepthMap = true

However, in both cases, the resulting texture appears pure red when drawn.

Here’s the snippet I used:

// init()
this.entity.camera.requestSceneDepthMap(true);

// update()
const renderPassDepthGrab = this.entity.camera.camera.renderPassDepthGrab;
if (!renderPassDepthGrab) return;

const depthRenderTarget = renderPassDepthGrab.depthRenderTarget;
if (!depthRenderTarget) return;

const depthTexture = this.app.graphicsDevice.isWebGL2
    ? depthRenderTarget.depthBuffer
    : depthRenderTarget.colorBuffer;  // Why colorBuffer here?

console.log('depth texture:', depthTexture);
this.app.drawTexture(0.7, -0.7, 0.5, 0.5, depthTexture);

Is this expected, or is there a correct way to sample it?

Any guidance or confirmation from others who’ve tried this recently would be appreciated!
Project Link: https://playcanvas.com/editor/scene/2346401

A depth texture is quite a specific type of data. It’s important to understand that depth textures come in different formats, and not all of them can be displayed directly on the screen. To visualize such a texture in PlayCanvas, you should use the dedicated function provided in the following link:

this.app.drawDepthTexture(0.7, -0.7, 0.5, 0.5)

Hi @Wagner , thanks for the reply. For my use-case I’m not trying to display the depth (it’s only for debugging). I need it for compute shader. Concretely, I’m looking for a reliable way to obtain a depth resource that I can bind as texture_2d<f32>, ideally linear depth in R32F.

Very few mobile devices support r32f texture, you are better off using rgba8 texture into which you encode float.

GLSL:


    precision highp float;

    #include "floatAsUintPS"

    uniform highp sampler2D uSceneDepthMap;

    #ifdef WEBGPU

        #ifdef SCENE_DEPTHMAP_FLOAT
            #define getDepth(xy, offset, level) texelFetch(uSceneDepthMap, xy + offset, level).r
        #else
            #define getDepth(xy, offset, level) uint2float(texelFetch(uSceneDepthMap, xy + offset, level))
        #endif

    #else

        #ifdef SCENE_DEPTHMAP_FLOAT
            #define getDepth(xy, offset, level) texelFetchOffset(uSceneDepthMap, xy, level, offset).r
        #else
            #define getDepth(xy, offset, level) uint2float(texelFetchOffset(uSceneDepthMap, xy, level, offset))
        #endif
    
    #endif
    precision highp float;

    uniform highp sampler2D uDepthMip;

    void main() {

        ivec2 xy = ivec2(gl_FragCoord.xy);
        float depth = getDepth(uDepthMip, xy, 0);

        #ifdef WRITE_DEPTH
            gl_FragDepth = depth ;
        #elifdef WRITE_FLOAT
            gl_FragColor = vec4(vec3(depth), 1.0);
        #else
            gl_FragColor = float2uint(depth);
        #endif
    }