refactor(gsplat): move GPU sort/cull pipeline into the hybrid renderer#8924
Merged
Conversation
added 5 commits
June 18, 2026 14:27
…ches Step 1-2 of moving the GPU pipeline into the renderer: add usesGpuSort/ requiresBounds/requiresCpuSort getters (base false, hybrid true) and route the manager's per-frame activeRenderer checks through them. No behavior change; activeRenderer is now used only for the prepareRendererMode mode-compare.
Step 3-4: extract _markSortedIfNeeded() (the first-sort version-advance + rebuild reaction) as the synchronous GPU counterpart of onSorted, and call it from update() before delegating the GPU sort; collapse the two GPU sortGpuHybrid call sites into one unconditional per-frame GPU delegate (behavior-identical) and remove the now-duplicate markSorted call from sortGpuHybridForCamera. No behavior change.
Step 5: the hybrid renderer now owns its radix sorter, projector, interval compaction and indirect slots, and the cull/project/sort methods (prepareRenderView, sortAndProjectForCamera, _runFrustumCulling, computeDistanceRange, allocateAndWriteIntervalIndirectArgs). Picking moves to the renderer's preparePickingView. The manager keeps the world, the version lifecycle (markSorted/onSorted), and the CPU worker sorter, passing per-call param bags to the renderer (no back-reference). Behavior-preserving.
Step 6-8: the GPU path culls/sorts every frame, so the frustum-change trackers (testFrustumChanged, lastCullingCameraFwd/ProjMat) were vestigial after the move — remove them; the CPU re-sort trackers (testCameraMovedForSort, lastSortCamera*) stay. Remove the now-unused canCull getter and refresh the manager class doc to describe the world/CPU-sort vs renderer-GPU-pipeline split.
… param bag Replace the untyped 'object' param bag with a GSplatRenderViewParams typedef defined on GSplatRenderer (the interface owner) and referenced from the manager and hybrid renderer. Also adds the base prepareRenderView/preparePickingView stubs (typed) and types the world/worldState params. Type-only change.
Build size reportThis PR changes the size of the minified bundles.
|
…public API) The typedef is internal plumbing between the manager and the hybrid renderer, not public API. Add @ignore so TypeDoc/api-report exclude it, and reference GSplatVaryings via an inline import() type (keeps it resolvable without a separate @import line that lint would prune as unused once the typedef is ignored).
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.
Moves the GPU sort/projection/cull pipeline out of
GSplatManagerand intoGSplatHybridRenderer, so each renderer owns its own per-view GPU work. Behavior-preserving. This is the prerequisite for an upcoming directional-shadow renderer that needs to reuse the per-view cull without duplicating manager plumbing.Changes:
GSplatManageris slimmed to:GSplatWorldownership, the world version lifecycle (markSorted/onSorted), the CPU worker sorter, and per-frame orchestration (~500 fewer lines). The version lifecycle stays here via a new_markSortedIfNeeded(the synchronous GPU counterpart ofonSorted), called before delegating. The manager passes per-call parameter bags to the renderer, with no renderer→manager back-reference.GSplatHybridRenderernow owns its GPU pipeline: the radix sorter, projector, interval compaction, and indirect draw/dispatch slots (created in its constructor, freed indestroy()), plus the cull/project/sort methods (prepareRenderView,sortAndProjectForCamera,_runFrustumCulling,computeDistanceRange,allocateAndWriteIntervalIndirectArgs). Picking moves topreparePickingView.GSplatRenderer(base) gains capability getters (usesGpuSort/requiresBounds/requiresCpuSort) and theprepareRenderView/preparePickingView/invalidateCullUploadinterface, plus aGSplatRenderViewParamstypedef for the per-call param bag. The manager now branches on these capabilities instead ofactiveRenderer.testFrustumChanged,lastCulling*) and thecanCullgetter are removed.GSplatQuadRenderer(CPU sort) is unchanged.API Changes:
@ignore).Performance:
autoRender = trueand on-demand paths both unchanged).