KHR_gaussian_splatting conformance
Catetus ships a Rust validator for the
Khronos KHR_gaussian_splatting extension
— currently at Release Candidate. Every clause in
the spec is encoded as a deterministic test that runs against ten
golden fixtures. The matrix below is the live output of
catetus-khr-validate on the committed corpus.
- 30 normative clauses
- 13 fixtures (5 positive, 8 negative)
- 390 cells (318 pass · 8 fail · 64 skip)
- 390/390 cells match expected outcome
Run it yourself
# clone & run the validator from the Catetus repo
git clone https://github.com/Catetus/catetus
cd Catetus
# validate any glTF/GLB asset (one of ours, or your own):
cargo run -p catetus-khr-conformance --bin catetus-khr-validate -- \
crates/catetus-khr-conformance/fixtures/01_valid_baseline.glb
# machine-readable JSON:
cargo run -p catetus-khr-conformance --bin catetus-khr-validate -- \
your-scene.glb --json
# regenerate the canonical fixture corpus byte-for-byte:
crates/catetus-khr-conformance/scripts/generate-fixtures.sh
# full conformance test matrix:
cargo test -p catetus-khr-conformance
Clause × fixture matrix
Rows are normative clauses, columns are fixtures. Hover a cell for the validator's detail string. Negative fixtures are highlighted in their header.
| Clause | 01_valid_baseline.glb | 02_valid_baseline.gltf | 03_valid_quantized.glb | 04_valid_with_sh.glb | 05_valid_spz_stub.glb | 06_invalid_missing_ext_used.glb | 07_invalid_no_rotation.gltf | 08_invalid_rotation_vec3.gltf | 09_invalid_position_no_minmax.gltf | 10_invalid_count_mismatch.gltf | 11_valid_spz_compressed.glb | 12_invalid_spz_missing_ext_used.glb | 13_invalid_spz_wrong_magic.glb |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
EXT_USED Root extensionsUsed array MUST list "KHR_gaussian_splatting". | PASS | PASS | PASS | PASS | PASS | FAIL | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ASSET_VERSION asset.version MUST be "2.0" per glTF 2.0. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
PRIM_EXT At least one primitive's extensions block MUST declare KHR_gaussian_splatting. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
PRIM_MODE_POINTS Primitive carrying KHR_gaussian_splatting MUST set mode to POINTS (0). | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
EXT_KERNEL The extension object MUST declare a string `kernel`. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
EXT_COLOR_SPACE The extension object MUST declare a string `colorSpace`. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
EXT_PROJECTION If `projection` is present it MUST be a string (default "perspective"). | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
EXT_SORTING If `sortingMethod` is present it MUST be a string (default "cameraDistance"). | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ATTR_POSITION Primitive attributes MUST declare a POSITION accessor. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ATTR_ROTATION Attributes MUST declare KHR_gaussian_splatting:ROTATION. | PASS | PASS | PASS | PASS | PASS | PASS | FAIL | PASS | PASS | PASS | PASS | PASS | PASS |
ATTR_SCALE Attributes MUST declare KHR_gaussian_splatting:SCALE. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ATTR_OPACITY Attributes MUST declare KHR_gaussian_splatting:OPACITY. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ATTR_SH_DC Attributes MUST declare KHR_gaussian_splatting:SH_DEGREE_0_COEF_0. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ACC_POSITION POSITION accessor MUST be VEC3 (FLOAT or normalized integer). | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ACC_ROTATION ROTATION accessor MUST be VEC4 (FLOAT or normalized signed byte/short). | PASS | PASS | PASS | PASS | PASS | PASS | SKIP | FAIL | PASS | PASS | PASS | PASS | PASS |
ACC_SCALE SCALE accessor MUST be VEC3 (FLOAT or unsigned-integer normalized variants). | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ACC_OPACITY OPACITY accessor MUST be SCALAR (FLOAT or normalized UByte/UShort). | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ACC_SH_COEF Every SH_DEGREE_l_COEF_n accessor MUST be VEC3 FLOAT. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ACC_POSITION_MINMAX POSITION accessor MUST provide both min and max arrays. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | FAIL | PASS | PASS | PASS | PASS |
SH_DEGREES_FULL SH degrees MUST be fully defined; using degree l requires degrees 0..l-1. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
ACC_COUNTS_AGREE All per-splat accessors MUST share the same count. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | FAIL | PASS | PASS | PASS |
BUFFERVIEW_BOUNDS Every accessor's bufferView byte footprint MUST fit inside its parent buffer. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | FAIL | PASS | PASS | PASS |
ATTRS_KNOWN_ONLY All KHR_gaussian_splatting:* attribute keys MUST be defined by the spec. | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS | PASS |
SPZ_DECLARED | SKIP | SKIP | SKIP | SKIP | PASS | SKIP | SKIP | SKIP | SKIP | SKIP | PASS | FAIL | PASS |
SPZ_CONSISTENT | SKIP | SKIP | SKIP | SKIP | PASS | SKIP | SKIP | SKIP | SKIP | SKIP | PASS | PASS | PASS |
SPZ_EXT_PRESENT | SKIP | SKIP | SKIP | SKIP | PASS | SKIP | SKIP | SKIP | SKIP | SKIP | PASS | PASS | PASS |
SPZ_VERSION | SKIP | SKIP | SKIP | SKIP | PASS | SKIP | SKIP | SKIP | SKIP | SKIP | PASS | PASS | PASS |
SPZ_BUFFERVIEW | SKIP | SKIP | SKIP | SKIP | PASS | SKIP | SKIP | SKIP | SKIP | SKIP | PASS | PASS | PASS |
SPZ_BLOB_MAGIC | SKIP | SKIP | SKIP | SKIP | PASS | SKIP | SKIP | SKIP | SKIP | SKIP | PASS | PASS | FAIL |
SPZ_DECODED_COUNT | SKIP | SKIP | SKIP | SKIP | PASS | SKIP | SKIP | SKIP | SKIP | SKIP | PASS | PASS | PASS |
Fixtures
| File | Container | Kind | Pass | Fail | Skip | Intent |
|---|---|---|---|---|---|---|
01_valid_baseline.glb | glb | positive | 23 | 0 | 7 | Should pass every applicable clause. |
02_valid_baseline.gltf | gltf | positive | 23 | 0 | 7 | Should pass every applicable clause. |
03_valid_quantized.glb | glb | positive | 23 | 0 | 7 | Should pass every applicable clause. |
04_valid_with_sh.glb | glb | positive | 23 | 0 | 7 | Should pass every applicable clause. |
05_valid_spz_stub.glb | glb | positive | 30 | 0 | 0 | Should pass every applicable clause. |
06_invalid_missing_ext_used.glb | glb | negative | 22 | 1 | 7 | Mutated to violate EXT_USED. |
07_invalid_no_rotation.gltf | gltf | negative | 21 | 1 | 8 | Mutated to violate ATTR_ROTATION. |
08_invalid_rotation_vec3.gltf | gltf | negative | 22 | 1 | 7 | Mutated to violate ACC_ROTATION. |
09_invalid_position_no_minmax.gltf | gltf | negative | 22 | 1 | 7 | Mutated to violate ACC_POSITION_MINMAX. |
10_invalid_count_mismatch.gltf | gltf | negative | 21 | 2 | 7 | Mutated to violate ACC_COUNTS_AGREE. |
11_valid_spz_compressed.glb | glb | negative | 30 | 0 | 0 | Mutated to violate a clause. |
12_invalid_spz_missing_ext_used.glb | glb | negative | 29 | 1 | 0 | Mutated to violate SPZ_DECLARED. |
13_invalid_spz_wrong_magic.glb | glb | negative | 29 | 1 | 0 | Mutated to violate SPZ_BLOB_MAGIC. |