Splats · interface

SplatPass

Explained in Gaussian splats.

interface SplatPass extends PassDefinition
import type { SplatPass } from '@driftengine/splats';

Properties

NameTypeDescription
visiblereadonlybooleanWhether the capture reaches the frame at all, as of the last setView.
More

Read this before asking a sorter for a new order. A capture out of frame costs one discarded draw call and a whole linear sort over every splat it has, and the sort is the expensive half — so the caller's frame should skip SplatSorter.frame when this is false. draw checks it too, but by then the sort has already happened.

countreadonlynumber

Methods

setView

setView(view: SplatView): void

Called once a frame, before drawPass. Allocates nothing.

ParameterTypeDescription
viewSplatView

setOrder

setOrder(order: Uint32Array, count: number): void

A new draw order, far to near. Four bytes a splat, into storage allocated once.

ParameterTypeDescription
orderUint32Array
countnumber
More

Until one is set the pass draws nothing: an unsorted capture composited back to front is wrong at every silhouette, and drawing it anyway would look like a working feature.

setModel

setModel(model: ArrayLike<number>): void

The capture's own transform, so two captures compose in one scene.

ParameterTypeDescription
modelArrayLike<number>
More

Two batches are two orders and there is no order between them, and that is a real limit rather than an omission. Each sorter ranks its own splats along the view direction expressed in that batch's space, so the two are each internally correct and the renderer draws one batch's whole cloud before the other's. Where they occupy different volumes — a statue and the room behind it — nothing shows. Where they interpenetrate, the seam is visible as a plane at which one capture starts winning every blend.

What that buys is that a batch's positions never move: one transform on the camera instead of a million on the splats, every frame. What would make it wrong is a scene built from overlapping parts, where the answer is one batch with one order rather than a merge — merging two sorted orders is cheap, but the splats would still be drawn from two textures with two draw calls, so the merge has nowhere to go.

uploadSplats

uploadSplats(from: number, count: number): void

Push a run of splats that has just arrived into the data texture.

ParameterTypeDescription
fromnumber
countnumber
More

For a capture that is still streaming, where the textures were sized for the final count at registration and are filled block by block — see SplatCapture. A caller that packed its whole capture before registering the pass never needs this: init uploads everything.

Whole rows are re-sent, so calling this with overlapping ranges is correct and merely costs a few kilobytes; calling it every frame with the whole capture is not, and is the per-frame upload the scheduler exists to avoid.