Skip to content

@aosengine/splat ​

Classes ​

AnimatedSplat ​

A dynamic splat: SplatSink plus lifecycle.

Implements ​

Constructors ​

Constructor ​
ts
new AnimatedSplat(renderer, options): AnimatedSplat;

Use createAnimatedSplat; the GPU buffers must be acquired before the object is usable, and that needs an initialised renderer.

Parameters ​
ParameterTypeDescription
rendererWebGPURendererAn initialised WebGPURenderer on the WebGPU backend.
optionsCreateAnimatedSplatOptionsCapacity, bounds and draw order.
Returns ​

AnimatedSplat

Properties ​

buffers ​
ts
readonly buffers: SplatGPUBuffers;

The four GPU buffers, in the layout documented in backendBuffers.ts.

Implementation of ​

SplatSink.buffers

capacity ​
ts
readonly capacity: number;

Total gaussians this sink can hold. Fixed for its lifetime.

Implementation of ​

SplatSink.capacity

splat ​
ts
readonly splat: AnimatedGaussianSplat;

The fork instance. Typed as the fork, not as Object3D, for object3D consumers.

Accessors ​

available ​
Get Signature ​
ts
get available(): number;

Slots not handed out. Named available, because free is the method above.

Returns ​

number

The count.

object3D ​
Get Signature ​
ts
get object3D(): Object3D;

The scene object.

Returns ​

Object3D

The fork instance, which is an ordinary Object3D.

The scene object. Add it to a scene, move it, parent it — it is an ordinary Object3D.

Implementation of ​

SplatSink.object3D

used ​
Get Signature ​
ts
get used(): number;

Slots currently handed out.

Returns ​

number

The count.

Methods ​

allocate() ​
ts
allocate(count): SlotRange;

Reserve a contiguous run of slots.

Parameters ​
ParameterTypeDescription
countnumberHow many gaussians.
Returns ​

SlotRange

The range.

Implementation of ​

SplatSink.allocate

clearSlots() ​
ts
clearSlots(range?): void;

Zero a slot range, which makes it invisible: a colour word of 0 is alpha 0.

This is a queue.writeBuffer of zeros, which is allowed here precisely because it is not a per-frame operation — it runs when a branch is allocated or retired. A producer must never upload gaussian data this way; that is what the compute pass is for.

Parameters ​
ParameterTypeDescription
range?SlotRangeThe range to clear. Defaults to the whole capacity.
Returns ​

void

Nothing.

dispose() ​
ts
dispose(): void;

Detach from the scene and release the geometry, material and every storage buffer.

"Every storage buffer" is nine of them: the four gaussian buffers, the spherical-harmonics contribution buffer if the pre-pass ever ran, and the four the sort holds. Three frees none of them on its own — BufferAttribute.dispose() dispatches an event nothing listens for on a storage attribute — so a despawned character used to leak about 2 MB of GPU memory.

Idempotent, and every mutating method throws afterwards.

Returns ​

void

Nothing.

free() ​
ts
free(range): void;

Give a range back.

Parameters ​
ParameterTypeDescription
rangeSlotRangeA range from AnimatedSplat.allocate.
Returns ​

void

Nothing.

Implementation of ​

SplatSink.free

markGaussiansChanged() ​
ts
markGaussiansChanged(): void;

Force a re-sort on the next frame.

Returns ​

void

Nothing.

Implementation of ​

SplatSink.markGaussiansChanged

setBoundingSphere() ​
ts
setBoundingSphere(center, radius): void;

Declare where the gaussians are, in local space.

Parameters ​
ParameterTypeDescription
centerVec3TupleLocal-space centre.
radiusnumberLocal-space radius.
Returns ​

void

Nothing.

Implementation of ​

SplatSink.setBoundingSphere

setFragmentAlpha() ​
ts
setFragmentAlpha(builder): void;

Scale each fragment's opacity by a node built from the splat's view-space centre, or pass null to draw as before. See the fork's edit 15.

Parameters ​
ParameterTypeDescription
builder((view) => Node) | nullReturns a float node from the view-space centre (a vec3 node).
Returns ​

void

Nothing.


SlotAllocationError ​

An allocation request that cannot be satisfied.

Extends ​

  • Error

Constructors ​

Constructor ​
ts
new SlotAllocationError(
   message, 
   requested, 
   largestFree
): SlotAllocationError;

Build a slot allocation error.

Parameters ​
ParameterTypeDescription
messagestringWhat went wrong.
requestednumberSlots requested.
largestFreenumberLargest free run at the time.
Returns ​

SlotAllocationError

Overrides ​
ts
Error.constructor

Properties ​

largestFree ​
ts
readonly largestFree: number;

The largest run available at the time.

requested ​
ts
readonly requested: number;

Slots that were asked for.


SplatLoadError ​

A splat file that could not be decoded.

Extends ​

  • Error

Constructors ​

Constructor ​
ts
new SplatLoadError(
   url, 
   message, 
   options?
): SplatLoadError;

Build a splat load error.

Parameters ​
ParameterTypeDescription
urlstringThe URL that failed.
messagestringWhat went wrong.
options?ErrorOptionsStandard Error options, used to keep the cause.
Returns ​

SplatLoadError

Overrides ​
ts
Error.constructor

Properties ​

url ​
ts
readonly url: string;

The URL that failed.

Interfaces ​

CreateAnimatedSplatOptions ​

Options accepted by createAnimatedSplat.

Properties ​

autoSort? ​
ts
readonly optional autoSort?: boolean;

Sort in onBeforeRender. Defaults to true, which is what a producer wants: paired with markGaussiansChanged it gives exactly one sort per frame.

boundingSphere? ​
ts
readonly optional boundingSphere?: object;

Where the gaussians will be, in local space. Defaults to a unit sphere at the origin, which is almost certainly wrong; set it as soon as the producer knows.

center ​
ts
readonly center: Vec3Tuple;
radius ​
ts
readonly radius: number;
capacity ​
ts
readonly capacity: number;

Gaussians to allocate. Fixed for the object's lifetime.

colorSpace? ​
ts
readonly optional colorSpace?: "linear" | "srgb";

What the producer's packed colour bytes mean. 'linear' (the default) is what three assumes and encodes to sRGB in its output pass; 'srgb' says the bytes are already sRGB (a character trained against photographs), so each gaussian is decoded to linear in the vertex shader and the screen shows the file's own colours instead of a second encode.

