3dtiled-to-3dtiles
Reference notes

SparkJS PackedSplats

A PackedSplats is a collection of Gaussian splats packed into 16 bytes per splat.

Source: https://sparkjs.dev/2.0.0-preview/docs/packed-splats/ Version: Spark 2.0 preview

A PackedSplats is a collection of Gaussian splats packed into 16 bytes per splat.

Byte Layout (16 bytes = 4 × uint32)

OffsetFieldSizeDescription
0R1BRed (uint8 0–255 → 0.0–1.0)
1G1BGreen (uint8 0–255 → 0.0–1.0)
2B1BBlue (uint8 0–255 → 0.0–1.0)
3A1BAlpha/opacity (uint8 0–255 → 0.0–1.0)
4–5center.x2Bfloat16
6–7center.y2Bfloat16
8–9center.z2Bfloat16
10quat oct.U1BOctahedral quaternion U (uint8)
11quat oct.V1BOctahedral quaternion V (uint8)
12scale.x1Blog-encoded uint8 (e^-12 to e^9)
13scale.y1Blog-encoded uint8
14scale.z1Blog-encoded uint8
15quat angle θ1BRotation angle (uint8, θ/π×255)

Total: 16 bytes/splat. With SH0+1+2+3: up to 56 bytes/splat.

Creating

const packedSplats = new PackedSplats({
  url?: string,           // .ply, .spz, .splat, .ksplat, .rad
  fileBytes?: Uint8Array,
  maxSplats?: number,
  packedArray?: Uint32Array,
  numSplats?: number,
  construct?: (splats) => void,
  lod?: boolean | number,
  lodSplats?: PackedSplats,
  splatEncoding?: SplatEncoding,
});

Encoding / Decoding

import { utils } from "@sparkjsdev/spark";

// Unpack all components
const { center, scales, quaternion, color, opacity } = utils.unpackSplat(packedSplats.packedArray, index);

// Pack
utils.setPackedSplat(packedSplats.packedArray, index, x, y, z, scaleX, scaleY, scaleZ, qx, qy, qz, qw, r, g, b, a);

// Iterate
packedSplats.forEachSplat((index, center, scales, quaternion, opacity, color) => { ... });

SH Layout (extra property)

BufferWords/splatCoefficientsQuantization
sh12 (8B)9 values (3 coeffs × RGB)Sint7
sh24 (16B)15 values (5 coeffs × RGB)Sint8
sh34 (16B)21 values (7 coeffs × RGB)Sint6

On this page