Introduction
A .splat file holds a 3D Gaussian splatting scene in a compact form for the web. It
comes from Kevin Kwok’s WebGL splat
viewer (antimatter15), released in 2023, whose script convert.py
makes it from the PLY file that the
3D Gaussian Splatting training code writes.
Many web viewers read it.
Each splat is a small, semi-transparent 3D Gaussian with a position, a size along three axes, a rotation, a colour and an opacity. A .splat keeps only the base colour, not the spherical harmonics that make the colour change with the viewing direction, and it stores each splat in 32 bytes instead of the PLY file’s 248.
Structure
The file has no header, signature or count. It is a run of 32-byte records, one a splat, so the number of splats is the file size divided by 32. Numbers are little-endian.
0Splat 0 the first record32 bytes+0Position x, y, z as float3212 bytes+12Scale x, y, z as float3212 bytes+24Colour red, green, blue, alpha as bytes4 bytes+28Rotation w, x, y, z as bytes4 bytes
32Splat 1 and so on to the end of the file32 bytes each
The splat record
| Offset | Size | Type | Field | Value |
|---|---|---|---|---|
| +0 | 12 | 3 × float32 | Position | The centre, x, y, z |
| +12 | 12 | 3 × float32 | Scale | The standard deviation along each of the splat’s own axes: exp(scale_i) of the PLY values |
| +24 | 3 | 3 × uint8 | Colour | Red, green, blue: (0.5 + SH_C0 × f_dc_i) × 255, clipped to 0 to 255 |
| +27 | 1 | uint8 | Alpha | The opacity: sigmoid(opacity) × 255, where sigmoid(v) = 1 / (1 + e−v) |
| +28 | 4 | 4 × uint8 | Rotation | The quaternion rot_0 to rot_3 (w, x, y, z), normalised, then q × 128 + 128, clipped to 0 to 255 |
SH_C0 is 0.28209479177387814, the degree 0 spherical harmonics constant
1 / (2√π). The colour bytes are cast to integers after scaling, so the fraction is
dropped.
From the bytes to a Gaussian
- Centre: the three floats as they are.
- Scale: the three floats as they are; they are already linear, not logarithms.
- Colour: each byte divided by 255.
- Opacity: the alpha byte divided by 255.
- Rotation: each byte b gives
(b − 128) / 128; the four values are normalised again before use, because rounding leaves them a little off unit length.
The covariance of the Gaussian is R S ST RT, where
R is the rotation matrix of the quaternion and S a diagonal
matrix of the three scales. Coordinates follow the training code’s camera space, in
which Y points down.
Order of the splats
convert.py sorts the splats before writing them, by
exp(scale_0 + scale_1 + scale_2) / (1 + exp(−opacity)), largest first:
the biggest and most opaque splats come first. A viewer that streams the file can
then draw a rough picture early. Readers do not depend on the order.
Recognising a .splat file
With no signature, a .splat file is known by its extension and its size, which is a multiple of 32. Its first floats are finite numbers and its scales are not negative, which rules out most other files of a suitable size.
Links
Software
- splat – Kevin Kwok’s WebGL viewer, which defined the format, with convert.py (web)
- GaussianSplats3D – three.js viewer that loads .splat, .ksplat and PLY (web)
- SuperSplat – PlayCanvas’s free open source splat editor (web)
Developers
- splat-transform – converts between splat formats, .splat among them (JavaScript)
Reference
- convert.py – the script that writes the format, the only description of it