renderOrder? ​
ts
readonly optional renderOrder?: number;

Draw order. Defaults to SPLAT_RENDER_ORDER.


CreateSplatObjectOptions ​

Options accepted by createSplatObject.

Properties ​

autoSort? ​
ts
readonly optional autoSort?: boolean;

Re-sort in onBeforeRender when the camera turns far enough. Defaults to true. Turn it off only if you drive updateSort yourself.

colorSpace? ​
ts
readonly optional colorSpace?: "linear" | "srgb";

What the file's colour bytes mean. 'linear' (the default) is three's assumption, and the renderer's output pass encodes them to sRGB. 'srgb' is for a splat trained against photographs — a place from Gameable CC — whose colours are already sRGB: they are decoded per gaussian, so the page shows the file's own colours instead of a lifted, washed-out copy. Opting in draws through the fork (AnimatedGaussianSplat) and marks the asset's geometry (userData.colorSpace), so every object made from that asset agrees.

environmentLighting? ​
ts
readonly optional environmentLighting?: SplatEnvironmentLighting;

Opt into diffuse lighting; omitted keeps the native, unlit splat path.

receiveShadows? ​
ts
readonly optional receiveShadows?: boolean;

Make it the maintained fork, which can receive shadows (setShadowReceiver); it draws exactly as three's own until one is switched on. Defaults to false here; the splat service's add passes true.

renderOrder? ​
ts
readonly optional renderOrder?: number;

Draw order. Defaults to SPLAT_RENDER_ORDER.


EnvironmentProbeOptions ​

Shared mesh environment and Gaussian probe settings. SH must already be in world space.

Properties ​

enabled? ​
ts
optional enabled?: boolean;

Set false to temporarily attach no mesh environment. Default true.

intensity? ​
ts
optional intensity?: number;

Shared brightness multiplier. Default 1.

radianceSH ​
ts
radianceSH: readonly readonly [number, number, number][];

Nine RGB radiance coefficients, already rotated to match the scene.

yaw? ​
ts
optional yaw?: number;

Panorama yaw in radians; does not rotate the supplied world-space SH.


GaussianCloud ​

Gaussians of a place, for panoramaFromGaussians.

Properties ​

colors ​
ts
readonly colors: ArrayLike<number>;

RGBA per gaussian (alpha = opacity), multiplied by colorScale to reach 0..1.

colorScale? ​
ts
readonly optional colorScale?: number;

Multiplier on colors. Defaults to 1/255.

colorSpace? ​
ts
readonly optional colorSpace?: "linear" | "srgb";

'srgb' decodes the colours before any sum. Defaults to 'srgb' (a place trained on photographs).

matrixWorld? ​
ts
readonly optional matrixWorld?: ArrayLike<number>;

Column-major 4x4 from the cloud's space to the world (three's Matrix4.elements). Defaults to identity.

positions ​
ts
readonly positions: ArrayLike<number>;

Centres, three per gaussian, in the cloud's own space.


GaussianPanoramaOptions ​

Options for panoramaFromGaussians.

Properties ​

maxSamples? ​
ts
readonly optional maxSamples?: number;

Upper bound on gaussians visited; the rest are skipped evenly. Defaults to 600 000.

minDistance? ​
ts
readonly optional minDistance?: number;

