@playcanvas/splat-transform
Version:
Library and CLI tool for 3D Gaussian splat format conversion and transformation
116 lines (115 loc) • 5.11 kB
TypeScript
import { DataTable } from '../data-table';
import { type CameraBasis, type Projection } from './camera';
import { RadixSortScratch } from '../spatial/radix-sort';
/**
* Number of SH coefficients per color channel for the scene's SH band
* count. Matches the `f_rest_*` layout in DataTable (channel-major).
*
* @param bands - 0–3.
* @returns Coefficient count per channel.
*/
declare const numSHCoeffsPerChannel: (bands: number) => number;
/**
* Floats per gaussian in the chunk input buffer that gets uploaded to the
* GPU project shader. Layout:
* [0..2] pos.xyz
* [3..6] rot.w, rot.x, rot.y, rot.z (rot_0..rot_3)
* [7..9] log_scale.xyz
* [10] opacity (logit)
* [11..13] f_dc.rgb
* [14..14+3·N-1] SH coefficients, channel-major: R[0..N-1], G[0..N-1], B[0..N-1]
*
* @param numSHBands - 0–3.
* @returns Per-gaussian stride in 32-bit floats.
*/
declare const splatInputStride: (numSHBands: number) => number;
/**
* Reusable scratch for `sortCandidatesByDepth`. Bundles the parallel-keys
* Float32 depth buffer with the shared `RadixSortScratch`. One instance is
* created per render in the orchestrator and reused across every group's
* sort to avoid allocating multi-MB typed arrays on every call. Buffers
* grow on demand and never shrink.
*/
declare class SortScratch {
/** Float32 depths in candidate order; parallel to the indices being sorted. */
depth: Float32Array;
/** Shared radix-sort working buffers. */
radix: RadixSortScratch;
constructor();
ensure(count: number): void;
}
/**
* Sort `candidateIndices[0..count)` by view depth ascending
* (front-to-back) so chunked dispatches process splats in correct blend
* order. Mutates `candidateIndices` in place.
*
* Depth metric depends on the projection. Pinhole uses
* `forward · (pos − eye)` (camera-space z). Equirect uses radial
* distance `‖pos − eye‖` — the natural front-to-back ordering for a
* spherical projection, since "in front of" is defined per direction
* rather than per camera-z plane. Delegates the actual sort to the
* shared `radixSortIndicesByFloat`, providing depths as the parallel
* Float32 keys.
*
* @param cols - Pre-resolved column references (only `x`, `y`, `z` are read).
* @param candidateIndices - Indices into dataTable rows (mutated).
* @param count - Number of valid entries.
* @param camera - Camera basis (forward used for pinhole, eye for both).
* @param projection - Projection mode; selects the depth metric.
* @param scratch - Reusable scratch buffers, grown on demand.
*/
declare const sortCandidatesByDepth: (cols: SplatColumnRefs, candidateIndices: Uint32Array, count: number, camera: CameraBasis, projection: Projection, scratch: SortScratch) => void;
/**
* Cached typed-array references for the columns that `packChunkInput`
* reads. Built once per render in the orchestrator and reused across
* every group/chunk to avoid `getColumnByName` lookups and the SH-rest
* array allocation on the hot path.
*/
type SplatColumnRefs = {
x: Float32Array;
y: Float32Array;
z: Float32Array;
rotW: Float32Array;
rotX: Float32Array;
rotY: Float32Array;
rotZ: Float32Array;
scaleX: Float32Array;
scaleY: Float32Array;
scaleZ: Float32Array;
opacity: Float32Array;
fdcR: Float32Array;
fdcG: Float32Array;
fdcB: Float32Array;
/** Channel-major SH coefficients: indices `[0..N-1]` red, then green, then blue. Empty when `numSHBands === 0`. */
shRest: Float32Array[];
};
/**
* Resolve the typed-array references for every column `packChunkInput`
* touches. Call once per render; reuse the result across all chunks.
*
* @param dataTable - Source splat data.
* @param numSHBands - Scene's SH band count (0–3).
* @returns Cached column references.
*/
declare const getSplatColumnRefs: (dataTable: DataTable, numSHBands: number) => SplatColumnRefs;
/**
* Pack a chunk's raw splat fields into a flat Float32Array suitable for
* upload to the GPU project shader. The layout matches `splatInputStride`.
*
* @param cols - Pre-resolved column references (build once via `getSplatColumnRefs`).
* @param chunkIndices - Indices into dataTable for this chunk's splats.
* @param chunkStart - Offset into `chunkIndices` where the chunk begins.
* @param chunkSize - Number of splats in this chunk.
* @param numSHBands - Scene's SH band count (0–3).
* @param out - Output buffer, length ≥ `chunkSize · stride`.
*/
declare const packChunkInput: (cols: SplatColumnRefs, chunkIndices: Uint32Array, chunkStart: number, chunkSize: number, numSHBands: number, out: Float32Array) => void;
/**
* Convenience: derive the scene's SH band count from the DataTable's
* `f_rest_*` columns. Used by the renderer to size the input stride.
*
* @param dataTable - Splat data.
* @returns SH band count clamped to 0–3.
*/
declare const sceneSHBands: (dataTable: DataTable) => 0 | 1 | 2 | 3;
export { splatInputStride, numSHCoeffsPerChannel, sortCandidatesByDepth, SortScratch, getSplatColumnRefs, packChunkInput, sceneSHBands, type SplatColumnRefs };