Skip to content

fix(shader): emit SCENE_DEPTHMAP_FLOAT for materials sampling scene depth#8851

Closed
slimbuck wants to merge 1 commit into
playcanvas:mainfrom
slimbuck:depth-fix
Closed

fix(shader): emit SCENE_DEPTHMAP_FLOAT for materials sampling scene depth#8851
slimbuck wants to merge 1 commit into
playcanvas:mainfrom
slimbuck:depth-fix

Conversation

@slimbuck

@slimbuck slimbuck commented Jun 5, 2026

Copy link
Copy Markdown
Member

Description

Materials that sample the scene depth map via screenDepthPS were decoding it in the wrong format on textureFloatRenderable devices, producing garbage depth values (visible as zebra/banding artifacts on any geometry shaded against scene depth — e.g. a gsplat cutout effect, and StandardMaterial paths that read uSceneDepthMap).

Root cause

screenDepthPS selects its decode from two defines:

#ifdef SCENE_DEPTHMAP_LINEAR
    #ifdef SCENE_DEPTHMAP_FLOAT
        return texture2D(uSceneDepthMap, uv).r;   // R32F: read float directly
    #else
        // unpack a float from RGBA8 ...
    #endif
#endif

Material shaders assemble their defines through ShaderUtils.getCoreDefines, which copies cameraShaderParams.defines. CameraShaderParams can only ever emit SCENE_DEPTHMAP_LINEAR — it has no device reference, and SCENE_DEPTHMAP_FLOAT depends on device.textureFloatRenderable. So the material path never set SCENE_DEPTHMAP_FLOAT.

Meanwhile RenderPassPrepass allocates the linear-depth texture as R32F when device.textureFloatRenderable (and packed RGBA8 otherwise). On a float-renderable device the texture is therefore R32F, but the material shader took the packed-RGBA8 decode branch → wrong values.

The post-process passes (render-pass-taa, render-pass-coc, render-pass-ssao, render-pass-depth-aware-blur) each already work around this by calling ShaderUtils.addScreenDepthChunkDefines(device, ...) themselves. The material define path was the one place that didn't.

Fix

Call ShaderUtils.addScreenDepthChunkDefines from getCoreDefines (which already has params.device in scope), so materials get SCENE_DEPTHMAP_FLOAT whenever the device is float-renderable — matching the format the prepass allocated. The redundant SCENE_DEPTHMAP_LINEAR re-set is a no-op (same key/value).

Fixes #

Checklist

@slimbuck slimbuck requested review from Copilot and mvaligursky June 5, 2026 21:08
@slimbuck slimbuck self-assigned this Jun 5, 2026
@slimbuck slimbuck added the area: graphics Graphics related issue label Jun 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes incorrect scene depth decoding in material shaders on devices that can render to 32-bit float textures (textureFloatRenderable). It ensures materials that use the screenDepthPS chunk receive the SCENE_DEPTHMAP_FLOAT define so they decode uSceneDepthMap as R32F when the prepass allocates it that way.

Changes:

  • Extend ShaderUtils.getCoreDefines to apply ShaderUtils.addScreenDepthChunkDefines(...) for material shader variants.
  • Ensure SCENE_DEPTHMAP_FLOAT is set for material shaders on float-renderable devices (matching RenderPassPrepass depth texture format selection).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mvaligursky

Copy link
Copy Markdown
Contributor

Superseded by #8856, which fixes the same bug more cleanly: instead of injecting a SCENE_DEPTHMAP_FLOAT define onto the material path, it selects the decode in the screenDepthPS chunk from the global CAPS_TEXTURE_FLOAT_RENDERABLE define. The texture format (set by the prepass) and the shader decode then share a single source of truth and can't disagree, and the redundant SCENE_DEPTHMAP_FLOAT concept is removed entirely.

@mvaligursky mvaligursky closed this Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: graphics Graphics related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants