3dtiled-to-3dtiles
3DTiles + glTF

KHR gaussian splatting

Khronos glTF extension for storing 3D Gaussian splats as point cloud primitives, plus its SPZ compression child extension.

KHR_gaussian_splatting

Source: https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md Status: Release Candidate (2026)

Overview

Defines basic support for storing 3D Gaussian splats in glTF assets as point cloud primitives.

Splats are defined by: position, rotation, scale, opacity, and spherical harmonics.

Extension Object Properties

PropertyTypeDescriptionRequired
kernelstringGaussian kernel typeYes
colorSpacestringColor space of reconstructed valuesYes
projectionstringProjection methodNo (default: "perspective")
sortingMethodstringSorting method for renderingNo (default: "cameraDistance")

Ellipse Kernel Attributes

Splat DataAttribute SemanticTypeRequired
PositionPOSITIONVEC3 floatYes
RotationKHR_gaussian_splatting:ROTATIONVEC4 float/byte/short normalizedYes
ScaleKHR_gaussian_splatting:SCALEVEC3 float/ubyte/ushortYes
OpacityKHR_gaussian_splatting:OPACITYSCALAR float/ubyte/ushort normalizedYes
SH degree 0KHR_gaussian_splatting:SH_DEGREE_0_COEF_0VEC3 floatYes
SH degree 1KHR_gaussian_splatting:SH_DEGREE_1_COEF_[0-2]VEC3 floatNo
SH degree 2KHR_gaussian_splatting:SH_DEGREE_2_COEF_[0-4]VEC3 floatNo
SH degree 3KHR_gaussian_splatting:SH_DEGREE_3_COEF_[0-6]VEC3 floatNo

Covariance Matrix

Σ = M·C·Cᵀ·Mᵀ

Where M = upper-left 3×3 of node transform, C = scale×rotation matrix.

Spherical Harmonics Color

Color = SH_0,0 × 0.2820947917738781 + 0.5

(plus higher degree terms for view-dependent color)

JSON Example

{
  "meshes": [{ "primitives": [{
    "attributes": {
      "POSITION": 0,
      "KHR_gaussian_splatting:SCALE": 2,
      "KHR_gaussian_splatting:ROTATION": 3,
      "KHR_gaussian_splatting:OPACITY": 4,
      "KHR_gaussian_splatting:SH_DEGREE_0_COEF_0": 5
    },
    "mode": 0,
    "extensions": {
      "KHR_gaussian_splatting": {
        "kernel": "ellipse",
        "colorSpace": "srgb_rec709_display"
      }
    }
  }]}]
}

Full Specification

See full spec at: https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md


Compression extension: KHR_gaussian_splatting_compression_spz_2

Source: https://github.com/KhronosGroup/glTF/pull/2531 Status: Draft (2026)

Extension for compressing 3D Gaussian splats using the SPZ v2 format (Niantic Spatial). Depends on KHR_gaussian_splatting above.

Usage

"extensions": {
  "KHR_gaussian_splatting": {
    "extensions": {
      "KHR_gaussian_splatting_compression_spz_2": {
        "bufferView": 0
      }
    }
  }
}
"extensionsUsed": ["KHR_gaussian_splatting", "KHR_gaussian_splatting_compression_spz_2"]

SPZ → glTF Attribute Mapping

SPZ fieldglTF AttributeConversion
positionsPOSITION—
colorsCOLOR_0 RGB0.5 + 0.282095 × x
alphasCOLOR_0 Asigmoid(x) = 1/(1+e^-x)
scalesKHR_gaussian_splatting:SCALEexp(x)
rotationsKHR_gaussian_splatting:ROTATION—
sh[0..2]SH_DEGREE_1_COEF_0—
sh[3..5]SH_DEGREE_1_COEF_1—
sh[6..8]SH_DEGREE_1_COEF_2—
sh[9..44]SH_DEGREE_2..3_COEF_*—

Coordinate system: Left-Up-Front (LUF) in SPZ PackOptions/UnpackOptions for glTF compatibility.

Resources


Compression extension: KHR_gaussian_splatting_compression_lgsc

Source: https://github.com/KhronosGroup/glTF/pull/2551 Status: Open PR (opened 2026-01-16, not merged) — author ibouazizi

A second, sibling compression child extension to KHR_gaussian_splatting, carrying a payload compressed with Qualcomm's L-GSC (Lite 3D Gaussian Splat Codec) v1.0. It sits at the same level in the lineage as _spz_2 above — same base extension, different codec — so the base's attribute semantics and covariance/SH math are unchanged; only the compressed blob differs.

The extension was first proposed as KHR_gaussian_splatting_lgsc and renamed during review to KHR_gaussian_splatting_compression_lgsc, a maintainer noting: "The pattern we've been using for compression extensions is KHR_gaussian_splatting_compression_lgsc." That rename is the useful signal here — Khronos is treating splat compression as an open set of interchangeable child extensions under one base, rather than blessing SPZ as the only codec.

The PR currently carries only a README; it does not yet spell out the JSON nesting, the bufferView property, or required fields. By the naming pattern it is expected to nest inside KHR_gaussian_splatting.extensions exactly like _spz_2 does, but do not treat that as specified until the PR lands. No conformance target exists yet, and no renderer in this repo's stack (CesiumJS, 3DTRJS + SparkJS) decodes L-GSC today.

The codec itself — qualcomm/lite-3Dgsplat-codec

AuthorQualcomm Technologies, Inc. and/or its subsidiaries
LicenseApache-2.0
DeliverableC++ library (compress/decompress API) + CMake build, Windows & Linux, with a sample
Input format"INRIA format" — i.e. the original 3DGS PLY layout
Coded datageometry (positions, rotations, scales, opacities) + appearance (diffuse RGB, SH)
SH supportup to order 3 (15 coefficients per channel)
Entropy coding"By default, the geometry and attributes are coded using zlib"
Levels3 compression levels (0 = minimal … 2 = maximum)

Note what this implies relative to SPZ: L-GSC as published is a zlib-backed container over linearized geometry/appearance arrays with a level knob, not a fixed-bit-layout quantization scheme like SPZ v2's 24-bit positions / 3-byte rotations. The repo publishes no benchmark numbers — no compression ratios, no quality or decode-speed comparison against SPZ, SOG, or raw PLY — so any size/quality claim about L-GSC vs _spz_2 would have to be measured locally before being repeated.

Resources

On this page