Add depth testing for compute GSplat renderer when CameraFrame depth prepass is enabled#8581
Conversation
…prepass is enabled Enable the compute-based Gaussian Splat rasterizer to depth-test against opaque scene geometry using the linear depth texture from the depth prepass. Splats behind opaque surfaces are skipped per-pixel, and entire 2x2 quads early-out when fully occluded. Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
This PR adds an optional depth-test path to the compute-based Gaussian Splat (GSplat) local rasterizer so splats can be occluded by opaque scene geometry when a linear-depth prepass is enabled (e.g., via CameraFrame.rendering.sceneDepthMap).
Changes:
- Adds a
DEPTH_TESTWGSL shader variant that loads the scene’s linear depth texture and skips splats behind it, including an early-out when a splat is behind all 2x2 quad samples. - Extends
GSplatLocalDispatchSetrasterize variants to support acolor-depthpipeline with asceneDepthMapbinding and refactors variant selection to use boolean flags. - Updates the
lod-streamingexample UI to toggle an occluder cube and enable/disable the depth prepass.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/scene/shader-lib/wgsl/chunks/gsplat/compute-gsplat-local-rasterize.js | Adds DEPTH_TEST sampling/comparisons against linear scene depth during compute rasterization. |
| src/scene/gsplat-unified/gsplat-local-dispatch-set.js | Adds bind-group support + shader defines for the depth-test rasterize variant. |
| src/scene/gsplat-unified/gsplat-compute-local-renderer.js | Selects depth-test variant at dispatch time and marks the pass as requiresDepth. |
| examples/src/examples/gaussian-splatting/lod-streaming.example.mjs | Adds an occluder entity and toggles CameraFrame depth prepass via UI state. |
| examples/src/examples/gaussian-splatting/lod-streaming.controls.mjs | Adds an “Occluder” toggle control. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // requiresDepth hints that a depth prepass should run first, so the | ||
| // rasterize shader can skip splats behind opaque geometry. | ||
| camera.beforePasses.push({ pass: this.framePass, requiresDepth: true }); |
There was a problem hiding this comment.
requiresDepth on camera.beforePasses doesn’t appear to be consumed anywhere in the current codebase (no reads found), so setting it to true here is currently a no-op and the added comment implies behavior that doesn’t actually happen. Either wire requiresDepth into the scheduling logic (so it actually triggers/requests a depth prepass) or keep this metadata/comment aligned with what the engine does today.
| // requiresDepth hints that a depth prepass should run first, so the | |
| // rasterize shader can skip splats behind opaque geometry. | |
| camera.beforePasses.push({ pass: this.framePass, requiresDepth: true }); | |
| camera.beforePasses.push({ pass: this.framePass }); |
Enable the compute-based Gaussian Splat rasterizer to depth-test against opaque scene geometry using the linear depth texture from the depth prepass.
Changes:
DEPTH_TESTshader variant to the compute rasterize shader that loads per-pixel scene depth and skips splats behind opaque geometryGSplatLocalDispatchSetvariant system to supportcolor-depthvariant withsceneDepthMapbindingcamera.shaderParams.sceneDepthMapLinearanduSceneDepthMaprequiresDepth: trueon the beforePasses entry to signal depth prepass dependencyall()for consistencygetRasterizeComputeto accept boolean parameters instead of string keysExamples:
lod-streamingexample with an "Occluder" toggle in Scene controls that shows an orange cube and enables the depth prepassPerformance: