Gaussian splat file formats: .ply, .spz, .splat and .ksplat
By Atlas World Model EditorialUpdated 5 min read
Key facts
| .ply per splat | 248 bytes (62 float32)(as of 2026-09-05)source |
|---|---|
| .splat per splat | 32 bytes (quantised)(as of 2026-09-05)source |
| .spz size | About 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:
| Attribute | Values | Purpose |
|---|---|---|
| Position | 3 | Where the splat sits in world space |
| Normal | 3 | Unused, kept for PLY compatibility |
SH degree 0 (f_dc) | 3 | Base colour |
SH degrees 1–3 (f_rest) | 45 | View-dependent colour |
| Opacity | 1 | Alpha before blending |
| Scale | 3 | Ellipsoid size on each axis |
| Rotation | 4 | Quaternion 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
| Situation | Format |
|---|---|
| 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) |
|---|---|---|---|
| 500K | 124 MB | 16 MB | 12 MB |
| 1M | 248 MB | 32 MB | 25 MB |
| 4M | 992 MB | 128 MB | 99 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
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.