Skip to main content

SPZ 4 is here: leaner, faster, and more future-proof

Date:5/5/2026
Author:Niantic Spatial
Categories:
Featured News
Research

SPZ 4 is here: leaner, faster, and more future-proof

When we open-sourced SPZ in late 2024, we described it as "JPG for 3D Gaussian splats": a single, sensible format that made splats roughly 10x smaller than PLY and easy to share anywhere. Since then, Adobe Photoshop users alone have created roughly 800,000 SPZ files in the last two months. The format is now deployed across web environments, real-time engines, robotics pipelines, and mobile platforms – in scenes far larger and more complex than the original implementation was built for.

Today, we are releasing SPZ 4: an evolution of the format that preserves its core design principles while extending its capabilities to support significantly larger, more demanding datasets.

Previous versions of SPZ made it practical to share Gaussian splats directly from mobile devices, establishing a compact, portable format that enabled broad adoption. Subsequent releases focused on maturing the format: improving compression efficiency, stabilizing the specification, and expanding compatibility across rendering engines, web pipelines, and downstream systems.

SPZ 4 addresses the scale and complexity of current workloads, supporting captures with tens of millions of points and introducing a more robust data model where critical metadata is embedded within the file itself, rather than managed externally.

Bigger scenes, faster encoding

SPZ 4 compresses about 3-5x faster, loads roughly 1.5-2x faster end-to-end, still produces files that are 10x smaller than uncompressed PLYs, and gives developers new controls over the quality so the same format can serve both maximum-fidelity and maximum-efficiency workflows. The single biggest change in SPZ 4 is how the file gets compressed. The original SPZ wrapped the entire payload in a single GZip stream. That worked beautifully for the splats most people were producing in 2024 (a few hundred thousand points off a phone scan), but it meant compression and decompression were stuck on a single CPU core. Multi-million-point captures just take too long.

SPZ 4 replaces GZip with six parallel ZSTD streams, one per attribute (positions, colors, scales, rotations, alphas, spherical harmonics). Each attribute is its own independently-compressed buffer, with a small table of contents up front so the parser/loader can quickly determine the size and layout of each compressed attribute stream (positions, colors, etc.) without having to decompress or scan the file first. Encode and decode now scale across cores.

The result, from a benchmark on an 8.5 GB / 34M-point PLY:

Format

Encode Time

File Size vs. Baseline

SPZ3 (baseline)

3 min 26 sec

-

SPZ4

1 min 8 sec (3x faster)

2.5% smaller

You can get smaller files and much faster encoding, with full CPU utilization across cores. Decoding parallelizes the same way. We also removed the old 10-million-point cap on the PLY loader and on the SPZ deserializer. SPZ 4 happily handles tens of millions of gaussians without complaint.

The speedup shows up downstream too. Time-to-render (decompress plus load into the renderer) with parallel decoding drops noticeably (~33–52% faster, or roughly 1.5x to 2.1x) across our test scenes:

Benchmark Scene

Points

v2/v3 size

v4 size

TTR v2/v3

TTR v4

Scene A

3.6M

66.2MB

65.7MB

1,264ms

844ms

Scene B

7.1M

254MB

128MB

3,450ms

1,660ms

Scene C

2.6M

39.3MB

40.5MB

958ms

619ms

Scene D

1.0M

20.7MB

18.9MB

364ms

238ms

Scene E

2.6M

118.5MB

65.1MB

1,375ms

657ms

A plaintext header

SPZ 4 puts the 32-byte file header in plaintext at a fixed offset, outside the compressed region. That means you can inspect a file's point count, SH degree, version, and flags without decompressing a single byte of payload data.

Files now begin with the magic bytes NGSP rather than the original GZip magic. The loader sees the first four bytes and dispatches to the right path, so old SPZ v2/v3 files still load fine via a fallback path. Old loaders that encounter a v4 file fail fast with an unrecognized-format error rather than crashing or producing garbled splats.

A real extension system

The other big architectural change in SPZ 4 is extensions. The original format was deliberately rigid (one degree of compression, one parameter layout, no room to wiggle) because we wanted it to be a universal lowest common denominator. As SPZ use has expanded beyond its initial scope, that rigidity became limiting. SPZ 4 introduces controlled extensibility, allowing new attributes and metadata to evolve within the format without breaking interoperability.

The mechanism is an opt-in vendor extension chain. Each record carries a vendor-tagged ID, a length field, and a payload, which means unknown extensions can be safely skipped, and multiple vendors can coexist in the same file without stepping on each other. Extensions are disabled by default; you opt in via PackOptions. Files without extensions look identical to baseline SPZ, so older readers keep working.

The first extension comes from Adobe, who drove much of the architecture:

  • 0xADBE0002 Safe Orbit Camera stores recommended elevation and radius bounds for orbit-style camera controls, so splat viewers don't have to guess how to frame and navigate the scene.

Vendor ID allocation is documented in extensions/README.md. We expect more extensions to follow; if you're thinking of adding one, the README is the place to start.

Better-looking splats, on your terms

SPZ 4 raises the ceiling on what splats can look like, and gives developers room to choose where on the quality curve they want to sit.

