Skip padding pixels during GSplat sorting and rendering#8471
Merged
mvaligursky merged 2 commits intomainfrom Feb 23, 2026
Merged
Skip padding pixels during GSplat sorting and rendering#8471mvaligursky merged 2 commits intomainfrom
mvaligursky merged 2 commits intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the unified GSplat pipeline to consistently treat work-buffer padding pixels as non-splats, reducing CPU sorting work and preventing GPU-side “ghost splats” caused by stale padding data.
Changes:
- Introduces
totalActiveSplats(excluding per-placement row padding) and routes CPU sorting/CPU-compaction to operate only on active splats. - Adds sentinel
pcNodeIndex = 0xFFFFFFFF(and related shader writes) so GPU compaction/visibility rejects padding pixels reliably. - Adjusts work-buffer sub-draw generation to cover trailing padding pixels so they get overwritten instead of retaining stale data.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/scene/shader-lib/wgsl/chunks/gsplat/frag/gsplatCopyToWorkbuffer.js | Writes pcId and a sentinel pcNodeIndex for out-of-bounds (padding) pixels in WGSL. |
| src/scene/shader-lib/wgsl/chunks/gsplat/compute-gsplat-compact-flag.js | Treats sentinel pcNodeIndex pixels as always invisible during GPU compaction flagging. |
| src/scene/shader-lib/glsl/chunks/gsplat/frag/gsplatCopyToWorkbuffer.js | Mirrors padding sentinel writes for GLSL. |
| src/scene/gsplat-unified/gsplat-world-state.js | Tracks totalActiveSplats in addition to totalUsedPixels. |
| src/scene/gsplat-unified/gsplat-unified-sort-worker.js | CPU worker sorts only active splats and maps compact indices back to work-buffer pixels via indexMap. |
| src/scene/gsplat-unified/gsplat-manager.js | Threads totalActiveSplats through CPU sort/compaction paths and updates stats to exclude padding. |
| src/scene/gsplat-unified/gsplat-info.js | Extends a sub-draw region to ensure trailing padding pixels are covered by fragment writes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
slimbuck
approved these changes
Feb 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
indexMap(built once per world-state change, not per-sort) maps compact splat indices back to work-buffer pixel positions, so the sorted order buffer and distance arrays are sized tototalActiveSplatsinstead oftotalUsedPixels.pcNodeIndexvalue (0xFFFFFFFF), preventing stale data in unused work-buffer regions from being treated as visible splats.pcIdandpcNodeIndexin the padding branch, ensuring padding pixels are never mistaken for real splats regardless of sort path.Technical Details
GSplatWorldStatetrackstotalActiveSplatsalongsidetotalUsedPixelsGSplatManagerpassestotalActiveSplatsfor CPU sort paths and GPU compaction element countsindexMapin theintervalshandler and uses it during counting sort outputGSplatInfo.updateSubDraws()extendscolEndof the last partial row totextureWidthcompute-gsplat-compact-flag.jschecks for sentinelnodeIdx == 0xFFFFFFFFbefore visibility lookup