UNPKG

@playcanvas/splat-transform

Version:

Library and CLI tool for 3D Gaussian splat format conversion and transformation

116 lines (115 loc) 5.11 kB
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 };