Configurable spherical harmonics quantization. The SH coefficients are what give a splat its view-dependent appearance: how light reflects off a surface, how a highlight moves as you orbit the camera, how much a material looks glossy versus matte. They're also one of the largest contributors to file size. You can tune the same scene for a maximum-fidelity archival render or a maximum-efficiency mobile viewer without reauthoring the splat. Internal testing showed an 18x compression ratio at 3 bits and essentially-zero MSE at 8 bits, with 5 bits being the sweet spot for most scenes.

Higher-fidelity splats with SH degree 4. Earlier SPZ versions topped out at SH degree 3, which covers most phone-captured splats but isn't enough for pipelines that produce more sharply view-dependent surfaces. SPZ 4 adds support for SH degree 4, so these higher-order splats round-trip through the format without losing the lighting detail they were generated with.

Together, these mean SPZ 4 is the first version of the SPZ format with a configurable quality dial.

SPZ at scale with Adobe

SPZ is increasingly the connective tissue for Gaussian splats across major creative and developer tools. Adobe has made SPZ central to its 3D toolchain – most recently shipping Photoshop's new Rotate Object feature, which lets users rotate 2D images in 3D space and gained traction immediately at launch. SPZ is the transacting format behind this capability, putting it in the path of millions of users.

Faster on the web and a growing ecosystem

A lot of SPZ usage now happens in the browser, through our Emscripten/WASM build. Alongside the SPZ 4 format release, the reference library ships a rebuilt WASM/TypeScript binding layer with proper TypedArray views over the gaussian data, plus a generated spz.d.ts for editor autocomplete. Loading SPZ files in the browser is also up to 20x faster. SPZ 4 adds Emscripten bindings for the C++ to JavaScript layer, delivering meaningful performance gains for web-based workflows.

The web ecosystem around SPZ is also expanding. Adobe recently extended SPZ support in Babylon.js, making it easier to load and render SPZ assets directly in web-based 3D pipelines.

A web tool for inspecting and converting splats

Alongside the library release, we're shipping a small WASM-powered web tool for working with splat files at nianticspatial.com/spz-converter. Drop a .spz or .ply file onto the page and it shows you the header, point count, SH degree, stream layout, and bounding box, then lets you convert between formats or export the metadata as JSON. Everything runs locally in the browser.

Backwards compatibility

A quick summary of what reads what:

  • SPZ 4 reads everything. Old SPZ v2/v3 files load fine via the legacy path.

  • Old loaders cannot read SPZ 4 files. They'll see the new NGSP magic and fail gracefully by reporting an unrecognized format.

  • Files without extensions appear as standard SPZ to loaders that do not implement or recognize extensions.

Breaking forward-compat with old readers is not a decision we make lightly. But the encoding speedups, the parallel decoding, the plaintext header, and the room to grow added up to a clear yes.

What's next

The architectural changes in v4 unlock future improvements. A few of the directions on our radar for v5:

  • Streaming and progressive loading.

  • Better SH quantization.

  • Spatial chunking and LOD.

  • More vendor extensions.

If you have ideas you'd like to see explored, please open an issue on the repo to start a discussion, or send a pull request if you've already prototyped something. The best parts of SPZ have come from people pushing on it from the community.

Get started with SPZ 4

There are a few easy ways in, depending on what you're trying to do:

If you just want to compress a PLY or look inside an SPZ file, head to nianticspatial.com/spz-converter and drop a file onto the page. No install, no signup, no upload. You'll get a header readout in seconds, and one-click conversion between .ply and .spz v4.


Source file

Drop a file here or click to browse

We'll detect the format and show the right actions.

.spz.ply
Private by design. Parsing, conversion, and compression run entirely in WebAssembly on this device. No data is sent to any server.

No file loaded

Drop a splat file on the left to inspect its properties and convert it.

DropInspectConvert
Note: This tool exports files in the new SPZ v4 format. The format is 3–5× faster to encode, smaller, and supports extensions, but only readers running the latest SPZ library can load these files. Older v2/v3 readers will report an unrecognized format. Developers can update at github.com/nianticlabs/spz.

If you want to integrate SPZ into your app, the library is on GitHub at github.com/nianticlabs/spz. For C++ projects, clone the repo and link against the core library. For Python, pip install from the repo gives you the bindings. For the web, the WASM build with TypeScript definitions is also there. For most existing integrations SPZ 4 is a drop-in upgrade: pull main, and your existing load/save calls keep working, with writes now producing v4 by default.

We'll be adding SPZ 4 exports to Scaniverse within a few months. We encourage anyone developing an app that imports SPZ to join us in this timeline so we can advance together.

If you want to contribute code, we welcome pull requests. Bug fixes and platform-specific build improvements are quickly incorporated; for larger changes (new extensions, format-level tweaks, performance work) please open an issue first to talk through the design. The extensions/README.md file documents the vendor ID allocation scheme if you're thinking of adding your own extension. Good first PRs include build improvements, integration guides for popular renderers, and tooling around the web utility.

A big thank you to everyone who made this release happen, especially the team at Adobe, who drove the extension architecture and a great deal of the WASM work, and to the community members who filed issues, ran benchmarks, pushed back on early designs, and provided the feedback that allows us to build better together. SPZ has always been better when more people are looking at it.

If you've been waiting to put bigger scenes, faster web viewers, or your own metadata into SPZ, go pull the latest. We can't wait to see what you build.

Share: