SDK JS
    Preparing search index...

    Module @bitruvius/turbo-spz

    @bitruvius/turbo-spz — browser SPZ (Niantic gaussian-splat) decode via a pure-Rust turbospz wasm. Decode-only.

    Three entry points:

    • SpzDecoder decodes a standalone .spz file (all versions v1–v4) to a flat SpzGaussianCloud.
    • SpzContainerDecoder adapts a standalone .spz file to the quantized streaming Decoder contract in @bitruvius/geo-core, so BVC-style splat layers render it through the same SplatRenderer path as any other container.
    • SpzGltfSplatDecoder / WorkerSpzGltfSplatDecoder decode a whole 3D-Tiles .glb gaussian-splat tile (KHR_gaussian_splatting, …_spz_2), satisfying the codec-agnostic GltfSplatDecoder seam in @bitruvius/geo-core so @bitruvius/tiles3d streams Esri/Cesium splat tilesets without depending on this package directly.

    Bitruvius

    @bitruvius/turbo-spz

    SPZ Gaussian splats, decoded in the browser faster than libspz.

    SPZ is the open compression format Niantic published for 3D Gaussian splats. TurboSPZ is an independent pure-Rust decoder for it, compiled to WebAssembly with SIMD128. It reads every SPZ version libspz reads: v1, v2, v3 and v4, with the legacy gzip framing detected from the magic bytes rather than configured by you.

    Turbocharged by Bitruvius TurboSPZ.

    Browser decode throughput, turbospz-wasm against Niantic libspz, both compiled to WASM SIMD128, decoding the same file per version.

    SPZ version Format turbospz-wasm libspz Speedup
    v2 gzip (legacy) 1078 MiB/s 595 MiB/s 1.81× faster
    v3 gzip (legacy) 1007 MiB/s 568 MiB/s 1.77× faster
    v4 zstd (current) 1078 MiB/s 847 MiB/s 1.27× faster

    SH degree 3, scene-averaged over hornedlizard (786K splats) and racoonfamily (933K splats). Higher is faster.

    One codebase, one answer. AVX2, NEON, WASM SIMD128 and a scalar fallback all produce byte-identical output. This package ships the WASM SIMD128 path, so a capture decoded in a phone browser matches the same file decoded by the native TurboSPZ tools on a workstation.

    Memory-safe by construction. Pure Rust, zero unsafe in the consumer libraries, and no emscripten anywhere in the build.

    import { SpzDecoder } from '@bitruvius/turbo-spz';

    const bytes = new Uint8Array(await (await fetch('scene.spz')).arrayBuffer());
    const cloud = await new SpzDecoder().decode(bytes);
    // cloud.numPoints, cloud.shDegree, then flat Float32Arrays:
    // positions (3N), scales (3N), rotations (4N), alphas (N), colors (3N), sh

    Reuse one decoder across many files. The wasm is a lazily initialized singleton, so only the first decode on the page pays the init cost.

    The arrays arrive as the container stores them, not as your shader wants them. Three conversions stand between decode and a correct render:

    scale = Math.exp(logScale);              // scales ship as logs
    color = 0.5 + 0.28209479177387814 * dc; // SH degree-0 DC to straight colour
    alpha = 1 / (1 + Math.exp(-a)); // alphas are opacity logits

    Opacity is the one that bites. Get it wrong and the scene renders uniformly near-opaque or near-invisible, with no error to tell you why.

    SpzGltfSplatDecoder and WorkerSpzGltfSplatDecoder decode whole 3D Tiles Gaussian-splat tiles (KHR_gaussian_splatting), which is how Esri and Cesium splat tilesets stream. The worker variant fans tiles out to a pool so the entropy decode never blocks your render thread. You rarely wire it up yourself: a splat layer in @bitruvius/sdk-maplibre uses it by default.

    import { Tiles3DSplatLayer } from '@bitruvius/sdk-maplibre';

    map.addLayer(new Tiles3DSplatLayer({ id: 'splats', url: tilesetUrl }));

    SpzContainerDecoder adapts a standalone .spz file to the SDK's streaming decoder contract, so a raw capture renders through the same pipeline as any other Bitruvius container.

    npm i @bitruvius/turbo-spz
    

    A self-contained ESM bundle is published on the Bitruvius CDN if you would rather skip the bundler entirely. In production, pin an exact version, add integrity= from the release manifest, and allow script-src 'wasm-unsafe-eval' in your CSP.

    This package decodes. It does not encode. There is no encoder in the package and none inside the .wasm. The decoder is free: anyone who needs to read SPZ data can pull it and ship it inside their application, under LICENSE. The TurboSPZ encoder is licensed separately: see bitruvius.com/turbo-spz for its benchmarks and licensing terms.

    Niantic and SPZ are trademarks of Niantic, Inc. Esri and ArcGIS are trademarks of Environmental Systems Research Institute, Inc. Cesium and 3D Tiles are trademarks of Cesium GS, Inc. Khronos and glTF are trademarks of The Khronos Group Inc. MapLibre is a trademark of the MapLibre organization. All other marks are the property of their respective owners.

    These names are used solely to describe the data formats this software interoperates with. Bitruvius is not affiliated with, sponsored by, or endorsed by any of them, and no such relationship is implied.

    TurboSPZ is an independent implementation of the openly published SPZ format, developed by Bitruvius and verified against Niantic's libspz reference, which Niantic releases under the MIT license. It is neither produced nor endorsed by Niantic, and compatibility claims describe interoperability with the format as verified by our test suites, not any form of certification.

    Proprietary. The full terms ship as LICENSE inside this package, and are readable before installing at cdn.bitruvius.com/legal/sdk-license-v1.txt.

    © Bitruvius, Inc.

    Classes

    SpzContainerDecoder
    SpzDecoder
    SpzGltfSplatDecoder
    WorkerSpzGltfSplatDecoder

    Interfaces

    SplatKeepMask
    SpzContainerDecoderOptions
    SpzDecoderOptions
    SpzGaussianCloud
    SpzGltfSplatDecoderOptions
    WasmHostInit
    WorkerSpzGltfSplatDecoderOptions

    Functions

    computeStrayMask
    quantizeSpzCloud