fix(shader): emit SCENE_DEPTHMAP_FLOAT for materials sampling scene depth#8851
fix(shader): emit SCENE_DEPTHMAP_FLOAT for materials sampling scene depth#8851slimbuck wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
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.getCoreDefinesto applyShaderUtils.addScreenDepthChunkDefines(...)for material shader variants. - Ensure
SCENE_DEPTHMAP_FLOATis set for material shaders on float-renderable devices (matchingRenderPassPrepassdepth texture format selection).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Superseded by #8856, which fixes the same bug more cleanly: instead of injecting a |
Description
Materials that sample the scene depth map via
screenDepthPSwere decoding it in the wrong format ontextureFloatRenderabledevices, 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 readuSceneDepthMap).Root cause
screenDepthPSselects its decode from two defines:Material shaders assemble their defines through
ShaderUtils.getCoreDefines, which copiescameraShaderParams.defines.CameraShaderParamscan only ever emitSCENE_DEPTHMAP_LINEAR— it has nodevicereference, andSCENE_DEPTHMAP_FLOATdepends ondevice.textureFloatRenderable. So the material path never setSCENE_DEPTHMAP_FLOAT.Meanwhile
RenderPassPrepassallocates the linear-depth texture asR32Fwhendevice.textureFloatRenderable(and packedRGBA8otherwise). 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 callingShaderUtils.addScreenDepthChunkDefines(device, ...)themselves. The material define path was the one place that didn't.Fix
Call
ShaderUtils.addScreenDepthChunkDefinesfromgetCoreDefines(which already hasparams.devicein scope), so materials getSCENE_DEPTHMAP_FLOATwhenever the device is float-renderable — matching the format the prepass allocated. The redundantSCENE_DEPTHMAP_LINEARre-set is a no-op (same key/value).Fixes #
Checklist