From 9dac310c5fed30be3f5560d9a6a433ad4b4cd9b9 Mon Sep 17 00:00:00 2001 From: "Adam N. Morris" Date: Tue, 22 Jul 2025 11:15:25 -0500 Subject: [PATCH 1/7] Added a small clarification regarding quaternion order --- extensions/2.0/Khronos/KHR_gaussian_splatting/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md b/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md index ca9a80c1ee..60d8d42fc2 100644 --- a/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md @@ -91,7 +91,7 @@ Each 3D Gaussian splat has the following attributes. At minimum the attributes m | --- | --- | --- | --- | --- | --- | | Position | POSITION | VEC3 | float | yes | | | Color (Spherical Harmonic degree 0 (Diffuse) and alpha) | COLOR_0 | VEC4 | unsigned byte normalized or float | yes | | -| Rotation | _ROTATION | VEC4 | float | yes | Rotation is a quaternion. | +| Rotation | _ROTATION | VEC4 | float | yes | Rotation is a quaternion. (xyzw) | | Scale | _SCALE | VEC3 | float | yes | | | Spherical Harmonics degree 1 | _SH_DEGREE_1_COEF_n (n = 0 to 2) | VEC3 | float | no (yes if degree 2 or 3 are used) | | | Spherical Harmonics degree 2 | _SH_DEGREE_2_COEF_n (n = 0 to 4) | VEC3 | float | no (yes if degree 3 is used) | | From fa056f09edfd4193d1fbd6ac190b18d2585a0d12 Mon Sep 17 00:00:00 2001 From: "Adam N. Morris" Date: Fri, 25 Jul 2025 10:30:05 -0500 Subject: [PATCH 2/7] Renamed the SPZ compression extension --- .../README.md | 2 +- ...rimitive.KHR_gaussian_splatting_compression_spz.schema.json} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename extensions/2.0/Khronos/{KHR_spz_gaussian_splats_compression => KHR_gaussian_splatting_compression_spz}/README.md (96%) rename extensions/2.0/Khronos/{KHR_spz_gaussian_splats_compression/schema/mesh.primitive.KHR_spz_gaussian_splats_compression.schema.json => KHR_gaussian_splatting_compression_spz/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json} (84%) diff --git a/extensions/2.0/Khronos/KHR_spz_gaussian_splats_compression/README.md b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md similarity index 96% rename from extensions/2.0/Khronos/KHR_spz_gaussian_splats_compression/README.md rename to extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md index b403400bb9..9baa4ca0f6 100644 --- a/extensions/2.0/Khronos/KHR_spz_gaussian_splats_compression/README.md +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md @@ -1,4 +1,4 @@ -# KHR\_spz\_gaussian\_splats\_compression +# KHR\_gaussian\_splatting\_spz\_compression ## Contributors diff --git a/extensions/2.0/Khronos/KHR_spz_gaussian_splats_compression/schema/mesh.primitive.KHR_spz_gaussian_splats_compression.schema.json b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json similarity index 84% rename from extensions/2.0/Khronos/KHR_spz_gaussian_splats_compression/schema/mesh.primitive.KHR_spz_gaussian_splats_compression.schema.json rename to extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json index 37246191c6..244e79cf6f 100644 --- a/extensions/2.0/Khronos/KHR_spz_gaussian_splats_compression/schema/mesh.primitive.KHR_spz_gaussian_splats_compression.schema.json +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema", - "title": "KHR_spz_gaussian_splats_compression glTF Mesh Primitive Extension", + "title": "KHR_gaussian_splatting_compression_spz glTF Mesh Primitive Extension", "type": "object", "description": "Compressed data for SPZ primitive.", "allOf": [ { "$ref": "glTFProperty.schema.json" } ], From 03f1934c616cf4b5bcde62cac5cbb4470884553f Mon Sep 17 00:00:00 2001 From: "Adam N. Morris" Date: Fri, 25 Jul 2025 13:01:23 -0500 Subject: [PATCH 3/7] Updates to the SPZ extension. --- .../README.md | 73 ++++++++++++------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md index 9baa4ca0f6..5471923ece 100644 --- a/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md @@ -44,23 +44,14 @@ At rest, the 3D Gaussian splats are stored within the SPZ compression format. Up ## Compressing 3D Gaussian splats using SPZ -If a primitive contains an `extension` property which defines both `KHR_gaussian_splatting` and `KHR_spz_gaussian_splats_compression` then support for SPZ compression is required. There is no requirement for a backup uncompressed buffer. +To use this extension, it must be defined in the `extensions` property in a `KHR_gaussian_splatting` extension definition. Any mesh primitive using `KHR_gaussian_splatting` that is using this extension will use the SPZ payload to retreive the values for `POSITION`, `COLOR_0`, `KHR_gaussian_splatting:SCALE`, `KHR_gaussian_splatting:ROTATION`, and all `KHR_gaussian_splatting:SH_DEGREE_ℓ_COEF_n` attributes. The [attribute mapping](#attribute-mapping) section defines how the SPZ data is mapped to these attributes. -The extension must be listed in `extensionsUsed` alongside `KHR_gaussian_splatting`. +The extension must then be listed in `extensionsUsed` alongside `KHR_gaussian_splatting`. ```json "extensionsUsed" : [ "KHR_gaussian_splatting", - "KHR_spz_gaussian_splats_compression" - ] -``` - -It must also be listed in `extensionsRequired`. When `KHR_spz_gaussian_splats_compression` is in use, the `KHR_gaussian_splatting` extension must also be listed as required. - -```json - "extensionsRequired" : [ - "KHR_gaussian_splatting", - "KHR_spz_gaussian_splats_compression" + "KHR_gaussian_splatting_compression_spz" ] ``` @@ -70,7 +61,7 @@ As this extension extends the base extension, all components of the base extensi ### Schema Example -Example SPZ extension shown below. This extension only affects any `primitive` nodes containting Gaussian splat data. Note that unlike the base `KHR_gaussian_splatting` extension, the `indices` property is excluded, and a `bufferView` is provided by the extension. This bufferview points to where the SPZ blob is stored. +Example SPZ extension shown below. This extension only affects any `primitive` nodes containting Gaussian splat data. A `bufferView` is provided by the extension which points to where the SPZ blob is stored. ```json "meshes": [{ @@ -78,17 +69,21 @@ Example SPZ extension shown below. This extension only affects any `primitive` n "attributes": { "POSITION": 0, "COLOR_0": 1, - "_SCALE": 2, - "_ROTATION": 3, - "_SH_DEGREE_1_COEF_0": 4, - "_SH_DEGREE_1_COEF_1": 5, - "_SH_DEGREE_1_COEF_2": 6 + "KHR_gaussian_splatting:SCALE": 2, + "KHR_gaussian_splatting:ROTATION": 3, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_0": 4, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_1": 5, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_2": 6 }, "material": 0, "mode": 0, "extensions": { - "KHR_spz_gaussian_splats_compression": { - "bufferView": 0, + "KHR_gaussian_splatting": { + "extensions": { + "KHR_gaussian_splatting_compression_spz": { + "bufferView": 0, + } + } } } }] @@ -109,11 +104,37 @@ Example SPZ extension shown below. This extension only affects any `primitive` n This property points to the bufferView containing the Gaussian splat data compressed with SPZ. +### Attribute Mapping + +Data may be used directly from SPZ or may be mapped to the placeholder attributes this extension provides. When mapping to attributes, the data from SPZ is mapped from the `GaussianCloudData` struct in SPZ to the following attributes in glTF. Several fields require additional conversion to make them glTF and renderer ready. + +| SPZ `GaussianCloudData` field | glTF Attribute | Required Conversion | +| --- | --- | +| `positions` | `POSITION` | | +| `colors` | `COLOR_0` RGB components | Compute _0.5 + 0.282095 * x_ to get the color between 0 and 1. | +| `alphas` | `COLOR_0` A component | Compute the sigmoid to get the alpha between 0 and 1. (Sigmoid formula: _1 / (1 + e^-x)_) | +| `scales` | `KHR_gaussian_splatting:SCALE` | Compute the base-e exponential of each scale value. (e.g. _e^x_ or `std::exp(x)`) | +| `rotations` | `KHR_gaussian_splatting:ROTATION` | | +| `sh` index 0 to 2 | `KHR_gaussian_splatting:SH_DEGREE_1_COEF_0` | | +| `sh` index 3 to 5 | `KHR_gaussian_splatting:SH_DEGREE_1_COEF_2` | | +| `sh` index 6 to 8 | `KHR_gaussian_splatting:SH_DEGREE_1_COEF_3` | | +| `sh` index 9 to 11 | `KHR_gaussian_splatting:SH_DEGREE_2_COEF_0` | | +| `sh` index 12 to 14 | `KHR_gaussian_splatting:SH_DEGREE_2_COEF_1` | | +| `sh` index 15 to 17 | `KHR_gaussian_splatting:SH_DEGREE_2_COEF_2` | | +| `sh` index 18 to 20 | `KHR_gaussian_splatting:SH_DEGREE_2_COEF_3` | | +| `sh` index 21 to 23 | `KHR_gaussian_splatting:SH_DEGREE_2_COEF_4` | | +| `sh` index 24 to 26 | `KHR_gaussian_splatting:SH_DEGREE_3_COEF_0` | | +| `sh` index 27 to 29 | `KHR_gaussian_splatting:SH_DEGREE_3_COEF_1` | | +| `sh` index 30 to 32 | `KHR_gaussian_splatting:SH_DEGREE_3_COEF_2` | | +| `sh` index 33 to 35 | `KHR_gaussian_splatting:SH_DEGREE_3_COEF_3` | | +| `sh` index 36 to 38 | `KHR_gaussian_splatting:SH_DEGREE_3_COEF_4` | | +| `sh` index 39 to 41 | `KHR_gaussian_splatting:SH_DEGREE_3_COEF_5` | | +| `sh` index 42 to 44 | `KHR_gaussian_splatting:SH_DEGREE_3_COEF_6` | | + ### Accessors Accessor requirements are modified from the base `KHR_gaussian_splatting` extension with the following adjustments to definition: - - SPZ compressed attributes must not include `bufferView` nor `byteOffset`. (See: [Conformance](#conformance)) - Accessor `type` is defined for the resulting type after decompression and dequantization has occurred. - The accessor `count` must match the number of points in the compressed SPZ data. @@ -121,17 +142,17 @@ Accessor requirements are modified from the base `KHR_gaussian_splatting` extens The recommended process for handling SPZ compression is as follows: -- If the loader does not support `KHR_gaussian_splatting` and `KHR_spz_gaussian_splats_compression`, it must fail. -- If the loader does support `KHR_gaussian_splatting` and `KHR_spz_gaussian_splats_compression` then: +- If the loader does not support `KHR_gaussian_splatting_compression_spz` and `accessor.bufferView` is undefined, other extensions may be providing the data. +- If the loader does not support `KHR_gaussian_splatting_compression_spz` and `accessor.bufferView` is defined, accessor data should be sourced as usual. +- If the loader does support `KHR_gaussian_splatting_compression_spz` then the loader must process `KHR_gaussian_splatting_compression_spz` data first. The loader must get the data from `KHR_gaussian_splatting_compression_spz`'s `bufferView` extension property. - - The loader must process `KHR_spz_gaussian_splats_compression` data first. The loader must get the data from `KHR_spz_gaussian_splats_compression`'s `bufferView` property. - - SPZ compressed attributes must not include `bufferView` nor `byteOffset` in their accessor declarations. Any attributes falling outside the SPZ format, however, must be stored as regular glTF attributes and must therefore include `bufferView` (and optionally `byteOffset`) in their accessor definitions. +This allows for a graceful fallback when an implementation does not support this extension. When compressing or decompressing the SPZ data to be stored within the glTF, you must specify a Left-Up-Front (`LUF`) coordinate system in the SPZ `PackOptions` or `UnpackOptions` within the SPZ library. This ensures that the data is compressed and decompressed appropriately for glTF. ## Schema -[SPZ Compression Schema](./schema/mesh.primitive.KHR_spz_gaussian_splats_compression.schema.json) +[SPZ Compression Schema](./schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json) ## Known Implementations From df36989d34f7f12df451a1ff3e24a99cd984a4d5 Mon Sep 17 00:00:00 2001 From: "Adam N. Morris" Date: Fri, 25 Jul 2025 14:46:09 -0500 Subject: [PATCH 4/7] Updated base 3DGS extension with feedback --- .../Khronos/KHR_gaussian_splatting/README.md | 82 ++++--------------- 1 file changed, 14 insertions(+), 68 deletions(-) diff --git a/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md b/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md index 60d8d42fc2..d3c0861d94 100644 --- a/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md @@ -34,7 +34,7 @@ Written against the glTF 2.0 spec. ## Overview -This extension defines support for storing 3D Gaussian splats in glTF, bringing structure and conformity to the 3D Gaussian splatting space. 3D Gaussian splats are effectively fields of 3D Gaussian splats that can be treated as a point cloud for the purposes of storage. 3D Gaussian splats are defined by their position, rotation, scale, and spherical harmonics which provide both diffuse and specular color. These values are stored as values on a point primitive. Since we treat the 3D Gaussian splats as points primitives, a graceful fallback to treating the data as a sparse point cloud is possible. +This extension defines support for storing 3D Gaussian splats in glTF, bringing structure and conformity to the 3D Gaussian splatting space. 3D Gaussian splatting uses fields of Gaussians that can be treated as a point cloud for the purposes of storage. 3D Gaussian splats are defined by their position, rotation, scale, and spherical harmonics which provide both diffuse and specular color. These values are stored as values on a point primitive. Since we treat the 3D Gaussian splats as points primitives, a graceful fallback to treating the data as a sparse point cloud is possible. ## Adding 3D Gaussian Splats to Primitives @@ -64,11 +64,11 @@ Example shown below. This extension only affects any `primitive` nodes containti "attributes": { "POSITION": 0, "COLOR_0": 1, - "_SCALE": 2, - "_ROTATION": 3, - "_SH_DEGREE_1_COEF_0": 4, - "_SH_DEGREE_1_COEF_1": 5, - "_SH_DEGREE_1_COEF_2": 6 + "KHR_gaussian_splatting:SCALE": 2, + "KHR_gaussian_splatting:ROTATION": 3, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_0": 4, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_1": 5, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_2": 6 }, "mode": 0, "indices": 7, @@ -85,74 +85,20 @@ The extension specifies no additional properties but must be included on a point #### attributes -Each 3D Gaussian splat has the following attributes. At minimum the attributes must contain `POSITION`, `COLOR_0`, `_ROTATION`, and `_SCALE`. `_SH_DEGREE_ℓ_COEF_n` attributes hold the spherical harmonics data and are not required. If higher degrees of Spherical Harmonics are used then lower degrees are required implicitly. +Each 3D Gaussian splat has the following attributes. At minimum the attributes must contain `POSITION`, `COLOR_0`, `KHR_gaussian_splatting:ROTATION`, and `KHR_gaussian_splatting:SCALE`. `KHR_gaussian_splatting:SH_DEGREE_ℓ_COEF_n` attributes hold the spherical harmonics data and are not required. `POSITION` and `COLOR_0` are defined by the base glTF specification. If higher degrees of Spherical Harmonics are used then lower degrees are required implicitly. | Splat Data | glTF Attribute | Accessor Type | Component Type | Required | Notes | | --- | --- | --- | --- | --- | --- | -| Position | POSITION | VEC3 | float | yes | | -| Color (Spherical Harmonic degree 0 (Diffuse) and alpha) | COLOR_0 | VEC4 | unsigned byte normalized or float | yes | | -| Rotation | _ROTATION | VEC4 | float | yes | Rotation is a quaternion. (xyzw) | -| Scale | _SCALE | VEC3 | float | yes | | -| Spherical Harmonics degree 1 | _SH_DEGREE_1_COEF_n (n = 0 to 2) | VEC3 | float | no (yes if degree 2 or 3 are used) | | -| Spherical Harmonics degree 2 | _SH_DEGREE_2_COEF_n (n = 0 to 4) | VEC3 | float | no (yes if degree 3 is used) | | -| Spherical Harmonics degree 3 | _SH_DEGREE_3_COEF_n (n = 0 to 6) | VEC3 | float | no | | +| Rotation | KHR_gaussian_splatting:ROTATION | VEC4 | float | yes | Rotation is a quaternion. (xyzw) | +| Scale | KHR_gaussian_splatting:SCALE | VEC3 | float | yes | | +| Spherical Harmonics degree 1 | KHR_gaussian_splatting:SH_DEGREE_1_COEF_n (n = 0 to 2) | VEC3 | float | no (yes if degree 2 or 3 are used) | | +| Spherical Harmonics degree 2 | KHR_gaussian_splatting:SH_DEGREE_2_COEF_n (n = 0 to 4) | VEC3 | float | no (yes if degree 3 is used) | | +| Spherical Harmonics degree 3 | KHR_gaussian_splatting:SH_DEGREE_3_COEF_n (n = 0 to 6) | VEC3 | float | no | | -The value of `COLOR_0` is derived by multiplying the 3 diffuse color components of the 3D Gaussian splat with the constant zeroth-order Spherical Harmonic (ℓ = 0). +The value of `COLOR_0` is derived by multiplying the 3 diffuse color components of the 3D Gaussian splat with the constant zeroth-order Spherical Harmonic (ℓ = 0) for the RGB channels. The alpha channel should contain the opacity of the splat. Each increasing degree of spherical harmonics requires more coeffecients. At the 1st degree, 3 sets of coeffcients are required, increasing to 5 sets for the 2nd degree, and increasing to 7 sets at the 3rd degree. With all 3 degrees, this results in 45 spherical harmonic coefficients stored in the `_SH_DEGREE_ℓ_COEF_n` attributes. -### Accessors - -Required `accessors` for `POSITION`, `COLOR_0`, `_SCALE`, and `_ROTATION`: - -```json - "accessors": [{ - "bufferView": 0, - "componentType": 5126, - "count": 590392, - "type": "VEC3", - "max": [ - 1, - 1, - 1, - ], - "min": [ - -1, - -1, - -1, - ] - }, { - "bufferView": 1, - "componentType": 5121, - "count": 590392, - "type": "VEC4", - "normalized": true - }, { - "bufferView": 2, - "componentType": 5126, - "count": 590392, - "type": "VEC3" - }, { - "bufferView": 3, - "componentType": 5126, - "count": 590392, - "type": "VEC4" - }], -``` - -Spherical harmonics `accessors` all follow the pattern: - -```json - "accessors": [{ - "bufferView": 4, - "componentType": 5126, - "count": 590392, - "type": "VEC3" - }] -``` - -Accessors must be defined for all in-use `attributes`. - ## Implementation *This section is non-normative.* @@ -339,7 +285,7 @@ Accessed via `usampler2D`: #### Sorting and Indexes -With the Gaussian splat attributes packed into a texture the sorting only has to act upon a separate `_INDEX` attribute created at runtime. Gaussian splats are sorted as above, but instead of sorting each vertex buffer only sort the index values. When the glTF is loaded, Gaussian splats can be indexed in the order read. +With the Gaussian splat attributes packed into a texture the sorting only has to act upon the index of the splat at runtime. Gaussian splats are sorted as above, but instead of sorting each vertex buffer you can only sort the index values. When the glTF is loaded, Gaussian splats can be indexed in the order read. #### Extracting Data in the Vertex Shader From 1f641c21c39f24dd1b6cb02d8d1a0a04f2149b31 Mon Sep 17 00:00:00 2001 From: "Adam N. Morris" Date: Fri, 25 Jul 2025 15:36:33 -0500 Subject: [PATCH 5/7] Added shape and rendering hints to base 3DGS spec --- .../Khronos/KHR_gaussian_splatting/README.md | 92 ++++++++++++++----- ...imitive.KHR_gaussian_splatting.schema.json | 41 +++++++-- 2 files changed, 103 insertions(+), 30 deletions(-) diff --git a/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md b/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md index d3c0861d94..4abe18454f 100644 --- a/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md @@ -50,40 +50,88 @@ The extension must be listed in `extensionsUsed`: Other extensions that depend on this extension such as 3D Gaussian splatting compression extensions may require that this extension be included in `extensionsRequired`. -### Geometry Type +## Geometry Type The `mode` of the `primitive` must be `POINTS`. -### Schema Example +## Schema Example -Example shown below. This extension only affects any `primitive` nodes containting 3D Gaussian splat data. +Example shown below including optional properties. This extension only affects any `primitive` nodes containting 3D Gaussian splat data. ```json - "meshes": [{ - "primitives": [{ - "attributes": { +"meshes": [{ + "primitives": [{ + "attributes": { "POSITION": 0, "COLOR_0": 1, - "KHR_gaussian_splatting:SCALE": 2, - "KHR_gaussian_splatting:ROTATION": 3, - "KHR_gaussian_splatting:SH_DEGREE_1_COEF_0": 4, - "KHR_gaussian_splatting:SH_DEGREE_1_COEF_1": 5, - "KHR_gaussian_splatting:SH_DEGREE_1_COEF_2": 6 - }, - "mode": 0, - "indices": 7, - "extensions": { - "KHR_gaussian_splatting": {} - } - }] - }], + "_SCALE": 2, + "_ROTATION": 3, + "_SH_DEGREE_1_COEF_0": 4, + "_SH_DEGREE_1_COEF_1": 5, + "_SH_DEGREE_1_COEF_2": 6 + }, + "mode": 0, + "indices": 7, + "extensions": { + "KHR_gaussian_splatting": { + "shape": "ellipsoid", + "hints": { + "sortingMethod": "cameraDistance", + "projection": "perspective" + } + } + } + }] +}], ``` -### Extension Properties +## Extension Properties -The extension specifies no additional properties but must be included on a point primitive with an empty body to indicate that the primitive should be treated as a 3D Gaussian splatting field. +### Shape -#### attributes +Gaussian splats can have a variety of shapes and this has the potential to change over time. The `shape` property is an optional property that provides an indication to the renderer what these shapes may be. Typically `ellipsoid` refers to the shape generally considered to be a "splat" and this is considered the default value. + +Renderers are free to ignore any values they do not recognize, but are encouraged to follow the non-normative list below. + +#### Known Shapes + +*This section is non-normative and not comprehensive. It may change over time.* + + - `ellipsoid` _(Default Value)_ + - `triangle` + - `quad` + +### Rendering Hints + +This extension provides a `hints` property that contains sub-properties that may help renderers understand how best to render the Gaussians to the screen. This property and all of it's sub-properties are optional, and renderers can choose to ignore them. + +#### Projection + +The `projection` property is an optional hint that specifies how the Gaussians should be projected into the image. This is typically provided by the training process for the splats. This is a freeform string field to allow new projections to be specified as they become available. The default value is `perspective`. + +Renderers are free to ignore any values they do not recognize, but are encouraged to follow the non-normative list below. + +##### Known Projection Methods + +*This section is non-normative and not comprehensive. It may change over time.* + + - `perspective` _(Default Value)_: The typical 3D perspective projection based on scene depth. + - `orthographic`: A orthogonal projection of splats into a scene to preserve shape and scale and reduce distortion. + +#### Sorting Method + +The `sortingMethod` property is an optional hint that specifies how the Gaussians should be sorted during the rendering process. This typically is provided by the training process for the splats. This is a freeform string field to allow new sorting methods to be specified as they become available. The default value is `cameraDistance`. + +Renderers are free to ignore any values they do not recognize, but are encouraged to follow the non-normative list below. + +##### Known Sorting Methods + +*This section is non-normative and not comprehensive. It may change over time.* + + - `cameraDistance` _(Default Value)_: The distance between the center of the splat and the position of the camera. + - `zDepth`: The projected z-depth in the camera projection. + +## Attributes Each 3D Gaussian splat has the following attributes. At minimum the attributes must contain `POSITION`, `COLOR_0`, `KHR_gaussian_splatting:ROTATION`, and `KHR_gaussian_splatting:SCALE`. `KHR_gaussian_splatting:SH_DEGREE_ℓ_COEF_n` attributes hold the spherical harmonics data and are not required. `POSITION` and `COLOR_0` are defined by the base glTF specification. If higher degrees of Spherical Harmonics are used then lower degrees are required implicitly. diff --git a/extensions/2.0/Khronos/KHR_gaussian_splatting/schema/mesh.primitive.KHR_gaussian_splatting.schema.json b/extensions/2.0/Khronos/KHR_gaussian_splatting/schema/mesh.primitive.KHR_gaussian_splatting.schema.json index 1e6e6405cb..f71298b352 100644 --- a/extensions/2.0/Khronos/KHR_gaussian_splatting/schema/mesh.primitive.KHR_gaussian_splatting.schema.json +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting/schema/mesh.primitive.KHR_gaussian_splatting.schema.json @@ -1,11 +1,36 @@ { - "$schema": "http://json-schema.org/draft-04/schema", - "title": "KHR_gaussian_splatting glTF Mesh Primitive Extension", - "type": "object", - "description": "Data for a 3D Gaussian Splat primitive.", - "allOf": [ { "$ref": "glTFProperty.schema.json" } ], - "properties": { - "extensions": { }, - "extras": { } + "$schema": "http://json-schema.org/draft-04/schema", + "title": "KHR_gaussian_splatting glTF Mesh Primitive Extension", + "type": "object", + "description": "Data for a 3D Gaussian Splat primitive.", + "allOf": [ + { + "$ref": "glTFProperty.schema.json" } + ], + "properties": { + "shape": { + "type": "string", + "description": "The shape of the Gaussian to render. Gaussians may be available in different shapes, so this is a freeform field that defaults to ellipsoid. See the extension specification for futher known types.", + "default": "ellipsoid" + }, + "hints": { + "type": "object", + "description": "Optional rendering hints for rendering the 3D Gaussian splats. Renderers are free to ignore any of these.", + "properties": { + "projection": { + "type": "string", + "description": "Provides a hint specifying how to project the Gaussians to achieve a perspective correct value. This is a freeform field that defaults to perspective. See the extension specification for further known types.", + "default": "perspective" + }, + "sortingMethod": { + "type": "string", + "description": "Provides a hint specifying how to sort the Gaussians during rendering. This is a freeform field defaulting to cameraDistance. See the extension specification for further known types.", + "default": "cameraDistance" + } + } + }, + "extensions": {}, + "extras": {} + } } From 81e73f1f367c05392dccfb150f1268448298abfb Mon Sep 17 00:00:00 2001 From: "Adam N. Morris" Date: Thu, 31 Jul 2025 17:28:23 -0500 Subject: [PATCH 6/7] Fixed a spot where I forgot to namespace the custom attributes --- .../2.0/Khronos/KHR_gaussian_splatting/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md b/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md index 4abe18454f..27b579d70e 100644 --- a/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting/README.md @@ -64,11 +64,11 @@ Example shown below including optional properties. This extension only affects a "attributes": { "POSITION": 0, "COLOR_0": 1, - "_SCALE": 2, - "_ROTATION": 3, - "_SH_DEGREE_1_COEF_0": 4, - "_SH_DEGREE_1_COEF_1": 5, - "_SH_DEGREE_1_COEF_2": 6 + "KHR_gaussian_splatting:SCALE": 2, + "KHR_gaussian_splatting:ROTATION": 3, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_0": 4, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_1": 5, + "KHR_gaussian_splatting:SH_DEGREE_1_COEF_2": 6 }, "mode": 0, "indices": 7, From e5f8ce1f520c4f72b0629e96919acb77548aeaa2 Mon Sep 17 00:00:00 2001 From: "Adam N. Morris" Date: Fri, 22 Aug 2025 12:06:52 -0500 Subject: [PATCH 7/7] Added explicit marking of the version for the SPZ library --- .../README.md | 4 ++-- ...tive.KHR_gaussian_splatting_compression_spz_2.schema.json} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename extensions/2.0/Khronos/{KHR_gaussian_splatting_compression_spz => KHR_gaussian_splatting_compression_spz_2}/README.md (95%) rename extensions/2.0/Khronos/{KHR_gaussian_splatting_compression_spz/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json => KHR_gaussian_splatting_compression_spz_2/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz_2.schema.json} (73%) diff --git a/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz_2/README.md similarity index 95% rename from extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md rename to extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz_2/README.md index 5471923ece..c9cee3d583 100644 --- a/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/README.md +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz_2/README.md @@ -1,4 +1,4 @@ -# KHR\_gaussian\_splatting\_spz\_compression +# KHR\_gaussian\_splatting\_compression\_spz\_2 ## Contributors @@ -36,7 +36,7 @@ Depends on the `KHR_gaussian_splatting` extension specification for attribute de ## Overview -This extension defines support for compressing 3D Gaussian splats stored within in glTF using the SPZ compression format for efficient streaming and storage. +This extension defines support for compressing 3D Gaussian splats stored within in glTF using [v2 of the SPZ compression format](https://github.com/nianticlabs/spz/tree/v2.0.0) for efficient streaming and storage. SPZ is a compression format from Niantic Spatial designed for Gaussian splats. Currently, it is open sourced under the MIT license. The SPZ format is primarily used in the Niantic Spatial Scaniverse app. It was purpose built for Gaussian splats and offers a balance of high compression with minimal visual fidelity loss, and allows for storing some or all of the 3D Gaussian's spherical harmonics. diff --git a/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz_2/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz_2.schema.json similarity index 73% rename from extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json rename to extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz_2/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz_2.schema.json index 244e79cf6f..2071946914 100644 --- a/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz.schema.json +++ b/extensions/2.0/Khronos/KHR_gaussian_splatting_compression_spz_2/schema/mesh.primitive.KHR_gaussian_splatting_compression_spz_2.schema.json @@ -1,8 +1,8 @@ { "$schema": "http://json-schema.org/draft-04/schema", - "title": "KHR_gaussian_splatting_compression_spz glTF Mesh Primitive Extension", + "title": "KHR_gaussian_splatting_compression_spz_2 glTF Mesh Primitive Extension", "type": "object", - "description": "Compressed data for SPZ primitive.", + "description": "Compressed data for SPZ v2 primitive.", "allOf": [ { "$ref": "glTFProperty.schema.json" } ], "properties": { "bufferView": {