Gaussians nearer than this to the probe are skipped (the character's own space). Defaults to 0.35 m.

minOpacity? ​
ts
readonly optional minOpacity?: number;

Gaussians fainter than this opacity are skipped. Defaults to 0.3.

width? ​
ts
readonly optional width?: number;

Pixels across; the height is half. Defaults to 64.


GltfLoaderLike ​

The subset of GLTFLoader this package needs, so the loader itself is not imported.

Methods ​

register() ​
ts
register(callback): unknown;

three's plugin hook.

Parameters ​
ParameterTypeDescription
callback(parser) => unknownBuilds the plugin from the parser.
Returns ​

unknown

The loader, for chaining.


KeyLightEstimate ​

A key light's direction and balance.

Properties ​

azimuth ​
ts
readonly azimuth: number;

Degrees around y, from +z toward +x.

confidence ​
ts
readonly confidence: number;

0 when there is no single key to find (flat light), 1 for a clear one.

direction ​
ts
readonly direction: readonly [number, number, number];

Unit vector from the scene toward the light, y up.

elevation ​
ts
readonly elevation: number;

Degrees above the horizon.

keyToFill ​
ts
readonly keyToFill: number;

Light on a surface facing the key over light on a surface facing away from it.

shadowStrength ​
ts
readonly shadowStrength: number;

How dark the key's shadow is, 0 to 1: the key's share of the light on a surface facing it, 1 - 1 / keyToFill, held at 0.9 or below.


LightProbeGrid ​

Samples a LightProbeGridData anywhere inside it.

Methods ​

sample() ​
ts
sample(
   x, 
   y, 
   z, 
   out
): Float32Array;

The light at a point, blended from the nearest probes.

Parameters ​
ParameterTypeDescription
xnumberPlace-frame x.
ynumberPlace-frame y.
znumberPlace-frame z.
outFloat32Array27 numbers, written in place.
Returns ​

Float32Array

out.


LightProbeGridData ​

The baked grid, as its JSON file holds it.

Properties ​

bounds ​
ts
readonly bounds: object;

The grid's box, in the place's frame.

max ​
ts
readonly max: readonly number[];
min ​
ts
readonly min: readonly number[];
dims ​
ts
readonly dims: object;

Probes across (x) and deep (z) per layer.

nx ​
ts
readonly nx: number;
nz ​
ts
readonly nz: number;
layerYs ​
ts
readonly layerYs: readonly number[];

Height of each layer, in the place's frame.

probes ​
ts
readonly probes: readonly object[];

Layer by layer, row by row (z), then x: { p: position, sh: 27 numbers }.

spacing ​
ts
readonly spacing: number;

Metres between neighbouring probes of a layer.


LoadSplatOptions ​

Options accepted by loadSplat.

Properties ​

fetch? ​
ts
readonly optional fetch?: {
  (input, init?): Promise<Response>;
  (input, init?): Promise<Response>;
};

Replaces globalThis.fetch, for tests and for an asset-manager transport.

Call Signature ​
ts
(input, init?): Promise<Response>;

MDN Reference

Parameters ​
ParameterType
inputURL | RequestInfo
init?RequestInit
Returns ​

Promise<Response>

Call Signature ​
ts
(input, init?): Promise<Response>;

MDN Reference

Parameters ​
ParameterType
inputstring | URL | Request
init?RequestInit
Returns ​

Promise<Response>

format? ​
ts
readonly optional format?: SplatFormatOption;

Force a decoder instead of sniffing. Defaults to 'auto'.

signal? ​
ts
readonly optional signal?: AbortSignal;

Aborts the fetch. The decode itself is synchronous and is not interruptible.


Panorama ​

An equirectangular picture in three's orientation: the top row looks up, u = 0.5 looks along +x.

Properties ​

channels? ​
ts
readonly optional channels?: 4 | 1 | 3;

Numbers per pixel: 1 (luminance), 3 (RGB) or 4 (RGBA). Defaults to 4.

colorSpace? ​
ts
readonly optional colorSpace?: "linear" | "srgb";

'srgb' decodes each number before any sum (a photograph); 'linear' uses it as is. Defaults to 'linear'.

data ​
ts
readonly data: ArrayLike<number>;

Row-major from the top row, channels numbers per pixel.

height ​
ts
readonly height: number;

Pixels down (180°).

scale? ​
ts
readonly optional scale?: number;

Multiplier that brings a stored number to 0..1 (1/255 for bytes). Defaults to 1.

width ​
ts
readonly width: number;

Pixels across (360°).

yaw? ​
ts
readonly optional yaw?: number;

Degrees added to every azimuth read from the picture, for a picture whose middle column does not look along +x (three's orientation). A World Labs place's own panorama looks along -z in its middle column: pass 90, plus the place's own turn. Defaults to 0.


PanoramaKeyLightOptions ​

Options for estimateKeyLightFromPanorama.

Properties ​

clipBoost? ​
ts
readonly optional clipBoost?: number;

How much brighter than white a clipped pixel is taken to be (an 8-bit picture stores a lamp or the sun as white): values above 0.8 are raised by up to 1 + clipBoost times, as the studio's place-light reader does. Defaults to 24 for an sRGB picture, 0 for a linear one.

holdAbove? ​
ts
readonly optional holdAbove?: number;

The key found is then lifted to at least this elevation, keeping its azimuth (a lamp at eye height still throws a floor shadow a camera can see). Defaults to minElevation.

keyCone? ​
ts
readonly optional keyCone?: number;

Half-width of the key's cone, in degrees, for the confidence. Defaults to 25.

minElevation? ​
ts
readonly optional minElevation?: number;

The key is searched no lower than this, in degrees above the horizon. Defaults to 0.


ShadowCharacter ​

A character, as the shadows need it.

Properties ​

captured? ​
ts
readonly optional captured?: KeyLightEstimate | null;

The light its colours were captured under, in the character's own space (see estimateKeyLightFromSurfels).

footBones? ​
ts
readonly optional footBones?: readonly string[];

The foot joints, for the contact shadow. Defaults to l_foot/r_foot, then foot_l/foot_r.

headBone? ​
ts
readonly optional headBone?: string;

The head joint: it and its children are left out of the character's own shadow. Defaults to c_head, then head.

holder ​
ts
readonly holder: Object3D;

Its origin stands on the floor between the feet.

radius? ​
ts
readonly optional radius?: number;

Metres from the holder's origin to cover around the character. Defaults to 1.

rig ​
ts
readonly rig: Object3D;

Its rig: every skinned mesh under it casts.

splat? ​
ts
readonly optional splat?: AnimatedGaussianSplat | null;

Its gaussians, which receive; null for a mesh-only character.


ShadowDeviceHints ​

What defaultShadowQuality looks at; each field defaults to the browser's own answer.

Properties ​

coarsePointer? ​
ts
readonly optional coarsePointer?: boolean;

A touch screen is the main pointer.

deviceMemory? ​
ts
readonly optional deviceMemory?: number;

navigator.deviceMemory in GB (Chrome's rounded answer; Safari has none).

shortSide? ​
ts
readonly optional shortSide?: number;

The screen's shorter side in CSS pixels.


ShadowInfo ​

What the shadows are doing, for a debug readout.

Properties ​

azimuth ​
ts
readonly azimuth: number;

Degrees around y from +z toward +x, where the light comes from.

characters ​
ts
readonly characters: number;

Characters casting.

confidence ​
ts
readonly confidence: number;

How sure the chosen source was, 0 to 1.

elevation ​
ts
readonly elevation: number;

Degrees above the horizon.

ground ​
ts
readonly ground: boolean;

Whether the see-through ground is drawing (no place).

keyToFill ​
ts
readonly keyToFill: number;

Light facing the key over light facing away, as read.

places ​
ts
readonly places: number;

Places receiving.

quality ​
ts
readonly quality: ShadowQuality;

The level in use.

route ​
ts
readonly route: KeyLightRoute;

Which source decided the light.

sources ​
ts
readonly sources: readonly object[];

Every source that answered, in the order they are preferred, with its answer.

strength ​
ts
readonly strength: number;

How dark the place's shadow is, 0 to 1.

updateMs ​
ts
readonly updateMs: number;

Milliseconds of CPU the last update took, depth passes included.


ShadowPlace ​

A place, as the shadows need it; every field is optional.

Properties ​

collider? ​
ts
readonly optional collider?: Object3D<Object3DEventMap> | null;

Its collider mesh: casts onto characters only, never onto the place itself.

colliderReach? ​
ts
readonly optional colliderReach?: number;

How far toward the light, in metres from the characters, the collider still casts. Only its faces that face the light cast, so a room's own shell never shades the room. Defaults to 8.

compareRoutes? ​
ts
readonly optional compareRoutes?: boolean;

Read every source this place has, not only the first, and list them in info.sources (for a readout; the place's own gaussians cost a tenth of a second more at load). Defaults to false.

lightProbes? ​
ts
readonly optional lightProbes?: LightProbeGridData | null;

A baked light-probe grid, positions and light in world space.

panorama? ​
ts
readonly optional panorama?: Panorama | null;

Its own 360° picture, directions in world space (pass yaw to align it).


ShadowQualityPreset ​

What a level draws.

Properties ​

characterMap ​
ts
readonly characterMap: boolean;

A second map for the characters themselves: their own shadow (an arm on the body) and the place's collider on them. A second depth pass, so only the top level has it.

contact ​
ts
readonly contact: boolean;

A soft dark patch under each foot.

mapSize ​
ts
readonly mapSize: number;

The key light's depth map, texels per side; 0 draws no cast shadow.

taps ​
ts
readonly taps: readonly number[];

The edge filter: flat [dx, dy, weight, ...] in texels.


SlotAllocator ​

Hands out and reclaims slot ranges inside a fixed capacity.

Properties ​

available ​
ts
readonly available: number;

Slots not handed out. Equals capacity - used.

Named available rather than free because free is the method next to it, and a property cannot be both.

capacity ​
ts
readonly capacity: number;

Total slots.

freeRuns ​
ts
readonly freeRuns: readonly SlotRange[];

The free runs, low offset first. Exposed for tests and for the debug overlay.

largestFree ​
ts
readonly largestFree: number;

The largest range allocate could satisfy right now.

used ​
ts
readonly used: number;

Slots currently handed out.

Methods ​

allocate() ​
ts
allocate(count): SlotRange;

Take the first free run large enough.

Parameters ​
ParameterTypeDescription
countnumberHow many slots. Must be a positive integer.
Returns ​

SlotRange

The range.

Throws ​

When nothing is large enough, or RangeError when count is not a positive integer.

free() ​
ts
free(range): void;

Give a range back, coalescing with either neighbour.

Parameters ​
ParameterTypeDescription
rangeSlotRangeA range from allocate.
Returns ​

void

Nothing.

Throws ​

When the range was not allocated, or was already freed.

reset() ​
ts
reset(): void;

Drop every allocation and return to one free run.

Returns ​

void

Nothing.


SlotRange ​

A contiguous run of gaussian slots.

Properties ​

count ​
ts
readonly count: number;

How many slots. Always at least 1.

offset ​
ts
readonly offset: number;

Index of the first slot.


SplatAsset ​

A decoded splat file.

Properties ​

boundingSphere ​
ts
readonly boundingSphere: Sphere;

Bounds of the centres, in the file's own coordinate system.

count ​
ts
readonly count: number;

Gaussians in the file.

format ​
ts
readonly format: SplatFormat;

Which decoder ran.

geometry ​
ts
readonly geometry: BufferGeometry;

Geometry with position (f32x3), covariance (f32x6), color (u8x4) and optional SH.

shDegree ​
ts
readonly shDegree: number;

Spherical-harmonics degree, 0 to 3. Degree 0 is flat colour.

url ​
ts
readonly url: string;

Where it came from.


SplatGPUBuffers ​

The four storage buffers behind a GaussianSplat, as real GPUBuffers.

Properties ​

center ​
ts
readonly center: GPUBuffer;

array<vec4<f32>>: xyz = centre in local space, w unused.

color ​
ts
readonly color: GPUBuffer;

array<u32>: pack4x8unorm(vec4(r, g, b, a)).

covarianceA ​
ts
readonly covarianceA: GPUBuffer;

array<vec4<f32>>: (c00, c01, c02, c11).

covarianceB ​
ts
readonly covarianceB: GPUBuffer;

array<vec4<f32>>: (c12, c22, 0, 0).


SplatModuleOptions ​

Options accepted by splat.

Properties ​

format? ​
ts
readonly optional format?: SplatFormat;

Force a decoder for every splat asset instead of sniffing each one. Leave unset unless your assets are served from URLs with no useful extension.


SplatService ​

What engine.get('splat') returns.

Properties ​

added ​
ts
readonly added: readonly (AnimatedGaussianSplat | GaussianSplat)[];

Every object add has put in the scene, in order (an object removed from the scene stays listed; its parent is null). The character bridge reads it to find the places that receive shadows.

loaded ​
ts
readonly loaded: ReadonlyMap<string, SplatAsset>;

Every splat asset loaded through the registry, by asset id.

Assets are cached by the registry, so this is a view of it, not a second cache.

Methods ​

add() ​
ts
add(id, options?): AnimatedGaussianSplat | GaussianSplat;

Add a loaded asset to the scene as a GaussianSplat, with the right draw order.

It receives shadows unless receiveShadows: false is passed: the object is then the maintained fork (AnimatedGaussianSplat), which draws exactly as three's own until a shadow is switched on.

Parameters ​
ParameterTypeDescription
idstringAsset id, as declared in assets.json.
options?CreateSplatObjectOptions-
Returns ​

AnimatedGaussianSplat | GaussianSplat

The object that was added.


SplatShadows ​

The running shadows of one scene.

Properties ​

info ​
ts
readonly info: ShadowInfo;

What the shadows are doing.

quality ​
ts
readonly quality: ShadowQuality;

The level in use.

Methods ​

addCharacter() ​
ts
addCharacter(key, character): void;

Add a character: its rig casts, its gaussians receive, its colours suggest the light.

Parameters ​
ParameterTypeDescription
keyobjectAny object that names it (the caller's own record).
characterShadowCharacterThe character.
Returns ​

void

Nothing.

addPlace() ​
ts
addPlace(splat, place?): void;

Add a place: its gaussians receive, its data suggests the light.

Parameters ​
ParameterTypeDescription
splatAnimatedGaussianSplatThe place's gaussians (the fork class).
place?ShadowPlaceIts collider, panorama or light probes.
Returns ​

void

Nothing.

dispose() ​
ts
dispose(): void;

Release every map, material and receiver.

Returns ​

void

removeCharacter() ​
ts
removeCharacter(key): void;

Remove a character.

Parameters ​
ParameterTypeDescription
keyobjectThe key it was added with.
Returns ​

void

Nothing.

removePlace() ​
ts
removePlace(splat): void;

Remove a place.

Parameters ​
ParameterTypeDescription
splatAnimatedGaussianSplatThe place's gaussians.
Returns ​

void

Nothing.

setKeyLight() ​
ts
setKeyLight(light): void;

Set the light yourself, or null to go back to reading it from the scene.

Parameters ​
ParameterTypeDescription
lightKeyLightEstimate | nullThe light, world space.
Returns ​

void

Nothing.

setQuality() ​
ts
setQuality(quality): void;

Change the level; 'auto' picks by device. Rebuilds the receivers' shaders once.

Parameters ​
ParameterTypeDescription
quality"auto" | ShadowQualityThe level.
Returns ​

void

Nothing.

update() ​
ts
update(dt): void;

Draw the depth maps. Call once a frame after the characters are posed, before the frame renders.

Parameters ​
ParameterTypeDescription
dtnumberSeconds since the last call.
Returns ​

void

Nothing.


SplatShadowsOptions ​

Options for createSplatShadows.

Properties ​

ground? ​
ts
readonly optional ground?: boolean;

A see-through ground under the characters when no place receives. Defaults to true.

quality? ​
ts
readonly optional quality?: "auto" | ShadowQuality;

A level, or 'auto' (the default) for defaultShadowQuality.

turnSeconds? ​
ts
readonly optional turnSeconds?: number;

Seconds a later, better light takes to turn in. Defaults to 1.


SplatSink ​

What a producer writes into.

Deliberately small and three-free: a lift shader needs slots, buffers and a way to say the gaussians moved, and nothing else.

Properties ​

buffers ​
ts
readonly buffers: SplatGPUBuffers;

The four GPU buffers, in the layout documented in backendBuffers.ts.

capacity ​
ts
readonly capacity: number;

Total gaussians this sink can hold. Fixed for its lifetime.

object3D ​
ts
readonly object3D: Object3D;

The scene object. Add it to a scene, move it, parent it — it is an ordinary Object3D.

Methods ​

allocate() ​
ts
allocate(count): SlotRange;

Reserve a contiguous run of slots.

Parameters ​
ParameterTypeDescription
countnumberHow many gaussians.
Returns ​

SlotRange

The range, as { offset, count }.

free() ​
ts
free(range): void;

Give a range back. The slots are not cleared; call clearSlots first if the caller is not about to overwrite them.

Parameters ​
ParameterTypeDescription
rangeSlotRangeA range from allocate.
Returns ​

void

Nothing.

markGaussiansChanged() ​
ts
markGaussiansChanged(): void;

Tell the splat its gaussians moved, so the next frame re-sorts.

Call it once per frame after the compute pass. Without it the sort only runs when the camera turns more than about 1.81 degrees, and a moving avatar seen from a still camera renders in a stale depth order.

Returns ​

void

Nothing.

setBoundingSphere() ​
ts
setBoundingSphere(center, radius): void;

Declare where the gaussians are, in the object's local space.

The sort quantises depth into 4096 bins across this sphere, so a sphere that does not contain the splats costs precision, and frustum culling is off precisely because this value is a promise rather than a measurement.

Parameters ​
ParameterTypeDescription
centerVec3TupleLocal-space centre.
radiusnumberLocal-space radius.
Returns ​

void

Nothing.


SurfelKeyLightOptions ​

Options for estimateKeyLightFromSurfels.

Properties ​

elevationRange? ​
ts
readonly optional elevationRange?: readonly [number, number];

The elevation is kept inside this range, in degrees. Defaults to [25, 70].

minGroupLuminance? ​
ts
readonly optional minGroupLuminance?: number;

Groups darker than this mean luminance are ignored (black carries no shading). Defaults to 0.01.

minGroupSize? ​
ts
readonly optional minGroupSize?: number;

Groups with fewer samples are ignored. Defaults to 24.


SurfelSamples ​

The light a character's colours carry, one sample per gaussian.

Properties ​

count ​
ts
readonly count: number;

Samples.

groups? ​
ts
readonly optional groups?: ArrayLike<number>;

Which patch of the same material each sample belongs to (a body part and a colour), so a dark coat and a pale face are compared only with themselves. Defaults to one group.

luminance ​
ts
readonly luminance: ArrayLike<number>;

Linear luminance per sample.

normals ​
ts
readonly normals: ArrayLike<number>;

Outward unit normals, three per sample.

weights? ​
ts
readonly optional weights?: ArrayLike<number>;

Weight per sample (opacity). Defaults to 1.

Type Aliases ​

KeyLightRoute ​

ts
type KeyLightRoute = 
  | "game"
  | "light probe"
  | "panorama"
  | "place gaussians"
  | "character"
  | "default";

Which source decided the key light's direction.


ShadowQuality ​

ts
type ShadowQuality = "off" | "contact" | "simple" | "soft";

How much shadow to draw.


SplatFormat ​

ts
type SplatFormat = "spz" | "ply" | "splat" | "ksplat";

Container formats loadSplat understands.


SplatFormatOption ​

ts
type SplatFormatOption = SplatFormat | "auto";

SplatFormat, or 'auto' to sniff.


Vec3Tuple ​

ts
type Vec3Tuple = [number, number, number];

A centre as a plain triple, so producers need no three import.

Variables ​

BYTES_PER_GAUSSIAN ​

ts
const BYTES_PER_GAUSSIAN: number;

Bytes one gaussian occupies across the four storage buffers.


DEFAULT_KEY_LIGHT ​

ts
const DEFAULT_KEY_LIGHT: KeyLightEstimate;

The light used when nothing can be read: above and to the front-right of a character facing +z.


PACKAGE ​

ts
const PACKAGE: "@aosengine/splat";

Package identity marker.

Example ​

ts
import { PACKAGE } from '@aosengine/splat';

console.log(PACKAGE); // '@aosengine/splat'

SHADOW_QUALITIES ​

ts
const SHADOW_QUALITIES: readonly ShadowQuality[];

Every level, lowest first.


SPLAT_RENDER_ORDER ​

ts
const SPLAT_RENDER_ORDER: 1000 = 1000;

Splats draw after opaque geometry.

The material is transparent with depthWrite: false, so three already puts it in the transparent pass; the render order pins splats after ordinary transparent meshes, because a splat cloud has no single depth to sort by and would otherwise be interleaved by its object centre.


SUPPORTED_THREE_VERSION ​

ts
const SUPPORTED_THREE_VERSION: "0.186.0" = '0.186.0';

The three version this file's private-surface knowledge was written against.

Functions ​

acquireSplatGPUBuffers() ​

ts
function acquireSplatGPUBuffers(renderer, splat): SplatGPUBuffers;

Materialise a splat's four storage attributes as real GPUBuffers and hand them back.

Idempotent in both directions: createStorageAttribute early-returns when the buffer already exists, and the same GPUBuffer objects come back on every call for the lifetime of the splat. The buffers are owned by three — do not destroy them; dispose the splat.

Parameters ​

ParameterTypeDescription
rendererWebGPURendererAn initialised WebGPURenderer.
splatobjectA GaussianSplat or AnimatedGaussianSplat.

Returns ​

SplatGPUBuffers

The four buffers, in the layout documented at the top of this file.

Throws ​

When the backend is WebGL, the renderer is not initialised, or three's internals moved.

Example ​

ts
const buffers = acquireSplatGPUBuffers(renderer, splat);
console.log(buffers.center.size / 16); // gaussian capacity

acquireStorageGPUBuffer() ​

ts
function acquireStorageGPUBuffer(renderer, attribute): GPUBuffer;

Materialise one StorageBufferAttribute as a real GPUBuffer and hand it back.

For a producer that writes a buffer from its own compute pass which a three material then reads through storage(attribute, …) — a character's mouth writes its mesh this way. The same private surface as acquireSplatGPUBuffers, for any storage attribute. The buffer is owned by three; give it back with releaseStorageAttribute.

Parameters ​

ParameterTypeDescription
rendererWebGPURendererAn initialised WebGPURenderer.
attributeobjectA StorageBufferAttribute.

Returns ​

GPUBuffer

Its GPUBuffer, with STORAGE | COPY_DST usage.

Throws ​

When the backend is WebGL, the renderer is not initialised, or three's internals moved.

Example ​

ts
const attribute = new StorageBufferAttribute(new Float32Array(1024 * 4), 4);
const buffer = acquireStorageGPUBuffer(renderer, attribute);
device.queue.writeBuffer(buffer, 0, new Float32Array(1024 * 4));

anglesFromDirection() ​

ts
function anglesFromDirection(direction): [number, number];

Azimuth and elevation of a direction.

Parameters ​

ParameterTypeDescription
directionArrayLike<number>Any non-zero vector, y up.

Returns ​

[number, number]

[azimuth, elevation] in degrees.


clampElevation() ​

ts
function clampElevation(
   direction, 
   min, 
   max
): [number, number, number];

The same direction with its elevation held inside a range.

Parameters ​

ParameterTypeDescription
directionArrayLike<number>Unit direction.
minnumberLowest elevation, degrees.
maxnumberHighest elevation, degrees.

Returns ​

[number, number, number]

The adjusted unit direction.


createAnimatedSplat() ​

ts
function createAnimatedSplat(renderer, options): Promise<AnimatedSplat>;

Build a dynamic splat on an initialised renderer.

Asynchronous by contract rather than by need: acquiring the buffers is synchronous today, but the call sits on the boundary where a backend could have to be asked for something, and every caller already awaits.

Parameters ​

ParameterTypeDescription
rendererWebGPURendererAn initialised WebGPURenderer on the WebGPU backend.
optionsCreateAnimatedSplatOptionsCapacity, bounds and draw order.

Returns ​

Promise<AnimatedSplat>

The sink, with its GPU buffers already acquired.

Throws ​

When the renderer is not initialised or fell back to WebGL.

Example ​

ts
import { createAnimatedSplat } from '@aosengine/splat';

const sink = await createAnimatedSplat(renderer, {
  capacity: 250_000,
  boundingSphere: { center: [0, 1, 0], radius: 1.4 },
});
scene.add(sink.object3D);

const head = sink.allocate(120_000);
// ... compute pass writes sink.buffers.* over [head.offset, head.offset + head.count)
sink.markGaussiansChanged();

createEnvironmentProbe() ​

ts
function createEnvironmentProbe(
   scene, 
   renderer, 
   panorama, 
   options
): object;

Filter a caller-owned panorama for mesh IBL and scale its world-space Gaussian probe. Dispose restores the previous scene environment if this helper still owns it. The input texture remains caller-owned. No assets or network requests are created.

Parameters ​

ParameterTypeDescription
sceneSceneScene receiving mesh IBL.
rendererRendererInitialized engine renderer.
panoramaTextureLinear HDR equirectangular panorama.
optionsEnvironmentProbeOptionsProbe and matching mesh intensity/orientation.

Returns ​

object

Shared SH coefficients and idempotent cleanup.

radianceSH ​
ts
radianceSH: [number, number, number][];
dispose() ​
ts
dispose(): void;
Returns ​

void

Example ​

ts
const lighting = createEnvironmentProbe(engine.scene, engine.renderer, panorama, {
  radianceSH: probe.radianceSH, intensity: 0.95, yaw: probe.yaw,
});
splat.setEnvironmentLighting({ radianceSH: lighting.radianceSH });
// On shutdown: lighting.dispose(); panorama.dispose();

createLightProbeGrid() ​

ts
function createLightProbeGrid(data): LightProbeGrid;

Check a baked grid and build its sampler.

Parameters ​

ParameterTypeDescription
dataLightProbeGridDataThe parsed JSON.

Returns ​

LightProbeGrid

The sampler.

Throws ​

When the grid's sizes do not match its probes.


createSlotAllocator() ​

ts
function createSlotAllocator(capacity): SlotAllocator;

Build a slot allocator over capacity slots.

Parameters ​

ParameterTypeDescription
capacitynumberTotal slots. Must be a positive integer.

Returns ​

SlotAllocator

An allocator with one free run covering everything.

Example ​

ts
import { createSlotAllocator } from '@aosengine/splat';

const slots = createSlotAllocator(1000);
const head = slots.allocate(400);
console.log(head.offset, head.count); // 0 400
slots.free(head);
console.log(slots.available); // 1000

createSplatObject() ​

ts
function createSplatObject(asset, options?): AnimatedGaussianSplat | GaussianSplat;

Turn a decoded asset into a scene object.

Uses three's own GaussianSplat unless lighting or shadows are asked for; then the maintained fork, which on a real geometry takes upstream's own path (the same one-time repack) and only adds the switches.

Parameters ​

ParameterTypeDescription
assetSplatAssetA decoded asset.
optionsCreateSplatObjectOptionsSort behaviour and draw order.

Returns ​

AnimatedGaussianSplat | GaussianSplat

The object, with its bounds computed and its render order set.

Example ​

ts
const splat = createSplatObject(asset, { autoSort: true });
splat.position.y = -1;
scene.add(splat);

createSplatShadows() ​

ts
function createSplatShadows(
   renderer, 
   scene, 
   options?
): SplatShadows;

Start shadows for one scene. Nothing is drawn until a character is added; on the WebGL fallback everything is a no-op.

Parameters ​

ParameterTypeDescription
rendererWebGPURendererThe engine's renderer.
sceneObject3DThe scene the ground (when there is no place) is added to.
optionsSplatShadowsOptionsThe level, the ground switch and how fast a new light turns in.

Returns ​

SplatShadows

The shadows.


defaultShadowQuality() ​

ts
function defaultShadowQuality(hints?): ShadowQuality;

The level a device starts at: soft on a computer, simple on a phone, the contact shadow alone on a phone with 2 GB of memory or less.

Parameters ​

ParameterTypeDescription
hintsShadowDeviceHintsWhat is known about the device; the browser is asked for anything missing.

Returns ​

ShadowQuality

The level.


directionFromAngles() ​

ts
function directionFromAngles(azimuth, elevation): [number, number, number];

A unit direction from azimuth and elevation.

Parameters ​

ParameterTypeDescription
azimuthnumberDegrees around y from +z toward +x.
elevationnumberDegrees above the horizon.

Returns ​

[number, number, number]

The unit vector, y up.


estimateKeyLightFromPanorama() ​

ts
function estimateKeyLightFromPanorama(panorama, options?): KeyLightEstimate;

Find the key light in a 360° picture: the brightest compact region above the horizon.

The picture is reduced to at most 128 x 64, every direction above minElevation is scored by the light inside a narrow lobe around it (a 12° half-width), and the best is refined to the centroid of the light near it. The balance follows from irradiance: keyToFill compares a surface facing the key with one facing away, and shadowStrength is the key's share of the light on the surface facing it, the share its shadow takes away. An 8-bit picture clips a sun at white, so its key reads weaker than it was and the shadow comes out lighter.

Parameters ​

ParameterTypeDescription
panoramaPanoramaThe picture, three's equirectangular orientation.
optionsPanoramaKeyLightOptionsSearch limits.

Returns ​

KeyLightEstimate

The key light; confidence near 0 for an evenly lit (overcast) picture.


estimateKeyLightFromSH() ​

ts
function estimateKeyLightFromSH(sh, options?): KeyLightEstimate;

Read the key light from a light probe: nine radiance coefficients of the light arriving at one point, in three's SphericalHarmonics3 order, either nine RGB triples (the engine's radianceSH) or 27 flat numbers (a baked probe grid's sh).

The first band's direction is where the most light comes from; keyToFill compares the irradiance facing it with the irradiance facing away. A probe is smooth by nature: it finds the side the light comes from, not a small lamp's exact position.

Parameters ​

ParameterTypeDescription
sh| ArrayLike<number> | readonly readonly [number, number, number][]The probe.
options{ minElevation?: number; }The key is held no lower than minElevation degrees (default 20).
options.minElevation?number-

Returns ​

KeyLightEstimate

The key light; confidence near 0 for light that is the same from every side.


estimateKeyLightFromSurfels() ​

ts
function estimateKeyLightFromSurfels(samples, options?): KeyLightEstimate & object;

Find the light a character was captured under from its own colours.

The capture-lighting idea (brightness against surface normal) with one change that matters for a clothed person: within each group of samples of one material (one body part, one colour), brightness relative to the group's mean is fitted against the normal's offset from the group's mean normal, L / mean(L) - 1 = d . (n - mean(n)), so a dark coat on the back and a pale face on the front do not read as light from the front. The fitted d points at the key; its length is the key's strength against the ambient light.

Parameters ​

ParameterTypeDescription
samplesSurfelSamplesOne sample per gaussian: outward normal, luminance, weight and group.
optionsSurfelKeyLightOptionsGroup filters and the elevation range.

Returns ​

KeyLightEstimate & object

The key light in the samples' own space; confidence near 0 when the colours carry no shading.


getGPUDevice() ​

ts
function getGPUDevice(renderer): GPUDevice;

The one GPUDevice in the process — the renderer's.

AGENTS.md hard rule 7: nothing calls navigator.gpu.requestAdapter(). The device only exists after await renderer.init(), and the backend object is replaced when the renderer falls back to WebGL, so never cache either across init.

Parameters ​

ParameterTypeDescription
rendererWebGPURendererAn initialised WebGPURenderer.

Returns ​

GPUDevice

The device the renderer owns.

Throws ​

When the renderer is not initialised, or fell back to WebGL.

Example ​

ts
await renderer.init();
const device = getGPUDevice(renderer);
device.createShaderModule({ code });

initCountingSortPatch() ​

ts
function initCountingSortPatch(target?): boolean;

Patch CountingSort.prototype.compute so a sort is one renderer.compute([...]) call.

Idempotent. @aosengine/splat applies it from the splat() module's init, from createSplatObject and from createAnimatedSplat, so a game never has to; it is exported for hosts that build splats some other way.

Parameters ​

ParameterTypeDescription
target?objectPrototype to patch. Tests pass a fake; production never sets it.

Returns ​

boolean

True when the prototype carries the patch after the call.

Example ​

ts
import { initCountingSortPatch } from '@aosengine/splat';

initCountingSortPatch(); // before the first frame that sorts a splat

isCountingSortPatched() ​

ts
function isCountingSortPatched(target?): boolean;

Whether a prototype already carries the counting-sort patch.

Parameters ​

ParameterTypeDescription
target?objectPrototype to check. Defaults to CountingSort.prototype.

Returns ​

boolean

True when initCountingSortPatch has run against it.

Example ​

ts
import { initCountingSortPatch, isCountingSortPatched } from '@aosengine/splat';

initCountingSortPatch();
console.log(isCountingSortPatched()); // true

isWebGPUBackend() ​

ts
function isWebGPUBackend(renderer): boolean;

Whether this renderer got a real WebGPU backend rather than the WebGL fallback.

Parameters ​

ParameterTypeDescription
rendererWebGPURendererA renderer, initialised or not.

Returns ​

boolean

True for the WebGPU backend.

Example ​

ts
await renderer.init();
if (!isWebGPUBackend(renderer)) console.warn('static splats only');

loadSplat() ​

ts
function loadSplat(url, options?): Promise<SplatAsset>;

Fetch and decode a splat file.

Parameters ​

ParameterTypeDescription
urlstringSPZ, PLY, SPLAT or KSPLAT.
optionsLoadSplatOptionsFormat override, abort signal, custom fetch.

Returns ​

Promise<SplatAsset>

The decoded asset.

Throws ​

On a non-2xx response, an unrecognised format or a decoder failure.

Example ​

ts
import { createSplatObject, loadSplat } from '@aosengine/splat';

const asset = await loadSplat('/models/arena.spz');
scene.add(createSplatObject(asset));

panoramaFromGaussians() ​

ts
function panoramaFromGaussians(
   cloud, 
   at, 
   options?
): Panorama & object;

Draw a small panorama of a place's gaussians as seen from one point: each pixel takes the colour of the nearest surface in its direction (the front layer of gaussians), so a lamp behind a wall is not seen and a window beside the character is. Feed the result to estimateKeyLightFromPanorama; it is the place's light probe at that point.

Parameters ​

ParameterTypeDescription
cloudGaussianCloudThe place's gaussians.
atArrayLike<number>The probe point in world space (a character's chest height is a good one).
optionsGaussianPanoramaOptionsSize and filters.

Returns ​

Panorama & object

A linear RGB panorama, width x width / 2.


parseShadowQuality() ​

ts
function parseShadowQuality(value): "auto" | ShadowQuality | null;

Read a quality from untrusted text (a URL switch, a saved setting).

Parameters ​

ParameterTypeDescription
valuestring | null | undefinedThe text.

Returns ​

"auto" | ShadowQuality | null

The level, 'auto', or null when the text is neither.


parseSplat() ​

ts
function parseSplat(
   buffer, 
   url, 
   format?
): Promise<SplatAsset>;

Decode a buffer that has already been fetched.

Separated from loadSplat so tests can drive every decoder from memory, and so an asset pipeline that already holds the bytes does not fetch twice.

Parameters ​

ParameterTypeDefault valueDescription
bufferArrayBufferundefinedThe file.
urlstringundefinedWhere it came from, for sniffing and error messages.
formatSplatFormatOption'auto'Decoder to use, or 'auto'.

Returns ​

Promise<SplatAsset>

The decoded asset.

Example ​

ts
import { parseSplat } from '@aosengine/splat';

const asset = await parseSplat(bytes, 'arena.spz');
console.log(asset.count, asset.shDegree);

registerGltfSplatExtension() ​

ts
function registerGltfSplatExtension(gltfLoader): void;

Teach a GLTFLoader to read KHR_gaussian_splatting.

Register it before the first load; meshes carrying the extension then come back as GaussianSplat nodes inside the glTF scene graph. Their render order is not set for you, because the glTF author owns that graph — walk the result and set SPLAT_RENDER_ORDER if splats are interleaving with your transparent meshes.

Parameters ​

ParameterTypeDescription
gltfLoaderGltfLoaderLikeThe loader to extend.

Returns ​

void

Nothing.

Example ​

ts
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { registerGltfSplatExtension } from '@aosengine/splat';

const loader = new GLTFLoader();
registerGltfSplatExtension(loader);
const gltf = await loader.loadAsync('/models/scene.glb');

releaseStorageAttribute() ​

ts
function releaseStorageAttribute(renderer, attribute): boolean;

Destroy the GPUBuffer behind one storage attribute.

The counterpart to acquireSplatGPUBuffers, and the reason this file exists: three creates a storage attribute's buffer through backend.createStorageAttribute and destroys it through backend.destroyAttribute, and neither is reachable from the public API. BufferAttribute.dispose() only dispatches a dispose event, which Geometries.js listens for on vertex and index attributes but never on storage ones — so without this call every disposed dynamic splat leaks its buffers for the lifetime of the page.

Safe to call more than once and on an attribute that was never uploaded: it returns false rather than letting destroyAttribute dereference a missing buffer.

Parameters ​

ParameterTypeDescription
rendererWebGPURendererThe renderer that materialised the attribute.
attributeobjectA StorageBufferAttribute (or any BufferAttribute).

Returns ​

boolean

True when a GPU buffer was destroyed.

Example ​

ts
for (const attribute of splat.storageAttributes()) releaseStorageAttribute(renderer, attribute);

shadowQualityPreset() ​

ts
function shadowQualityPreset(quality): ShadowQualityPreset;

What a quality level draws.

Parameters ​

ParameterTypeDescription
qualityShadowQualityThe level.

Returns ​

ShadowQualityPreset

Its map size, filter and contact switch.


sniffSplatFormat() ​

ts
function sniffSplatFormat(url, bytes): SplatFormat;

Guess the container format from the URL and the first bytes.

The extension wins when it is one we know, because .ksplat has no magic number and .splat has no header at all. Content sniffing is the fallback, and it can only recognise the two formats that are self-describing: SPZ (gzip, or NGSP for v4) and PLY (ply\n).

Parameters ​

ParameterTypeDescription
urlstringThe URL the bytes came from. Query and hash are ignored.
bytesUint8ArrayAt least the first 8 bytes of the file.

Returns ​

SplatFormat

The format.

Throws ​

When neither the extension nor the content identifies it.

Example ​

ts
import { sniffSplatFormat } from '@aosengine/splat';

sniffSplatFormat('/models/arena.spz', new Uint8Array(8)); // 'spz'

splat() ​

ts
function splat(options?): EngineModule;

The splat EngineModule.

Registers the splat asset type, so { "id": "arena", "type": "splat", "src": "arena.spz" } in assets.json resolves to a SplatAsset, and publishes a small service for putting one in the scene.

Parameters ​

ParameterTypeDescription
optionsSplatModuleOptionsOptional format override.

Returns ​

EngineModule

The module, to be passed in createEngine({ modules }).

Example ​

ts
import { createEngine } from '@aosengine/core';
import { splat } from '@aosengine/splat';

const engine = await createEngine({ canvas, manifest: '/assets.json', modules: [splat()] });
engine.get('splat').add('arena');
engine.start();

strengthOf() ​

ts
function strengthOf(keyToFill): number;

How dark a shadow of the key is: the key's share of the light on a surface facing it.

Parameters ​

ParameterTypeDescription
keyToFillnumberKey over fill, 1 or more.

Returns ​

number

0 to 0.9.