Skip to content

Gaussian splat file formats: .ply, .spz, .splat and .ksplat

By Atlas World Model EditorialUpdated 5 min read

Key facts

.ply per splat248 bytes (62 float32)(as of 2026-09-05)source
.splat per splat32 bytes (quantised)(as of 2026-09-05)source
.spz sizeAbout 10x smaller than .ply(as of 2026-09-05)source
Marble exports.ply and .spz splats(as of 2026-09-05)source

A one-million-splat scene is 248 MB as a .ply, about 25 MB as a .spz, and 32 MB as a .splat. Same scene, same splat count, three very different files. This guide explains what each format stores and what it discards, so you can pick one without guessing. Everything here applies to worlds exported from Marble, and is expected to apply to Atlas exports when access opens.

What a splat actually contains

3D Gaussian Splatting represents a scene as millions of anisotropic 3D Gaussians, each carrying position, scale, rotation, opacity and view-dependent colour (Kerbl et al., SIGGRAPH 2023). In the reference implementation each splat stores:

AttributeValuesPurpose
Position3Where the splat sits in world space
Normal3Unused, kept for PLY compatibility
SH degree 0 (f_dc)3Base colour
SH degrees 1–3 (f_rest)45View-dependent colour
Opacity1Alpha before blending
Scale3Ellipsoid size on each axis
Rotation4Quaternion orientation

That is 62 float32 values, 248 bytes per splat. The 45 spherical-harmonic coefficients are 72 percent of the file, and they exist so a surface can change colour as you orbit it: the sheen on a table, the highlight sliding across a car. Every format below is essentially a different answer to the question “how much of that can we throw away?”

.ply — the training output

The .ply produced by the Inria implementation is a binary little-endian point cloud with the 62 properties above, one row per splat (reference implementation). It is the format most trainers write and most tools read.

Use it when you plan to retrain, prune, re-edit or convert. Do not ship it to a browser: 248 MB over a mobile connection is not a page, it is a download.

One caveat worth knowing: .ply is a container, not a splat format. A generic PLY point cloud from photogrammetry has the same extension and will open in a mesh tool but not in a splat viewer, because the splat-specific properties are missing. If a file fails to load, check for the f_dc_0 and scale_0 properties before blaming the viewer.

.spz — the one to ship

Niantic’s .spz is an open-source compressed splat format, roughly 10x smaller than the equivalent .ply (nianticlabs/spz). It gets there by quantising rather than by dropping splats: positions become fixed-point integers, scales and rotations become small integers, and the spherical-harmonic coefficients are quantised hardest because that is where the bytes are. The result is gzipped.

The compression is lossy and tuned so the loss is invisible at normal viewing distances. For distribution that trade is almost always correct: a 25 MB world starts rendering while a 248 MB one is still downloading. World Labs exports Marble worlds as .spz for exactly this reason (World Labs docs).

Keep the original .ply in cold storage anyway. Quantisation is one-way, and if you later want to retrain or run a cleanup pass you want the float32 original, not a decompressed approximation of it.

.splat — the 32-byte web format

The .splat format from antimatter15 packs each splat into exactly 32 bytes: three float32 for position, three float32 for scale, four bytes of RGBA colour and four bytes of quaternion. That is 32 MB per million splats, with no container and no header to parse.

The trade is explicit: colour is a single RGBA value, so all view-dependent shading is gone. Scenes lose their highlights and read slightly flatter, which matters for a glossy product shot and does not matter for a matte interior. In exchange, decoding is a memory copy, which is why the format spread through web viewers before .spz existed.

.ksplat — the viewer-specific one

.ksplat is the format used by mkkellogg’s GaussianSplats3D viewer, with several compression levels trading precision for size, and a scene structure that lets the viewer stream and sort more efficiently. It is a good choice if you are building on that specific viewer and a poor choice as an interchange format, because support outside it is thin.

Picking one

SituationFormat
Trainer output, archive, re-editing.ply
Shipping a world to a browser.spz
Web viewer that predates spz support.splat
Building on GaussianSplats3D.ksplat
Handing a file to someone else.ply if they will edit it, .spz if they will look at it

A useful default: train to .ply, archive that file, convert to .spz for anything that travels over a network, and never let .splat be your only copy.

Sizes at a glance

Splats.ply.splat.spz (approx)
500K124 MB16 MB12 MB
1M248 MB32 MB25 MB
4M992 MB128 MB99 MB

The .spz column is approximate because compression depends on scene content; the 10x figure is the one Niantic publishes; we have not measured it ourselves.

Converting between them

Niantic’s repository ships a converter alongside the format specification, and it is the reference path for .ply to .spz. Most web viewers, including the splat viewer on this site, read .ply, .spz and .splat, so opening a file in a viewer that can re-export is often the fastest conversion for one-off work.

Two things to watch during conversion. Axis conventions differ between pipelines, and a world that looks upside down after conversion usually needs a Y-axis flip rather than a re-export. And spherical-harmonic degree is sometimes reduced during conversion to save space; if a converted scene looks flat, check whether the SH coefficients survived.

What this means for Atlas and Marble

Marble exports splats today, and Atlas is expected to produce the same family of assets given both come from World Labs’ spatial pipeline. If you are building a workflow now, build it around .ply as the archive format and .spz as the delivery format, and it will keep working when Atlas access opens. The Atlas vs Marble comparison covers what each model produces; the game development guide covers getting splats into an engine.

Bottom line

The formats are not competing standards, they are stages in a pipeline: .ply is what the trainer writes, .spz is what you ship, .splat and .ksplat are what specific viewers wanted before a compressed standard existed. Keep the .ply, ship the .spz, and drop any of them into the browser viewer when you need to check what you actually have.

Sources

  1. 3D Gaussian Splatting for Real-Time Radiance Field Rendering (paper)
  2. Inria reference implementation
  3. Niantic spz format and converter
  4. antimatter15 .splat viewer
  5. mkkellogg GaussianSplats3D (.ksplat)
  6. Spark renderer (World Labs)

Frequently asked questions

Which splat format should I use for the web?

Use .spz. It is roughly 10x smaller than the .ply your trainer produces, loads much faster over a network, and the quality loss is invisible in normal viewing.

Is .spz lossy?

Yes. It quantises positions, scales, rotations and colour into small integers. The loss is deliberate and tuned to be imperceptible; keep the original .ply if you plan to retrain or re-edit.

Why is my .ply file 250 MB?

The standard 3D Gaussian Splatting .ply stores 62 float32 values per splat, which is 248 bytes each. One million splats is therefore about 248 MB before any compression.

Can I convert between splat formats?

Yes. Niantic publishes an open-source spz converter, and most web viewers read .ply, .spz and .splat, so a viewer round-trip is often the simplest conversion path.

What does Marble export?

Marble exports Gaussian splats as .ply and .spz, plus a mesh and a fly-through video. Both splat files open in this site's viewer.

Does a smaller format mean fewer splats?

No. Compression changes how each splat is stored, not how many there are. Reducing splat count is a separate operation, usually done by pruning during or after training.