Skip to content

Add SPZ gaussian splat format support via external parser#9018

Merged
mvaligursky merged 3 commits into
mainfrom
mv-spz-format
Jul 3, 2026
Merged

Add SPZ gaussian splat format support via external parser#9018
mvaligursky merged 3 commits into
mainfrom
mv-spz-format

Conversation

@mvaligursky

@mvaligursky mvaligursky commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Adds support for loading gaussian splats from SPZ files (version 4), implemented as an external parser script rather than engine code, using the parser registry on the gsplat resource handler.

Changes:

  • scripts/esm/gsplat/spz-parser.mjs - SpzParser which applications register via app.loader.getHandler('gsplat').addParser(new SpzParser(app)). The parser reads the SPZ v4 (NGSP) container directly and keeps the splat data in its quantized form in GPU textures (~20 bytes per splat plus optional spherical harmonics), dequantizing it in the shader - similar to the compressed PLY and SOG formats. Supports 0-3 SH bands (degree 4 files are clamped to 3 bands), and both GLSL and WGSL.
  • The ZSTD compressed attribute streams are decompressed using a wasm module the application registers draco-style:
    pc.WasmModule.setConfig('ZstdDecoderModule', {
        glueUrl: 'zstd.wasm.js',
        wasmUrl: 'zstd.wasm.wasm'
    });
    The decoder (zstd's single-file zstddeclib compiled to wasm, 54kB) is vendored into examples/assets/wasm/zstd/ with provenance and licenses documented in the wasm assets README.
  • No engine changes - the parser builds on the public GSplatResourceBase / GSplatFormat API.

Examples:

  • The gaussian-splatting/viewer example now accepts dropped .spz files (loaded with +Y up, no flip rotation).
  • New gaussian-splatting/simple-spz example, loading the biker asset converted to spz v4 (2.1MB vs 2.5MB compressed ply). Verified on WebGL2 and WebGPU, with spherical harmonics additionally verified using an SH3 test asset.

Adds a parser for the SPZ format (https://github.com/nianticlabs/spz),
version 4, implemented outside the engine as a script
(scripts/esm/gsplat/spz-parser.mjs) and registered with the gsplat
resource handler by the application.

The splat data is kept in its quantized form on the GPU (~20 bytes per
splat plus spherical harmonics) and dequantized in the shader, similar
to the compressed PLY and SOG formats. The ZSTD compressed attribute
streams are decompressed using a wasm module registered draco-style via
pc.WasmModule, with the decoder vendored into examples assets.

Includes a new gaussian-splatting/simple-spz example with the biker
asset converted to spz v4.
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

Build size report

This PR does not change the size of the minified bundles.

Bundle Minified Gzip Brotli
playcanvas.min.js 2272.9 KB — 585.6 KB — 455.3 KB —
playcanvas.min.mjs 2270.3 KB — 584.6 KB — 454.8 KB —

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant