Skip to main content

Gaussian splat data and shading

Source columns and rendering

SplatSource contains framework-independent, decoded typed arrays. Positions and linear one-standard-deviation scales are packed XYZ Float32Array values; rotations are packed [w, x, y, z] quaternions; colors are normalized RGBA Uint8Array values or linear RGBA Float32Array values; and opacities are linear Float32Array values. Floating-point colors preserve high-dynamic-range spherical-harmonic DC radiance, including values above one and below zero, until rendering. Prepared GPU columns use the float32x3, float32x4, unorm8x4, and float32 memory formats provided by @luma.gl/gpgpu/gpu-data.

SplatRenderer supports none, global, and tile depth-ordering modes alongside camera matrix, viewport, radius, opacity, and visibility controls; GPUSplatGraphRenderer always uses global GPU ordering. WebGPU uses GPU-ready splat buffers and WGSL; WebGL2 uses an attribute-backed GLSL fallback. Both renderers support higher-order directional radiance, semantic filtering, dedicated GPU picking, and mixed mesh composition through their corresponding interaction helpers. When globally sorted source batches are densely interleaved, SplatRenderer bounds draw-call growth by grouping rows into depth-ordered batch runs without changing or repacking their source buffers.

The exposure property scales linear color before display mapping. Floating-point source colors automatically enable Reinhard highlight compression on standard dynamic range targets; set toneMapping to 'none' or 'reinhard' to override the automatic choice. On a WebGPU canvas configured with rgba16float and extended tone mapping, the renderer preserves unclamped positive radiance for the presentation target instead of applying SDR highlight compression.

Higher-order spherical harmonics

Supply sphericalHarmonics as a row-major Float32Array containing non-DC coefficients in basis-major RGB triplets. Degrees one, two, and three require 9, 24, and 45 scalar coefficients per source row. Set sphericalHarmonicsDegree explicitly or let preparation infer it from the coefficient count. The existing color column contains the already reconstructed DC radiance.

const prepared = makeGPUSplatData(device, {
positions,
scales,
rotations,
colors,
opacities,
sphericalHarmonics: new Float32Array(rowCount * 24),
sphericalHarmonicsDegree: 2
});

const renderer = new SplatRenderer(device, {
data: prepared,
cameraPosition: [cameraX, cameraY, cameraZ],
sphericalHarmonicsDegree: 2
});

WebGPU evaluates the directional coefficients directly from source-owned storage buffers in either the standard renderer or the reusable graph feature pass. The WebGL2 fallback evaluates directional radiance into a renderer-owned color buffer without changing the original source colors. Changing cameraPosition refreshes directional colors independently from source ownership.

Semantic filtering and dynamic updates

Provide semanticIds: Uint32Array with one compact class identifier per source row. Configure semanticFilter with included or excluded IDs, an includeUnlabeled policy, or a predicate that receives the stable global row and source-batch identity. Arrow semantic columns must contain finite unsigned 32-bit integer identifiers; nulls, string labels, fractions, and out-of-range values are rejected. Omit the column entirely for an unlabeled source batch.

renderer.setProps({
semanticFilter: {
include: [3, 7],
exclude: [11],
predicate: (semanticId, rowIndex, sourceBatchIndex) => rowIndex !== hiddenRow
}
});

prepared.updateRows(12, {
positions: new Float32Array([nextX, nextY, nextZ]),
semanticIds: new Uint32Array([7]),
opacities: new Float32Array([0.9])
});

Updates preserve buffer identities, source-batch boundaries, and stable row indices. Borrowing renderers detect the prepared batch's revision and refresh visibility, sorting, semantic masks, or directional colors as needed.