Rebuild the ACTIVE ordering into a valid permutation of [0, count),
reusing whatever permutation the buffer already holds over
[0, prevCount) instead of resetting to storage order.
The problem this solves: an nD re-slice changes a node's resident element
count at almost every step (cloud, a 4D Points timelapse, walks
27834 -> 27643 -> 27416 -> 27124 ...), and the commit paths' preserveOrdering
guard requires prevCount === count. So it never fired on a real timelapse
and every timepoint fell through to writeSortedIndexIdentity, drawing
at least one frame in pure storage order before the SortWorker's permutation
landed ~5 ms later. Under an order-dependent blending mode that frame is
visibly wrong — it reads as a flash once per timepoint through playback.
The reason the guard was written that way is real and is stated at
commit-gsplats-geometry.ts: a permutation of [0,prevCount) is not a
permutation of [0,count). This closes that gap rather than relaxing the
invariant. Measured on the live cloud demo at a frozen camera pose — the
fraction of sampled element pairs composited in correct back-to-front order,
across a real timepoint step:
(Freeze the camera pose before measuring anything like this. Demos open in
cinematic mode with the camera orbiting at ~13.85 deg/s, and an ordering
scored against a pose it was not sorted for reads 0.161 — stale in CAMERA,
not in data. That number cost an afternoon.)
The walk emits each value below count the first time it is seen, then
appends whatever is still missing in ascending order. That yields a valid
permutation for a GROWN count, a SHRUNK count, and a malformed input
alike — a partially applied chunked ordering degrades to a valid
permutation instead of drawing one element twice and another never, which
matters because cancelSortedIndexOrderingApply exists precisely
because partial application is a reachable state.
Unlike writeSortedIndexIdentity this deliberately does NOT re-home
the geometry on slot 0. A full identity write is the fresh-start signal that
lets an untracked node's default-valued selector uniform be correct; a
repair is the opposite claim — its callers fire only when the tenant, the
geometry and the attribute buffers are all unchanged, so the slot/uniform
pairing is already established, and normalising would throw away the
permutation being repaired.
Rebuild the ACTIVE ordering into a valid permutation of
[0, count), reusing whatever permutation the buffer already holds over[0, prevCount)instead of resetting to storage order.The problem this solves: an nD re-slice changes a node's resident element count at almost every step (
cloud, a 4D Points timelapse, walks 27834 -> 27643 -> 27416 -> 27124 ...), and the commit paths'preserveOrderingguard requiresprevCount === count. So it never fired on a real timelapse and every timepoint fell through to writeSortedIndexIdentity, drawing at least one frame in pure storage order before the SortWorker's permutation landed ~5 ms later. Under an order-dependent blending mode that frame is visibly wrong — it reads as a flash once per timepoint through playback.The reason the guard was written that way is real and is stated at
commit-gsplats-geometry.ts: a permutation of [0,prevCount) is not a permutation of [0,count). This closes that gap rather than relaxing the invariant. Measured on the liveclouddemo at a frozen camera pose — the fraction of sampled element pairs composited in correct back-to-front order, across a real timepoint step:(Freeze the camera pose before measuring anything like this. Demos open in cinematic mode with the camera orbiting at ~13.85 deg/s, and an ordering scored against a pose it was not sorted for reads 0.161 — stale in CAMERA, not in data. That number cost an afternoon.)
The walk emits each value below
countthe first time it is seen, then appends whatever is still missing in ascending order. That yields a valid permutation for a GROWN count, a SHRUNK count, and a malformed input alike — a partially applied chunked ordering degrades to a valid permutation instead of drawing one element twice and another never, which matters because cancelSortedIndexOrderingApply exists precisely because partial application is a reachable state.Unlike writeSortedIndexIdentity this deliberately does NOT re-home the geometry on slot 0. A full identity write is the fresh-start signal that lets an untracked node's default-valued selector uniform be correct; a repair is the opposite claim — its callers fire only when the tenant, the geometry and the attribute buffers are all unchanged, so the slot/uniform pairing is already established, and normalising would throw away the permutation being repaired.