Each section’s data is one block, storageSizeBytes long, at the place
the section headers give. It holds
the section’s buckets, then its splat records. All numbers are little-endian.
Buckets
At levels 1 and 2 the splats of a section are grouped into buckets: cubes of
bucketBlockSize on a side, each with a centre. A splat’s centre is kept
as an offset from its bucket’s centre, in 16 bits an axis. The splats are stored
bucket by bucket: first the full buckets, bucketSize splats each, then
the partly filled ones.
| Offset | Size | Type | Part |
|---|---|---|---|
| +0 | 4 × partiallyFilledBucketCount | uint32 | The number of splats in each partly filled bucket |
| … | 12 × bucketCount | 3 × float32 | The centre of each bucket, full buckets first |
| … | maxSplatCount × splat size | records | The splats, bucket by bucket |
Splat j of a section is in bucket ⌊j / bucketSize⌋
while j < fullBucketCount × bucketSize;
after that, the partly filled buckets follow one another with the lengths given. At
level 0 there are no buckets: both counts are 0 and the splats start the block.
The splat record
| Level 0 | Levels 1 and 2 | Field | Meaning |
|---|---|---|---|
| +0, 3 × float32 | +0, 3 × uint16 | Centre | The position, or at levels 1 and 2 an offset in its bucket |
| +12, 3 × float32 | +6, 3 × half | Scale | The standard deviation along each of the splat’s axes, linear |
| +24, 4 × float32 | +12, 4 × half | Rotation | Quaternion w, x, y, z |
| +40, 4 × uint8 | +20, 4 × uint8 | Colour | Red, green, blue and opacity, 0 to 255 |
| +44 | +24 | Harmonics | 9 values at degree 1, 24 at degree 2: float32 at level 0, half at level 1, uint8 at level 2 |
From the record to a Gaussian
- Centre at levels 1 and 2: for each axis,
(v − r) × (
bucketBlockSize/ 2) / r plus the bucket centre, where v is the stored uint16 and r iscompressionScaleRange(32767 when 0). The writer stores round(offset × r / (bucketBlockSize/ 2)) + r, clamped, so offsets reach half a block either way. - Scale: as stored. The converter has already applied the exponential to the PLY file’s log scales.
- Rotation: as stored, then normalised.
- Colour: each byte / 255. The converter wrote (0.5 +
SH_C0×f_dc) × 255, so this is the base colour. - Opacity: the fourth colour byte / 255. The converter wrote
sigmoid(
opacity) × 255.
Spherical harmonics
The harmonics values come in two groups, each channel by channel. The reader takes them with a stride, three apart for degree 1 and five apart for degree 2.
| Values | Holds |
|---|---|
| 0 to 2 | Red, degree 1 coefficients 1 to 3 |
| 3 to 5 | Green, degree 1 coefficients 1 to 3 |
| 6 to 8 | Blue, degree 1 coefficients 1 to 3 |
| 9 to 13 | Red, degree 2 coefficients 4 to 8 |
| 14 to 18 | Green, degree 2 coefficients 4 to 8 |
| 19 to 23 | Blue, degree 2 coefficients 4 to 8 |
The coefficients are numbered as in the 3D Gaussian Splatting PLY. At level 2 each value is a byte mapped onto the header’s range.