Accessing depth buffer 2022

Hey, I’ve read around and there seems to have been an update recently to how to get access to the depth buffer on your camera in PlayCanvas.

Earlier you could just write this line on the camera entity

this.entity.camera.camera.requestDepthMap();

and then later access the depth map in any shader by declaring this uniform variable in any fragment shader code:

uniform sampler2D uDepthMap;

Recently however, it seems the first function for requesting the depth buffer has been replaced by this:

this.entity.camera.requestSceneDepthMap(true);

But I haven’t managed to figure out how to access it, so it can be used in for instance, custom shaders. Anyone know how to go about this?

1 Like

Hi @Astra and welcome,

The last method is the proposed way to request the engine to render a depth map:

this.entity.camera.requestSceneDepthMap(true);

After you do that you can access the depth map in your shaders, and there are convenience methods in the screenDepthPS shader chunk.

So for if your material doesn’t include that shader chunk already, you can add manually in your overriden shader code like this:

// example accessing the depth map in an overriden diffuse shader chunk
material.chunks.diffusePS = `

${pc.shaderChunks.screenDepthPS}

#ifdef MAPCOLOR
uniform vec3 material_diffuse;
#endif

#ifdef MAPTEXTURE
uniform sampler2D texture_diffuseMap;
#endif

void getAlbedo() {

    float pixelDepth = getLinearDepth(vPositionW);
    float screenDepth = getLinearScreenDepth();

    dAlbedo = vec3(1.0);

#ifdef MAPCOLOR
    dAlbedo *= material_diffuse.rgb;
#endif

#ifdef MAPTEXTURE
    vec3 albedoBase = gammaCorrectInput(texture2D(texture_diffuseMap, $UV, textureBias).$CH);
    dAlbedo *= addAlbedoDetail(albedoBase);
#endif

#ifdef MAPVERTEX
    dAlbedo *= gammaCorrectInput(saturate(vVertexColor.$VC));
#endif
}
`;

material.update();
2 Likes

Thanks!

ok, must admit I’m not that familiar with using shader chunks (make separate openGL fragment and vertex shaders most of the time), but if I understand correctly “getLinearDepth(vPositionW)” and “getLinearScreenDepth()” are now integrated functions that can be accessed in any custom openGL script in PlayCanvas, returning the pixel and screen depth?

I’m assuming “vPositionW” is the world position. Is this also now a latent variable that no longer needs to be passed manually to the fragment shader, but can be accessed without any declaration?

So shader chunks are the small shader pieces that the PlayCanvas standard material is using to assemble the complete vertex and pixel shaders pushed to the GPU for rendering.

One way of writing custom shaders is instead of authoring them from scratch, to override the required shader pieces instead, and rebuild the material shader to include your changes.

Regarding the depth access methods, those are included in this shader chunk:

If you are writing a custom shader from scratch, you can still use them in your shader. You can copy/paste and include that shader code in your shader as helper methods to access depth.

1 Like

this example uses depth texture in custom shaders
https://playcanvas.github.io/#/graphics/ground-fog

source: https://github.com/playcanvas/engine/blob/main/examples/src/examples/graphics/ground-fog.tsx

3 Likes

This github link is down, any update on this?

Hi @Slush and welcome,

The updated github link for screenDepthPS is here: engine/screenDepth.js at a1cb6e20c0e436027b9d417c36882467106868bc · playcanvas/engine · GitHub