diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index 1027338d6d..43e6e0193b 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -25,11 +25,6 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- # REUSE license checker
- - name: license-check
- run: |
- reuse lint
-
# Build spec targets
- name: spec-generate
run: |
diff --git a/.github/workflows/reuse.yml b/.github/workflows/reuse.yml
new file mode 100644
index 0000000000..126d91dd19
--- /dev/null
+++ b/.github/workflows/reuse.yml
@@ -0,0 +1,15 @@
+# Copyright 2022 The Khronos Group Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+name: REUSE Compliance
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: REUSE Compliance Check
+ uses: fsfe/reuse-action@v1.1.1
diff --git a/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md b/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
new file mode 100644
index 0000000000..31a7be9339
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
@@ -0,0 +1,168 @@
+# KHR\_materials\_emissive\_strength
+
+## Contributors
+
+* Mike Bond, Adobe, [@miibond](https://github.com/MiiBond)
+* Alex Jamerson, Amazon
+* Thomas Dideriksen, Amazon
+* Alex Wood, AGI, [@abwood](https://twitter.com/abwood)
+* Ed Mackey, AGI, [@emackey](https://twitter.com/emackey)
+* Nicolas Savva, Autodesk, [@nicolassavva-autodesk](https://github.com/nicolassavva-autodesk)
+* Henrik Edstrom, Autodesk
+* Tobias Haeussler, Dassault Systemes, [@proog128](https://github.com/proog128)
+* Bastian Sdorra, Dassault Systemes, [@bsdorra](https://github.com/bsdorra)
+* Emmett Lalish, Google, [@elalish](https://github.com/elalish)
+* Richard Sahlin, IKEA, [@rsahlin](https://github.com/rsahlin)
+* Alexey Knyazev, Individual Contributor, [@lexaknyazev](https://github.com/lexaknyazev)
+* Bruce Cherniak, Intel
+* Gary Hsu, Microsoft [@bghgary](https://twitter.com/bghgary)
+* Nicholas Barlow, Microsoft
+* Adam Morris, Target [@weegeekps](https://github.com/weegeekps)
+* Sandra Voelker, Target
+* Ben Houston, Threekit, [@bhouston](https://twitter.com/BenHouston3D)
+* Andreas Atteneder, Unity
+* Norbert Nopper, UX3D, [@UX3DGpuSoftware](https://twitter.com/UX3DGpuSoftware)
+* Eric Chadwick, Wayfair, [echadwick-wayfair](https://github.com/echadwick-wayfair)
+
+Copyright (C) 2021-2022 The Khronos Group Inc. All Rights Reserved. glTF is a trademark of The Khronos Group Inc.
+See [Appendix](#appendix-full-khronos-copyright-statement) for full Khronos Copyright Statement.
+
+## Status
+
+Complete, Ratified by the Khronos Group
+
+## Dependencies
+
+Written against the glTF 2.0 spec.
+
+## Exclusions
+
+* This extension must not be used on a material that also uses `KHR_materials_unlit`.
+
+## Overview
+
+The core glTF 2.0 material model includes an `emissiveFactor` and an `emissiveTexture` to control the color and
+intensity of the light being emitted by the material, clamped to the range [0.0, 1.0]. However, in PBR environments
+with high-dynamic range reflections and lighting, stronger emission effects may be desirable.
+
+In this extension, a new `emissiveStrength` scalar factor is supplied, that governs the upper limit of emissive
+strength per material.
+
+**Implementation Note**: This strength can be colored and tempered using the core material's `emissiveFactor`
+and `emissiveTexture` controls, permitting the strength to vary across the surface of the material.
+Supplying values above 1.0 for `emissiveStrength` can have an influence on
+reflections, tonemapping, blooming, and more.
+
+### Physical Units
+
+This extension supplies a unitless multiplier to the glTF 2.0 specification's emissive factor and
+texture. Including this multiplier does not alter the physical units defined in glTF 2.0's
+[additional textures section](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#additional-textures),
+under the **emissive** texture.
+
+## Extending Materials
+
+*This section is non-normative.*
+
+Any material with an `emissiveFactor` (and optionally an `emissiveTexture`) can have its strength modulated
+or amplified by the inclusion of this extension. For example:
+
+```json
+{
+ "materials": [
+ {
+ "emissiveFactor": [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "emissiveTexture": {
+ "index": 3
+ },
+ "extensions": {
+ "KHR_materials_emissive_strength": {
+ "emissiveStrength": 5.0
+ }
+ }
+ }
+ ]
+}
+```
+
+In the above example, the `emissiveFactor` has been set to its maximum value, to enable the `emissiveTexture`.
+The `emissiveStrength` has been set to 5.0, making the texture five times brighter than it otherwise
+would have been.
+
+### Parameters
+
+The following parameters are contributed by the `KHR_materials_emissive_strength` extension:
+
+| Name | Type | Description | Required |
+|------------------------|------------|-------------------------------------------------------------------------------|--------------------|
+| **emissiveStrength** | `number` | The strength adjustment to be multiplied with the material's emissive value. | No, default: `1.0` |
+
+
+## Implementation Notes
+
+*This section is non-normative.*
+
+A typical (pseudocode) implementation might look like the following:
+
+```
+color += emissiveFactor.rgb * sRGB_to_Linear(emissiveTexture.rgb) * emissiveStrength;
+```
+
+## Schema
+
+- [glTF.KHR_materials_emissive_strength.schema.json](schema/glTF.KHR_materials_emissive_strength.schema.json)
+
+## Appendix: Full Khronos Copyright Statement
+
+Copyright 2021-2022 The Khronos Group Inc.
+
+This specification is protected by copyright laws and contains material proprietary
+to Khronos. Except as described by these terms, it or any components
+may not be reproduced, republished, distributed, transmitted, displayed, broadcast,
+or otherwise exploited in any manner without the express prior written permission
+of Khronos.
+
+This specification has been created under the Khronos Intellectual Property Rights
+Policy, which is Attachment A of the Khronos Group Membership Agreement available at
+https://www.khronos.org/files/member_agreement.pdf. Khronos grants a conditional
+copyright license to use and reproduce the unmodified specification for any purpose,
+without fee or royalty, EXCEPT no licenses to any patent, trademark or other
+intellectual property rights are granted under these terms. Parties desiring to
+implement the specification and make use of Khronos trademarks in relation to that
+implementation, and receive reciprocal patent license protection under the Khronos
+IP Policy must become Adopters under the process defined by Khronos for this specification;
+see https://www.khronos.org/conformance/adopters/file-format-adopter-program.
+
+Some parts of this Specification are purely informative and do not define requirements
+necessary for compliance and so are outside the Scope of this Specification. These
+parts of the Specification are marked as being non-normative, or identified as
+**Implementation Notes**.
+
+Where this Specification includes normative references to external documents, only the
+specifically identified sections and functionality of those external documents are in
+Scope. Requirements defined by external documents not created by Khronos may contain
+contributions from non-members of Khronos not covered by the Khronos Intellectual
+Property Rights Policy.
+
+Khronos makes no, and expressly disclaims any, representations or warranties,
+express or implied, regarding this specification, including, without limitation:
+merchantability, fitness for a particular purpose, non-infringement of any
+intellectual property, correctness, accuracy, completeness, timeliness, and
+reliability. Under no circumstances will Khronos, or any of its Promoters,
+Contributors or Members, or their respective partners, officers, directors,
+employees, agents or representatives be liable for any damages, whether direct,
+indirect, special or consequential damages for lost revenues, lost profits, or
+otherwise, arising from or in connection with these materials.
+
+Khronos® and Vulkan® are registered trademarks, and ANARI™, WebGL™, glTF™, NNEF™, OpenVX™,
+SPIR™, SPIR‑V™, SYCL™, OpenVG™ and 3D Commerce™ are trademarks of The Khronos Group Inc.
+OpenXR™ is a trademark owned by The Khronos Group Inc. and is registered as a trademark in
+China, the European Union, Japan and the United Kingdom. OpenCL™ is a trademark of Apple Inc.
+and OpenGL® is a registered trademark and the OpenGL ES™ and OpenGL SC™ logos are trademarks
+of Hewlett Packard Enterprise used under license by Khronos. ASTC is a trademark of
+ARM Holdings PLC. All other product names, trademarks, and/or company names are used solely
+for identification and belong to their respective owners.
diff --git a/extensions/2.0/Khronos/KHR_materials_emissive_strength/schema/glTF.KHR_materials_emissive_strength.schema.json b/extensions/2.0/Khronos/KHR_materials_emissive_strength/schema/glTF.KHR_materials_emissive_strength.schema.json
new file mode 100644
index 0000000000..49a35e8b3d
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_materials_emissive_strength/schema/glTF.KHR_materials_emissive_strength.schema.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema",
+ "title": "KHR_materials_emissive_strength glTF extension",
+ "type": "object",
+ "description": "glTF extension that adjusts the strength of emissive material properties.",
+ "allOf": [ { "$ref": "glTFProperty.schema.json" } ],
+ "properties": {
+ "emissiveStrength": {
+ "type": "number",
+ "description": "The strength adjustment to be multiplied with the material's emissive value.",
+ "default": 1.0,
+ "minimum": 0.0
+ },
+ "extensions": { },
+ "extras": { }
+ }
+}
diff --git a/extensions/2.0/Khronos/KHR_materials_iridescence/README.md b/extensions/2.0/Khronos/KHR_materials_iridescence/README.md
new file mode 100644
index 0000000000..a3bdf49e26
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_materials_iridescence/README.md
@@ -0,0 +1,475 @@
+# KHR\_materials\_iridescence
+
+## Contributors
+
+* Pascal Schoen, Adidas
+* Tobias Haeussler, Dassault Systemes [@proog128](https://github.com/proog128)
+* Ben Houston, Threekit, [@bhouston](https://twitter.com/BenHouston3D)
+* Mathias Kanzler, UX3D
+* Norbert Nopper, UX3D [@UX3DGpuSoftware](https://twitter.com/UX3DGpuSoftware)
+* Jim Eckerlein, UX3D
+* Alexey Knyazev, Individual Contributor, [@lexaknyazev](https://github.com/lexaknyazev)
+* Eric Chadwick, Wayfair, [echadwick-wayfair](https://github.com/echadwick-wayfair)
+* Alex Wood, AGI [@abwood](https://twitter.com/abwood)
+* Ed Mackey, AGI [@emackey](https://twitter.com/emackey)
+
+Copyright (C) 2018-2022 The Khronos Group Inc. All Rights Reserved. glTF is a trademark of The Khronos Group Inc.
+See [Appendix](#appendix-full-khronos-copyright-statement) for full Khronos Copyright Statement.
+
+## Status
+
+Complete, Ratified by the Khronos Group
+
+## Dependencies
+
+Written against the glTF 2.0 spec.
+
+## Exclusions
+
+* This extension must not be used on a material that also uses `KHR_materials_pbrSpecularGlossiness`.
+* This extension must not be used on a material that also uses `KHR_materials_unlit`.
+
+## Overview
+
+Iridescence describes an effect where hue varies depending on the viewing angle and illumination angle: A thin-film of a semi-transparent layer results in inter-reflections and due to thin-film interference, certain wavelengths get absorbed or amplified. Iridescence can be seen on soap bubbles, oil films, or on the wings of many insects.
+With this extension, thickness and index of refraction (IOR) of the thin-film can be specified, enabling iridescent materials.
+
+## Extending Materials
+
+The iridescence materials are defined by adding the `KHR_materials_iridescence` extension to any glTF material.
+
+```json
+{
+ "materials": [
+ {
+ "extensions": {
+ "KHR_materials_iridescence": {
+ "iridescenceFactor": 1.0,
+ "iridescenceIor": 1.3,
+ "iridescenceThicknessMaximum": 400.0
+ }
+ }
+ }
+ ]
+}
+```
+
+## Properties
+
+All implementations should use the same calculations for the BRDF inputs. Implementations of the BRDF itself can vary based on device performance and resource constraints. See [appendix](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#appendix-b-brdf-implementation) for more details on the BRDF calculations.
+
+| | Type | Description | Required |
+| ------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------| ------------------- |
+| **iridescenceFactor** | `number` | The iridescence intensity factor. | No, default:`0.0` |
+| **iridescenceTexture** | [`textureInfo`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-textureinfo) | The iridescence intensity texture. | No |
+| **iridescenceIor** | `number` | The index of refraction of the dielectric thin-film layer. | No, default:`1.3` |
+| **iridescenceThicknessMinimum** | `number` | The minimum thickness of the thin-film layer given in nanometers. | No, default:`100.0` |
+| **iridescenceThicknessMaximum** | `number` | The maximum thickness of the thin-film layer given in nanometers. | No, default:`400.0` |
+| **iridescenceThicknessTexture** | [`textureInfo`](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#reference-textureinfo) | The thickness texture of the thin-film layer. | No |
+
+The values for iridescence intensity can be defined using a factor, a texture, or both.
+`iridescenceFactor` is multiplied with the red channel of `iridescenceTexture` to control the overall strength of the iridescence effect. If the texture is not set, a value of 1.0 is assumed for the texture.
+
+```glsl
+iridescence = iridescenceFactor * iridescenceTexture.r
+```
+
+If `iridescenceFactor` is zero (default), the iridescence extension has no effect on the material.
+All textures in this extension use a single channel in linear space.
+The thickness of the thin-film is set to `iridescenceThicknessMaximum` if `iridescenceThicknessTexture` is not given.
+If `iridescenceThicknessTexture` is set, the thickness of the thin-film varies between `iridescenceThicknessMinimum` and `iridescenceThicknessMaximum` as follows:
+
+```glsl
+thickness = mix(iridescenceThicknessMinimum, iridescenceThicknessMaximum, iridescenceThicknessTexture.g)
+```
+
+Aside from light direction and IOR, the thickness of the thin-film defines the variation in hue.
+This effect is the result of constructive and destructive interferences of certain wavelengths.
+If the the optical path difference between the ray reflected at the thin-film and the ray reflected at the base material is half the wavelength (λ), the resulting 180 degree phase shift is cancelling out the reflected light:
+
+
+
+
+
+
+With a thin-film thickness near half the wavelength of visible light (380 nm - 750 nm), the effect is most visible.
+By increasing the thin-film thickness, multiples of wavelengths are still causing wave interferences, however, as the optical path distance increases, different rays are mixed in.
+This leads to more pastel colored patterns for increased thickness:
+
+
+
+Comparison of different iridescence thickness ranges for a constant iridescence IOR value of 1.3 on a dielectric base material with IOR value of 1.5.
+
+
+The thin-film layer can have a different IOR than the underlying material. With `iridescenceIor` one can set an IOR value for the thin-film layer independently. The more this value differs from the IOR of the base material, the stronger the iridescence. It also has an effect on the optical path difference as visible here:
+
+
+
+Comparison of different iridescence IOR values for a thin-film thickness range between 200 nm (bottom) and 800 nm (top) on a dielectric base material with IOR value of 1.5.
+
+
+The iridescence effect is modeled via a microfacet BRDF with a modified Fresnel reflectance term that accounts for inter-reflections as shown in the paper from [Belcour/Barla](#theory-documentation-and-implementations).
+
+## Iridescence BRDF
+
+### Metal Base Material
+
+The metal BRDF in the glTF 2.0 core specification in [B.2.1. Metals](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#metals) will be replaced by the following term:
+
+```
+metal_brdf =
+ iridescent_conductor_layer(
+ iridescence_strength = iridescence,
+ iridescence_thickness = iridescenceThickness,
+ iridescence_ior = iridescenceIor,
+ outside_ior = 1.0,
+ base_f0 = baseColor,
+ specular_brdf = specular_brdf(
+ α = roughness ^ 2))
+```
+
+### Dielectric Base Material
+
+The dielectric BRDF in the glTF 2.0 core specification in [B.2.2. Dielectrics](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#dielectrics) will be replaced by the following term:
+
+```
+dielectric_brdf =
+ iridescent_dielectric_layer(
+ iridescence_strength = iridescence,
+ iridescence_thickness = iridescenceThickness,
+ iridescence_ior = iridescenceIor,
+ outside_ior = 1.0,
+ base_ior = 1.5,
+ base = diffuse_brdf(
+ color = baseColor),
+ specular_brdf = specular_brdf(
+ α = roughness ^ 2))
+```
+
+For transmissive `base` materials, the `diffuse_brdf(...)` will be replaced by the mix between a `diffuse_brdf(...)` and a `specular_btdf(...)` as described in the [`KHR_materials_transmission`](../KHR_materials_transmission#transmission-btdf) extension.
+
+The `base_ior` can be changed using the [`KHR_materials_ior`](../KHR_materials_ior) extension.
+
+In case of combining `KHR_materials_iridescence` with [`KHR_materials_specular`](../KHR_materials_specular/README.md), `dielectric_brdf` becomes the following:
+
+```
+dielectric_brdf =
+ iridescent_dielectric_layer(
+ iridescence_strength = iridescence,
+ iridescence_thickness = iridescenceThickness,
+ iridescence_ior = iridescenceIor,
+ outside_ior = 1.0,
+ base_ior = 1.5,
+ base_f0_color = specularColor.rgb,
+ specular_weight = specular,
+ base = diffuse_brdf(
+ color = baseColor),
+ specular_brdf = specular_brdf(
+ α = roughness ^ 2))
+```
+
+### Clearcoat
+
+When adding a clearcoat ontop, an additional interface between the clearcoat and thin-film layer would be created. Due to simplicity and artistical friendlyness, this interface is ignored.
+
+## Implementation Notes
+
+### Metal Base Material
+
+```
+function iridescent_conductor_layer(iridescence_strength, iridescence_thickness, iridescence_ior, outside_ior, base_f0, specular_brdf) {
+ return mix(
+ conductor_fresnel(base_f0, specular_brdf),
+ specular_brdf * iridescent_fresnel(
+ outside_ior,
+ iridescence_ior,
+ base_f0,
+ iridescence_thickness),
+ iridescence_strength)
+}
+```
+
+### Dielectric Base Material
+
+```
+function iridescent_dielectric_layer(iridescence_strength, iridescence_thickness, iridescence_ior, outside_ior, base_ior, base, specular_brdf) {
+ base_f0 = ((1-base_ior)/(1+base_ior))^2
+
+ iridescent_f = iridescent_fresnel(
+ outside_ior,
+ iridescence_ior,
+ base_f0,
+ iridescence_thickness)
+
+ return mix(
+ fresnel_mix(base_ior, base, specular_brdf),
+ rgb_mix(base, specular_brdf, iridescent_f),
+ iridescence_strength)
+}
+```
+
+Similar to [`KHR_materials_specular`](../KHR_materials_specular/README.md#implementation), to ensure energy conservation, the base BRDF is weighted with the inverse of the maximum component value of the iridescence Fresnel color and then added with the specular iridescence BRDF inside the `rgb_mix()` function:
+
+```
+function rgb_mix(base, specular_brdf, rgb_alpha) {
+ rgb_alpha_max = max(rgb_alpha.r, rgb_alpha.g, rgb_alpha.b)
+
+ return (1 - rgb_alpha_max) * base + rgb_alpha * specular_brdf
+}
+```
+
+If instead `1 - rgb_alpha` would be used directly, inverse colors would be created. By using the maximum component value, no energy would be gained.
+
+When using this extension together with the [`KHR_materials_specular`](../KHR_materials_specular/README.md#implementation) extension the `iridescent_dielectric_layer()` function changes slightly (as already pointed out in the previous section):
+
+```
+function iridescent_dielectric_layer(iridescence_strength, iridescence_thickness, iridescence_ior, outside_ior, base_ior, base_f0_color, specular_weight, base, specular_brdf) {
+ base_f0 = ((1-base_ior)/(1+base_ior))^2 * base_f0_color
+ base_f0 = min(base_f0, float3(1.0))
+ fr = base_f0 + (1 - base_f0)*(1 - abs(VdotH))^5
+
+ iridescent_f = iridescent_fresnel(
+ outside_ior,
+ iridescence_ior,
+ specular_weight * base_f0,
+ iridescence_thickness)
+
+ return rgb_mix(
+ base,
+ specular_brdf,
+ mix(specular_weight * fr, iridescent_f, iridescence_strength))
+}
+```
+
+The two additional parameters `base_f0_color` and `specular_weight` correspond to `f0_color` and `weight` of the `dielectric_brdf` in [`KHR_materials_specular`](../KHR_materials_specular/README.md#extending-materials).
+
+### Iridescence Fresnel
+
+*This section is non-normative.*
+
+The calculation of `iridescent_fresnel(...)` is described in the following sections as GLSL code at the viewing angle . For glTF an approximation of the original model (defined in the Mitsuba code example from [Belcour/Barla](#theory-documentation-and-implementations)) is used.
+
+```glsl
+vec3 iridescent_fresnel(outsideIor, iridescenceIor, baseF0, iridescenceThickness, cosTheta1) {
+ vec3 F_iridescence = vec3(0.0);
+
+ // Calculation of the iridescence Fresnel for the viewing angle theta1
+ ...
+
+ return F_iridescence;
+}
+```
+
+#### **Material Interfaces**
+
+The iridescence model defined by [Belcour/Barla](#theory-documentation-and-implementations) models two material interfaces - one from the outside to the thin-film layer and another one from the thin-film to the base material. These two interfaces are defined as follows:
+
+```glsl
+// First interface
+float R0 = IorToFresnel0(iridescenceIor, outsideIor);
+float R12 = F_Schlick(R0, cosTheta1);
+float R21 = R12;
+float T121 = 1.0 - R12;
+
+// Second interface
+vec3 baseIor = Fresnel0ToIor(baseF0 + 0.0001); // guard against 1.0
+vec3 R1 = IorToFresnel0(baseIor, iridescenceIor);
+vec3 R23 = F_Schlick(R1, cosTheta2);
+```
+
+`iridescenceIor` is the index of refraction of the thin-film layer, `outsideIor` the IOR outside the thin-film (usually air) and `baseIor` the IOR of the base material. The latter is calculated from its F0 value using the inverse of the special normal incidence case of Fresnel's equations:
+
+```glsl
+// Assume air interface for top
+vec3 Fresnel0ToIor(vec3 F0) {
+ vec3 sqrtF0 = sqrt(F0);
+ return (vec3(1.0) + sqrtF0) / (vec3(1.0) - sqrtF0);
+}
+```
+
+This simple formula is used for both dielectrics and metals. While it is physically correct for dielectric materials, it's only an approximation for metals, which are usually described using a complex IOR with an additional extinction factor. Such a value cannot be accurately inferred from the F0 value and is thus assumed to be `0.0`.
+
+To calculate the reflectance factors at normal incidence of both interfaces (`R0` and `R1`), the special case is used as is:
+
+
+
+```glsl
+float IorToFresnel0(float transmittedIor, float incidentIor) {
+ return pow((transmittedIor - incidentIor) / (transmittedIor + incidentIor), 2.0);
+}
+```
+
+To calculate the reflectances `R12` and `R23` at the viewing angles (angle hitting the thin-film layer) and (angle after refraction in the thin-film) Schlick Fresnel is again used. This approximation allows to eliminate the split into S and P polarization for the exact Fresnel equations.
+
+ can be calculated using Snell's law (with being `outsideIor` and being `iridescenceIor`):
+
+
+
+```glsl
+float sinTheta2Sq = pow(outsideIor / iridescenceIor, 2.0) * (1.0 - pow(cosTheta1, 2.0));
+float cosTheta2Sq = 1.0 - sinTheta2Sq;
+
+// Handle total internal reflection
+if (cosTheta2Sq < 0.0) {
+ return vec3(1.0);
+}
+
+float cosTheta2 = sqrt(cosTheta2Sq);
+```
+
+#### **Phase Shift**
+
+The phase shift is as follows:
+
+
+
+and depends on the first-order optical path difference (or `OPD`):
+
+```glsl
+OPD = 2.0 * iridescenceIor * iridescenceThickness * cosTheta1;
+```
+
+`phi12` and `phi23` define the base phases per interface and are approximated with `0.0` if the IOR of the hit material (`iridescenceIor` or `baseIor`) is higher than the IOR of the previous material (`outsideIor` or `iridescenceIor`) and *π* otherwise. Also here, polarization is ignored.
+
+```glsl
+// First interface
+float phi12 = 0.0;
+if (iridescenceIor < outsideIor) phi12 = M_PI;
+float phi21 = M_PI - phi12;
+
+// Second interface
+vec3 phi23 = vec3(0.0);
+if (baseIor[0] < iridescenceIor) phi23[0] = M_PI;
+if (baseIor[1] < iridescenceIor) phi23[1] = M_PI;
+if (baseIor[2] < iridescenceIor) phi23[2] = M_PI;
+
+// Phase shift
+vec3 phi = vec3(phi21) + phi23;
+```
+
+#### **Analytic Spectral Integration**
+
+Spectral integration is performed in the Fourier space.
+
+```glsl
+// Compound terms
+vec3 R123 = clamp(R12 * R23, 1e-5, 0.9999);
+vec3 r123 = sqrt(R123);
+vec3 Rs = sq(T121) * R23 / (vec3(1.0) - R123);
+
+// Reflectance term for m = 0 (DC term amplitude)
+vec3 C0 = R12 + Rs;
+I = C0;
+
+// Reflectance term for m > 0 (pairs of diracs)
+vec3 Cm = Rs - T121;
+for (int m = 1; m <= 2; ++m)
+{
+ Cm *= r123;
+ vec3 Sm = 2.0 * evalSensitivity(float(m) * OPD, float(m) * phi);
+ I += Cm * Sm;
+}
+
+F_iridescence = max(I, vec3(0.0));
+```
+
+With the sensitivity evaluation function being:
+
+```glsl
+vec3 evalSensitivity(float OPD, vec3 shift) {
+ float phase = 2.0 * M_PI * OPD * 1.0e-9;
+ vec3 val = vec3(5.4856e-13, 4.4201e-13, 5.2481e-13);
+ vec3 pos = vec3(1.6810e+06, 1.7953e+06, 2.2084e+06);
+ vec3 var = vec3(4.3278e+09, 9.3046e+09, 6.6121e+09);
+
+ vec3 xyz = val * sqrt(2.0 * M_PI * var) * cos(pos * phase + shift) * exp(-sq(phase) * var);
+ xyz.x += 9.7470e-14 * sqrt(2.0 * M_PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift[0]) * exp(-4.5282e+09 * sq(phase));
+ xyz /= 1.0685e-7;
+
+ vec3 rgb = XYZ_TO_REC709 * xyz;
+ return rgb;
+}
+```
+
+and the color space transformation matrix to convert from XYZ to RGB:
+
+```glsl
+const mat3 XYZ_TO_REC709 = mat3(
+ 3.2404542, -0.9692660, 0.0556434,
+ -1.5371385, 1.8760108, -0.2040259,
+ -0.4985314, 0.0415560, 1.0572252
+);
+```
+
+The full derivation of the fast analytical spectral integration is described in the original publication in section 4 (Analytical Spectral Integration) and will not be described in detail here.
+
+## Reference
+
+### Theory, Documentation and Implementations
+
+[Belcour, L. and Barla, P. (2017): A Practical Extension to Microfacet Theory for the Modeling of Varying Iridescence](https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html)
+
+[Autodesk: Arnold for Maya user guide - Thin Film](https://docs.arnoldrenderer.com/display/A5AFMUG/Thin+Film)
+
+[Drobot, M. and Micciulla, A. (2017): Practical Multilayered Materials in Call of Duty: Infinite Warfare](https://blog.selfshadow.com/publications/s2017-shading-course/drobot/s2017_pbs_multilayered.pdf)
+
+[Kneiphof, T., Golla, T. and Klein, R. (2019): Real-time Image-based Lighting of Microfacet BRDFs with Varying Iridescence](https://cg.cs.uni-bonn.de/publication/kneiphof-2019-real-time)
+
+[Akenine-Möller, T., Haines, E., Hoffman, N., Pesce, A., Iwanicki, M., and Hillaire, S. (2018): Real-Time Rendering, Fourth Edition; page 361ff](https://www.realtimerendering.com/)
+
+[Sussenbach, M. (2013): Rendering Iridescent Objects in Real-time](http://dspace.library.uu.nl/handle/1874/287110)
+
+## Schema
+
+[glTF.KHR_materials_iridescence.schema.json](schema/glTF.KHR_materials_iridescence.schema.json)
+
+## Appendix: Full Khronos Copyright Statement
+
+Copyright 2018-2022 The Khronos Group Inc.
+
+This specification is protected by copyright laws and contains material proprietary
+to Khronos. Except as described by these terms, it or any components
+may not be reproduced, republished, distributed, transmitted, displayed, broadcast,
+or otherwise exploited in any manner without the express prior written permission
+of Khronos.
+
+This specification has been created under the Khronos Intellectual Property Rights
+Policy, which is Attachment A of the Khronos Group Membership Agreement available at
+https://www.khronos.org/files/member_agreement.pdf. Khronos grants a conditional
+copyright license to use and reproduce the unmodified specification for any purpose,
+without fee or royalty, EXCEPT no licenses to any patent, trademark or other
+intellectual property rights are granted under these terms. Parties desiring to
+implement the specification and make use of Khronos trademarks in relation to that
+implementation, and receive reciprocal patent license protection under the Khronos
+IP Policy must become Adopters under the process defined by Khronos for this specification;
+see https://www.khronos.org/conformance/adopters/file-format-adopter-program.
+
+Some parts of this Specification are purely informative and do not define requirements
+necessary for compliance and so are outside the Scope of this Specification. These
+parts of the Specification are marked as being non-normative, or identified as
+**Implementation Notes**.
+
+Where this Specification includes normative references to external documents, only the
+specifically identified sections and functionality of those external documents are in
+Scope. Requirements defined by external documents not created by Khronos may contain
+contributions from non-members of Khronos not covered by the Khronos Intellectual
+Property Rights Policy.
+
+Khronos makes no, and expressly disclaims any, representations or warranties,
+express or implied, regarding this specification, including, without limitation:
+merchantability, fitness for a particular purpose, non-infringement of any
+intellectual property, correctness, accuracy, completeness, timeliness, and
+reliability. Under no circumstances will Khronos, or any of its Promoters,
+Contributors or Members, or their respective partners, officers, directors,
+employees, agents or representatives be liable for any damages, whether direct,
+indirect, special or consequential damages for lost revenues, lost profits, or
+otherwise, arising from or in connection with these materials.
+
+Khronos® and Vulkan® are registered trademarks, and ANARI™, WebGL™, glTF™, NNEF™, OpenVX™,
+SPIR™, SPIR‑V™, SYCL™, OpenVG™ and 3D Commerce™ are trademarks of The Khronos Group Inc.
+OpenXR™ is a trademark owned by The Khronos Group Inc. and is registered as a trademark in
+China, the European Union, Japan and the United Kingdom. OpenCL™ is a trademark of Apple Inc.
+and OpenGL® is a registered trademark and the OpenGL ES™ and OpenGL SC™ logos are trademarks
+of Hewlett Packard Enterprise used under license by Khronos. ASTC is a trademark of
+ARM Holdings PLC. All other product names, trademarks, and/or company names are used solely
+for identification and belong to their respective owners.
diff --git a/extensions/2.0/Khronos/KHR_materials_iridescence/figures/interference.png b/extensions/2.0/Khronos/KHR_materials_iridescence/figures/interference.png
new file mode 100644
index 0000000000..bee28a08cd
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_materials_iridescence/figures/interference.png differ
diff --git a/extensions/2.0/Khronos/KHR_materials_iridescence/figures/ior-comparison.png b/extensions/2.0/Khronos/KHR_materials_iridescence/figures/ior-comparison.png
new file mode 100644
index 0000000000..4a7c1f2144
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_materials_iridescence/figures/ior-comparison.png differ
diff --git a/extensions/2.0/Khronos/KHR_materials_iridescence/figures/thickness-comparison.png b/extensions/2.0/Khronos/KHR_materials_iridescence/figures/thickness-comparison.png
new file mode 100644
index 0000000000..15436e7f9f
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_materials_iridescence/figures/thickness-comparison.png differ
diff --git a/extensions/2.0/Khronos/KHR_materials_iridescence/schema/glTF.KHR_materials_iridescence.schema.json b/extensions/2.0/Khronos/KHR_materials_iridescence/schema/glTF.KHR_materials_iridescence.schema.json
new file mode 100644
index 0000000000..4410f8442f
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_materials_iridescence/schema/glTF.KHR_materials_iridescence.schema.json
@@ -0,0 +1,48 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema",
+ "title": "KHR_materials_iridescence glTF extension",
+ "type": "object",
+ "description": "glTF extension that defines an iridescence effect.",
+ "allOf": [ { "$ref": "glTFProperty.schema.json" } ],
+ "properties": {
+ "iridescenceFactor": {
+ "type": "number",
+ "description": "The iridescence intensity factor.",
+ "default": 0.0,
+ "minimum": 0.0,
+ "maximum": 1.0
+ },
+ "iridescenceTexture": {
+ "allOf": [ { "$ref": "textureInfo.schema.json" } ],
+ "description": "The iridescence intensity texture.",
+ "gltf_detailedDescription": "The iridescence intensity texture. The values are sampled from the R channel. These values are linear. If a texture is not given, a value of `1.0` **MUST** be assumed. If other channels are present (GBA), they are ignored for iridescence intensity calculations."
+ },
+ "iridescenceIor": {
+ "type": "number",
+ "description": "The index of refraction of the dielectric thin-film layer.",
+ "default": 1.3,
+ "minimum": 1.0
+ },
+ "iridescenceThicknessMinimum": {
+ "type": "number",
+ "description": "The minimum thickness of the thin-film layer given in nanometers.",
+ "default": 100.0,
+ "minimum": 0.0,
+ "gltf_detailedDescription": "The minimum thickness of the thin-film layer given in nanometers. The value **MUST** be less than or equal to the value of `iridescenceThicknessMaximum`."
+ },
+ "iridescenceThicknessMaximum": {
+ "type": "number",
+ "description": "The maximum thickness of the thin-film layer given in nanometers.",
+ "default": 400.0,
+ "minimum": 0.0,
+ "gltf_detailedDescription": "The maximum thickness of the thin-film layer given in nanometers. The value **MUST** be greater than or equal to the value of `iridescenceThicknessMinimum`."
+ },
+ "iridescenceThicknessTexture": {
+ "allOf": [ { "$ref": "textureInfo.schema.json" } ],
+ "description": "The thickness texture of the thin-film layer.",
+ "gltf_detailedDescription": "The thickness texture of the thin-film layer to linearly interpolate between the minimum and maximum thickness given by the corresponding properties, where a sampled value of `0.0` represents the minimum thickness and a sampled value of `1.0` represents the maximum thickness. The values are sampled from the G channel. These values are linear. If a texture is not given, the maximum thickness **MUST** be assumed. If other channels are present (RBA), they are ignored for thickness calculations."
+ },
+ "extensions": { },
+ "extras": { }
+ }
+}
diff --git a/extensions/2.0/Khronos/KHR_materials_specular/README.md b/extensions/2.0/Khronos/KHR_materials_specular/README.md
index 751cf337c0..0ea6abbabd 100644
--- a/extensions/2.0/Khronos/KHR_materials_specular/README.md
+++ b/extensions/2.0/Khronos/KHR_materials_specular/README.md
@@ -96,7 +96,7 @@ dielectric_brdf =
layer = specular_brdf(α = roughness^2))
```
-The `fresnel_mix` function mixes two BSDFs according to a Fresnel term. The `layer` is weighted with `weight * fresnel(ior, f0_color)`. The `base` is weighted with `1 - weight * fresnel(ior, f0_color)`.
+The `fresnel_mix` function mixes two BSDFs according to a Fresnel term. The `layer` is weighted with `weight * fresnel(ior, f0_color)`. The `base` is weighted with `1 - weight * max_value(fresnel(ior, f0_color))`.
The specular factor used as `weight` scales `layer` and `base`. The less energy is reflected by the `layer` (`specular_brdf`), the more can be shifted to the `base` (`diffuse_brdf`). The following image shows specular factor increasing from 0 to 1.
@@ -104,7 +104,15 @@ The specular factor used as `weight` scales `layer` and `base`. The less energy
The specular color is a directional-dependent weight included in the Fresnel term. At normal incidence (`f0`), `specularColor` scales the F0 reflectance `f0_color`. At grazing incidence (`f90`), the reflectance remains at 1. In between the scale factor is smoothly interpolated.
-As with specular factor, `base` will be weighted with the directional-dependent remaining energy according to the Fresnel term. `f0_color` is an RGB color, involving the complementary to specular color. To make it easy to use and ensure energy conservation, the RGB color is converted to scalar via `max(r, g, b)`. The following images show specular color increasing from [0,0,0] to [1,1,1] (top) and from [0,0,0] to [1,0,0] (bottom).
+As with specular factor, `base` will be weighted with the directional-dependent remaining energy according to the Fresnel term. `f0_color` is an RGB color, involving the complementary to specular color. To avoid inverse colors and ensure energy conservation, the RGB color is converted to scalar via `max(r, g, b)`:
+
+```
+function max_value(vec3 color) {
+ return max(color.r, color.g, color.b)
+}
+```
+
+The following images show specular color increasing from [0,0,0] to [1,1,1] (top) and from [0,0,0] to [1,0,0] (bottom).
![](figures/specular-color.png)
![](figures/specular-color-2.png)
@@ -122,7 +130,7 @@ function fresnel_mix(f0_color, ior, weight, base, layer) {
f0 = ((1-ior)/(1+ior))^2 * f0_color
f0 = min(f0, float3(1.0))
fr = f0 + (1 - f0)*(1 - abs(VdotH))^5
- return mix(base, layer, weight * fr)
+ return (1 - weight * max_value(fr)) * base + weight * fr * layer
}
```
diff --git a/extensions/2.0/Khronos/KHR_materials_transmission/README.md b/extensions/2.0/Khronos/KHR_materials_transmission/README.md
index cec60fa6df..d882602962 100644
--- a/extensions/2.0/Khronos/KHR_materials_transmission/README.md
+++ b/extensions/2.0/Khronos/KHR_materials_transmission/README.md
@@ -180,33 +180,47 @@ Optical transparency does not require any changes whatsoever to the specular ter
The specular transmission `specular_btdf(α)` is a microfacet BTDF
-
+$$
+\text{MicrofacetBTDF} = \frac{G_T D_T}{4 \left|N \cdot L \right| \left| N \cdot V \right|}
+$$
with the Trowbridge-Reitz/GGX microfacet distribution
-
+$$
+D_T = \frac{\alpha^2 \chi^+(N \cdot H_T)}{\pi ((N \cdot H_T)^2 (\alpha^2 - 1) + 1)^2}
+$$
and the separable form of the Smith joint masking-shadowing function
-,
+$$
+G_T = \frac{2 \left| N \cdot L \right| \chi^+\left(\frac{H_T \cdot L}{N \cdot L}\right)}{\left| N \cdot L \right| + \sqrt{\alpha^2 + (1 - \alpha^2) (N \cdot L)^2}} \frac{2 \left| N \cdot V \right| \chi^+\left(\frac{H_T \cdot V}{N \cdot V}\right)}{\left| N \cdot V \right| + \sqrt{\alpha^2 + (1 - \alpha^2) (N \cdot V)^2}}
+$$
-using the transmission half vector *H**T*
+using the transmission half vector $H_T$
-.
+$$
+H_T = \text{normalize}(V + 2 \left| N \cdot L \right| N + L)
+$$
-With the step function χ+ we ensure that the microsurface is only visible for directions that are on the same side of the macro and microsurfaces. Macro and microsurfaces are oriented according to *N* and *H**T*, respectively.
+With the step function $\chi^+$ we ensure that the microsurface is only visible for directions that are on the same side of the macro and microsurfaces. Macro and microsurfaces are oriented according to $N$ and $H_T$, respectively.
Introducing the visibility function
-
+$$
+V_T = \frac{G_T}{4 \left| N \cdot L \right| \left| N \cdot V \right|}
+$$
simplifies the original microfacet BTDF to
-
+$$
+\text{MicrofacetBTDF} = V_T D_T
+$$
with
-.
+$$
+V_T = \frac{\chi^+\left(\frac{H_T \cdot L}{N \cdot L}\right)}{\left| N \cdot L\right| + \sqrt{\alpha^2 + (1 - \alpha^2) (N \cdot L)^2}} \frac{\chi^+\left(\frac{H_T \cdot V}{N \cdot V}\right)}{\left| N \cdot V \right| + \sqrt{\alpha^2 + (1 - \alpha^2) (N \cdot V)^2}}
+$$
Thus we have the function
diff --git a/extensions/2.0/Khronos/KHR_materials_variants/schema/glTF.KHR_materials_variants.schema.json b/extensions/2.0/Khronos/KHR_materials_variants/schema/glTF.KHR_materials_variants.schema.json
index 1d5fb000ab..cf0108d6ff 100644
--- a/extensions/2.0/Khronos/KHR_materials_variants/schema/glTF.KHR_materials_variants.schema.json
+++ b/extensions/2.0/Khronos/KHR_materials_variants/schema/glTF.KHR_materials_variants.schema.json
@@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-04/schema",
"title": "KHR_materials_variants glTF extension",
"type": "object",
- "description": "glTF extension that defines a material variations for mesh primivites",
+ "description": "glTF extension that defines a material variations for mesh primitives",
"allOf": [ { "$ref": "glTFProperty.schema.json" } ],
"properties": {
"variants": {
diff --git a/extensions/2.0/Khronos/KHR_materials_volume/README.md b/extensions/2.0/Khronos/KHR_materials_volume/README.md
index 8aad192de8..9e4cf26066 100644
--- a/extensions/2.0/Khronos/KHR_materials_volume/README.md
+++ b/extensions/2.0/Khronos/KHR_materials_volume/README.md
@@ -178,31 +178,41 @@ Base color and absorption both have an effect on the final color of a volumetric
The specular transmission `specular_btdf(α)` defined in `KHR_materials_transmission` now takes refraction into account. That means that we use Snell's law to compute the modified half vector:
-.
+$$
+H_{TR} = -\text{normalize}(\eta_i V + \eta_o L)
+$$
-*ηi* and *ηo* denote the IOR of the incident and transmitted side of the surface, respectively. *V* is the vector pointing to the camera, *L* points to the light. In a path tracer, *V* corresponds to the incident side of the surface, which is the side of the medium with *ηi*.
+$\eta_i$ and $\eta_o$ denote the IOR of the incident and transmitted side of the surface, respectively. $V$ is the vector pointing to the camera, $L$ points to the light. In a path tracer, $V$ corresponds to the incident side of the surface, which is the side of the medium with $\eta_i$.
Incident and transmitted IOR have to be correctly set by the renderer, depending on whether light enters or leaves the object. An algorithm for tracking the IOR through overlapping objects was described by [Schmidt and Budge (2002)](#SchmidtBudge2002).
The refractive microfacet BTDF is normalized in a different way.
-
+$$
+\text{MicrofacetBTDF} = \frac{\left| H_{TR} \cdot L \right| \left| H_{TR} \cdot V \right|}{\left| N \cdot L \right| \left| N \cdot V \right|} \frac{\eta_o^2 G_{T} D_{TR}}{\left(\eta_i (H_{TR} \cdot V) + \eta_o (H_{TR} \cdot L)\right)^2}
+$$
-The *DT* and *GTR* terms are the same as in the specular transmission in `KHR_materials_transmission` except using the modified half vector *HTR* calculated from the refraction direction. See [Walter et al. (2007)](#Walter2007) for details.
+The $D_T$ and $G_{TR}$ terms are the same as in the specular transmission in `KHR_materials_transmission` except using the modified half vector $H_{TR}$ calculated from the refraction direction. See [Walter et al. (2007)](#Walter2007) for details.
The Fresnel term also makes use of the modified half vector and, in addition, needs to take internal reflection into account. When using the Schlick approximation, care must be taken to use the angle that is on the dense side of the boundary, i.e., the side with the medium that has a higher IOR. In addition, total internal reflection has to be considered. Therefore, we have three cases:
-Light enters medium with higher IOR: *ηo* ≥ *ηi*.
+1. Light enters medium with higher IOR: $\eta_o \ge \eta_i$.
-
+$$
+F_{TR}^{+} = f_0 + (1 - f_0) (1 - \left| V \cdot H_{TR} \right| )^5
+$$
-Light enters medium with lower IOR and there is no total internal reflection: *ηo* < *ηi* and sin2(*θo*) < 1. The angle at the transmitted side of the boundary (medium with lower IOR) *θo* is computed from the angle of incidence via sin2(*θo*) = (*ηi* / *ηo*)2 (1 - dot(*V*, *HTR*)2) and thus cos(*θo*) = sqrt(1 - sin2(*θo*)).
+2. Light enters medium with lower IOR and there is no total internal reflection: $\eta_o < \eta_i$ and $\sin^2 \theta_o < 1$. The angle at the transmitted side of the boundary (medium with lower IOR) $\theta_o$ is computed from the angle of incidence via $\sin^2 \theta_o = \left(\frac{\eta_i}{\eta_o}\right)^2 (1 - (V \cdot H_{TR})^2)$ and thus $\cos \theta_o = \sqrt{1 - \sin^2 \theta_o}$.
-
+$$
+F_{TR}^{-} = f_0 + (1 - f_0) (1 - \left| \cos\theta_o \right| )^5
+$$
-Light enters medium with lower IOR and there is total internal reflection: *ηo* < *ηi* and sin2(*θo*) ≥ 1.
+3. Light enters medium with lower IOR and there is total internal reflection: $\eta_o < \eta_i$ and and $\sin^2 \theta_o \ge 1$.
-
+$$
+F_{TR}^\text{TIR} = 1
+$$
## Interaction with other extensions
diff --git a/extensions/2.0/Vendor/GRIFFEL_bim_data/README.md b/extensions/2.0/Vendor/GRIFFEL_bim_data/README.md
new file mode 100644
index 0000000000..b086611e5f
--- /dev/null
+++ b/extensions/2.0/Vendor/GRIFFEL_bim_data/README.md
@@ -0,0 +1,234 @@
+# GRIFFEL\_bim\_data
+
+## Contributors
+
+* Kiryl Ambrazheichyk, Griffel Studio LLC, [kiryl@griffelstudio.com](mailto:kiryl@griffelstudio.com)
+* Aliaksandr Valodzin, Griffel Studio LLC, [alexander@griffelstudio.com](mailto:alexander@griffelstudio.com)
+* Aliaksandr Nazarau, Griffel Studio LLC, [@Alexanderexe](https://github.com/Alexanderexe)
+* Ekaterina Kudelina, Griffel Studio LLC, [@uncio](https://github.com/uncio)
+
+## Status
+
+Draft
+
+## Dependencies
+
+Written against the glTF 2.0 spec.
+
+## Overview
+
+This extension allows keeping domain specific data in relation to geometry.
+
+It's applicable when glTF standard `extras` property is not enough to store huge amount of metadata or when it's insufficient from the file size or data complexity perspective.
+
+The extension was originally developed for architecture, engineering and construction (AEC) industry to keep Building Information Model (*BIM*) data, but it's suitable for any other industry which operates huge amounts of information. We encourage any subject matter experts to discuss and improve this specification to create useful general metadata glTF extension.
+
+### Objectives
+
+Keep metadata of each real world object in the most compact and simple way possible.
+
+### Assumptions
+
+Each node with a mesh represents a real world object.
+Node tree represents some logical hierarchy of real world objects. For a construction site with two buildings it might look like this:
+
+```text
+Model 1
+Model 2
+├Storey 1
+└Storey 2
+ ├Category 1
+ └Category 2
+ ├Element 1
+ └Element 2
+```
+
+Where:
+Model - is a building,
+Storey - includes all elements which lay or rise up starting from a particular level,
+Category - groups elements by some parameter (columns, furniture, ducts, etc.),
+Element - leaf `node` with `mesh` which represents a real construction product and have associated meta data.
+
+This is a recommended approach to compose a gltf file, although the extension doesn't restrict mesh to node attachment - any node can still have a mesh and/or associated meta data. Also nodes hierarchy can be different - depending on the desired logical grouping of elements.
+
+### Approach
+
+A single piece of metadata for the node is represented by instance `property`. Property is a key-value pair, like 'name of the object's parameter' - 'its value'. To keep it simple name and value of the property are `strings`.
+Node can also have a `type`. Type is a set of properties which is common for many nodes.
+Instance properties override the same type properties (with the same key) for a node.
+
+#### Example
+
+There are two timber doors in the building. Each is 900 mm (3') wide. First is 2,1 m (7') high, second is 2,4 m (8') high.
+In this example properties are: "Width - 900 mm", "Height - 2,1 m", "Height - 2,4 m", "Material - Timber".
+A single `type` here is represented by the collection consisting of the first and the last properties as width and material are common properties for both doors.
+
+To save some space for storing properties they are written only once in the properties collection and referenced by each node where needed. To save even more space each unique property name and each unique property value are stored in separate collections. This approach is beneficial over keeping metadata in `extras` for large amounts of data.
+
+Types and nodes reference properties by index.
+Each node can reference any number of properties and only one type.
+
+## Implementation notice
+
+Given the same two doors from the example above, there are two options to implement the extension:
+
+### Embed properties into glTF json
+
+```javascript
+"nodes": [
+ {
+ "name": "Door 1",
+ "extensions": {
+ "GRIFFEL_bim_data": {
+ "properties": [
+ 0
+ ],
+ "type": 0
+ }
+ }
+ },
+ {
+ "name": "Door 2",
+ "extensions": {
+ "GRIFFEL_bim_data": {
+ "properties": [
+ 3
+ ],
+ "type": 0
+ }
+ }
+ }
+],
+"extensions": [
+ "GRIFFEL_bim_data": {
+ "propertyNames": [
+ "Height",
+ "Width",
+ "Material"
+ ],
+ "propertyValues": [
+ "2,1 m",
+ "900 mm",
+ "Timber"
+ "2,4 m",
+ ],
+ "properties": [
+ {
+ "name": 0,
+ "value": 0
+ },
+ {
+ "name": 1,
+ "value": 1
+ },
+ {
+ "name": 2,
+ "value": 2
+ },
+ {
+ "name": 0,
+ "value": 3
+ }
+ ],
+ "types": [
+ {
+ "properties": [
+ 1,
+ 2
+ ]
+ }
+ ]
+ }
+]
+```
+
+### Write properties to separate binary file
+
+In this case each node points to the buffer view which references the buffer where metadata for this node can be found. File is a serialized `GRIFFEL_bim_data` extension object with additional `nodeProperties` field. This field maps node properties and their types to nodes by node index.
+
+[MessagePack](https://msgpack.org/) must be used for serializing extension object in a separate binary file to achive the most compact file size and the fastest deserialization speed.
+
+```javascript
+// gltf content:
+"nodes": [
+ {
+ "name": "Door 1",
+ "extensions": {
+ "GRIFFEL_bim_data": {
+ "bufferView": 99
+ }
+ }
+ },
+ {
+ "name": "Door 2",
+ "extensions": {
+ "GRIFFEL_bim_data": {
+ "bufferView": 99
+ }
+ }
+ }
+]
+
+"bufferViews": [
+ // buffer view indexed 99:
+ {
+ "buffer": 1,
+ "byteOffset": 0,
+ "byteLength": 1234
+ }
+
+"buffers": [
+ // buffer indexed 1:
+ {
+ "uri": "projectName.meta",
+ "byteLength": 1234
+ }
+]
+
+// Content of 'projectName.meta':
+{
+ "nodeProperties": [
+ {
+ "node": 0,
+ "properties": [
+ 0
+ ],
+ "type": 0
+ },
+ {
+ "node": 1,
+ "properties": [
+ 3
+ ],
+ "type": 0
+ }
+ ],
+ // propertyNames, propertyValues, properties and types collections are the same
+}
+```
+
+So, for each node, if GRIFFEL_bim_data extension has `properties` or `type` - look for them in the same gltf json file. If the extension states `bufferView` - look for the data in the separate .meta file by the url from the buffer.
+Nodes can have both embedded and separately stored properties, in that case any or both can be used. Exporters should take care of possible data duplication. Though, cross references between embedded and external data are not allowed. Importers should treat embedded values as of higher priority than values, stored in a separate file, as the file may be obsolete or corrupted more likely. If separately stored data references same node many times specifying new or additional properties for it, it is up to Importer: ignore duplicates or apply them all.
+
+## glTF Schema Updates
+
+### JSON Schema Root
+
+[glTF.GRIFFEL_bim_data.schema.json](schema/glTF.GRIFFEL_bim_data.schema.json)
+
+### JSON Schema Node
+
+[node.GRIFFEL_bim_data.schema.json](schema/node.GRIFFEL_bim_data.schema.json)
+
+## Standalone JSON Schema
+
+[GRIFFEL_bim_data.schema.json](schema/GRIFFEL_bim_data.schema.json)
+
+## Known Implementations
+
+* [glTF Exporter](https://apps.autodesk.com/RVT/en/Detail/Index?id=8451869436709222290) - add-in for Autodesk Revit
+
+## Resources
+
+* [MessagePack](https://msgpack.org/) - binary serialization format
+* [Griffel Studio Blog](https://griffelstudio.com/blog/) - information about extension
diff --git a/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/GRIFFEL_bim_data.schema.json b/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/GRIFFEL_bim_data.schema.json
new file mode 100644
index 0000000000..eac61a29df
--- /dev/null
+++ b/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/GRIFFEL_bim_data.schema.json
@@ -0,0 +1,113 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema",
+ "title": "GRIFFEL_bim_data Serializable Object",
+ "type": "object",
+ "description": "Contains same properties as embedded version plus properties to node map. Used only when data is saved in a separate file.",
+ "properties": {
+ "nodeProperties": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "description": "Node properties and type.",
+ "properties": {
+ "node": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of the node in glTF file."
+ },
+ "properties": {
+ "type": "array",
+ "uniqueItems": true,
+ "item": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a property in the root level collection."
+ },
+ "minItems": 1,
+ "description": "Collection of indices properties of the node."
+ },
+ "type": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of the type of the node."
+ }
+ },
+ "required": [ "node" ],
+ "anyOf": [
+ { "required": [ "properties" ] },
+ { "required": [ "type" ] }
+ ]
+ },
+ "minItems": 1,
+ "description": "Node type and instance properties map. Used only when data is saved in a separate file."
+ },
+ "propertyValues": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "description": "Property value."
+ },
+ "minItems": 1,
+ "description": "Collection of unique property values."
+ },
+ "propertyNames": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "description": "Property name.",
+ "minLength": 1
+ },
+ "minItems": 1,
+ "description": "Collection of unique property names."
+ },
+ "properties": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "title": "Node Property",
+ "type": "object",
+ "description": "Key value pair - unique property (instance or type) attached to nodes. Name and value are referenced by index of corresponding root level collection.",
+ "properties": {
+ "name": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a property name in the root level collection."
+ },
+ "value": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a property value in the root level collection."
+ }
+ },
+ "required": [ "name", "value" ]
+ },
+ "minItems": 1,
+ "description": "Collection of unique property name - property value pairs."
+ },
+ "types": {
+ "type": "array",
+ "items": {
+ "title": "Node Type",
+ "type": "object",
+ "description": "Set of properties which are common for many nodes.",
+ "properties": {
+ "name": {
+ "type":"string",
+ "description": "Name of the type."
+ },
+ "properties": {
+ "type": "array",
+ "uniqueItems": true,
+ "item": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a property in the root level collection."
+ },
+ "description": "Collection of indices which point to corresponding properties of the type.",
+ "minItems": 1
+ }
+ },
+ "required": [ "properties" ]
+ },
+ "minItems": 1,
+ "description": "Collection of types - common sets of properties for many nodes."
+ }
+ },
+ "required": [ "nodeProperties", "propertyValues", "propertyNames", "properties" ]
+}
diff --git a/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/glTF.GRIFFEL_bim_data.schema.json b/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/glTF.GRIFFEL_bim_data.schema.json
new file mode 100644
index 0000000000..987b190b91
--- /dev/null
+++ b/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/glTF.GRIFFEL_bim_data.schema.json
@@ -0,0 +1,79 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema",
+ "title": "GRIFFEL_bim_data glTF Extension",
+ "type": "object",
+ "description": "Domain specific properties for glTF nodes.",
+ "properties": {
+ "propertyValues": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "description": "Property value."
+ },
+ "minItems": 1,
+ "description": "Collection of unique property values."
+ },
+ "propertyNames": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "description": "Property name.",
+ "minLength": 1
+ },
+ "minItems": 1,
+ "description": "Collection of unique property names."
+ },
+ "properties": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "title": "Node Property",
+ "type": "object",
+ "description": "Key value pair - unique property (instance or type) attached to nodes. Name and value are referenced by index of corresponding root level collection.",
+ "properties": {
+ "name": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a property name in the root level collection."
+ },
+ "value": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a property value in the root level collection."
+ }
+ },
+ "required": [ "name", "value" ]
+ },
+ "minItems": 1,
+ "description": "Collection of unique property name - property value pairs."
+ },
+ "types": {
+ "type": "array",
+ "items": {
+ "title": "Node Type",
+ "type": "object",
+ "description": "Set of properties which are common for many nodes.",
+ "properties": {
+ "name": {
+ "type":"string",
+ "description": "Name of the type."
+ },
+ "properties": {
+ "type": "array",
+ "uniqueItems": true,
+ "item": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a property in the root level collection."
+ },
+ "description": "Collection of indices which point to corresponding properties of the type.",
+ "minItems": 1
+ }
+ },
+ "required": [ "properties" ]
+ },
+ "minItems": 1,
+ "description": "Collection of types - common sets of properties for many nodes."
+ }
+ },
+ "required": [ "propertyValues", "propertyNames", "properties" ]
+}
diff --git a/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/node.GRIFFEL_bim_data.schema.json b/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/node.GRIFFEL_bim_data.schema.json
new file mode 100644
index 0000000000..72bc3913bf
--- /dev/null
+++ b/extensions/2.0/Vendor/GRIFFEL_bim_data/schema/node.GRIFFEL_bim_data.schema.json
@@ -0,0 +1,34 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema",
+ "title": "GRIFFEL_bim_data Node Extension",
+ "type": "object",
+ "description": "References type and instance properties of the node and/or buffer where those properties can be found by node ID.",
+ "allOf": [ { "$ref": "glTFProperty.schema.json" } ],
+ "properties": {
+ "bufferView": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of the buffer view which points to the buffer with the data for this node."
+ },
+ "properties": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a property in the root level collection."
+ },
+ "minItems": 1,
+ "description": "Collection of indices which point to corresponding instance properties of the node. (Instance properties are unique to the node. They override the same type properties.)"
+ },
+ "type": {
+ "allOf": [ { "$ref": "glTFid.schema.json" } ],
+ "description": "Index of a type in the root level collection. (Type is a set of properties which are common for many nodes.)"
+ },
+ "extensions": { },
+ "extras": { }
+ },
+ "anyOf": [
+ { "required": [ "bufferView" ] },
+ { "required": [ "properties" ] },
+ { "required": [ "type" ] }
+ ]
+}
diff --git a/extensions/Prefixes.md b/extensions/Prefixes.md
index 4054483776..a8738f0d42 100644
--- a/extensions/Prefixes.md
+++ b/extensions/Prefixes.md
@@ -33,13 +33,16 @@ Once a prefix is approved, it should be added to the [glTF Validator's list of k
| `CITRUS` | Citrus Toolbox | https://github.com/KenzieMac130/CitrusToolbox | [#1962](https://github.com/KhronosGroup/glTF/issues/1962) |
| `CLO` | CLO Virtual Fashion | https://www.clo3d.com | [#1944](https://github.com/KhronosGroup/glTF/issues/1944) |
| `CVTOOLS` | Canvas Tools | https://github.com/MackeyK24/CanvasTools | [#1389](https://github.com/KhronosGroup/glTF/issues/1389) |
+| `DOTV` | DotVision | https://dotvision.com `guillaume.pelletier at dotvision.com` | [#2192](https://github.com/KhronosGroup/glTF/issues/2192) |
| `EMBARK` | Embark Studios AB | https://www.embark-studios.com/ | [#2097](https://github.com/KhronosGroup/glTF/issues/2097) |
| `EPIC` | Epic Games, Inc. | https://www.epicgames.com/ | [#1905](https://github.com/KhronosGroup/glTF/issues/1905) |
| `F8` | Forum8 Co., Ltd. | https://www.forum8.com/ | [#1999](https://github.com/KhronosGroup/glTF/issues/1999) |
| `FB` | Facebook, Inc. | https://www.facebook.com/ | [#1139](https://github.com/KhronosGroup/glTF/pull/1139) |
| `FOXIT` | Foxit Software, Inc. | https://foxitsoftware.com `liqian_mu at foxitsoftware.com` | [#1712](https://github.com/KhronosGroup/glTF/issues/1712) |
| `GOOGLE` | Google, LLC | https://www.google.com/ | [#1123](https://github.com/KhronosGroup/glTF/issues/1123) |
-| `GRIFFEL` | Griffel Studio | http://griffelstudio.com/ | [#1861](https://github.com/KhronosGroup/glTF/issues/1861) |
+| `GRIFFEL` | Griffel Studio | https://griffelstudio.com/ | [#1861](https://github.com/KhronosGroup/glTF/issues/1861) |
+| `HEVOLUS` | Hevolus Srl | https://www.hevolus.it/ | [#2183](https://github.com/KhronosGroup/glTF/issues/2183) |
+| `INTEL` | Intel Corporation | https://www.intel.com/ | [#2142](https://github.com/KhronosGroup/glTF/issues/2142) |
| `KDAB` | The KDAB Group | https://www.kdab.com/ | [#1728](https://github.com/KhronosGroup/glTF/pull/1728) |
| `LLQ` | Lifeliqe, Inc. | https://www.lifeliqe.com/ | [#1414](https://github.com/KhronosGroup/glTF/issues/1414) |
| `MAXAR` | Maxar Technologies | https://www.maxar.com/ | [#1869](https://github.com/KhronosGroup/glTF/issues/1869) |
@@ -47,7 +50,10 @@ Once a prefix is approved, it should be added to the [glTF Validator's list of k
| `MOZ` | Mozilla Corporation | https://www.mozilla.org/ | [#1349](https://github.com/KhronosGroup/glTF/issues/1349) |
| `MPEG` | The Moving Picture Experts Group | https://mpeg.chiariglione.org/standards/mpeg-i | [#1754](https://github.com/KhronosGroup/glTF/issues/1754) |
| `MSFT` | Microsoft Corporation | https://www.microsoft.com/ | [#1164](https://github.com/KhronosGroup/glTF/pull/1164) |
+| `MTTR` | Matterport, Inc. | https://matterport.com/ | [#2150](https://github.com/KhronosGroup/glTF/issues/2150) |
| `MX` | The Matrix.org Foundation | https://matrix.org/ | [#2126](https://github.com/KhronosGroup/glTF/issues/2126) |
+| `NEEDLE` | Needle Tools | https://needle.tools/ `felix at needle.tools` | [#2131](https://github.com/KhronosGroup/glTF/issues/2131) |
+| `NTAR` | Nextech AR Solutions Inc. | https://www.nextechar.com/ `mitch at nextechar.com` | [#2188](https://github.com/KhronosGroup/glTF/issues/2188) |
| `NV` | NVIDIA Corporation | https://www.nvidia.com | [#1211](https://github.com/KhronosGroup/glTF/issues/1211) |
| `OFT` | OppenFuture Technologies | https://www.hololux.cn/en/ | [#1957](https://github.com/KhronosGroup/glTF/issues/1957) |
| `OMI` | Open Metaverse Interoperability Group | https://github.com/omigroup/OMI | [#2003](https://github.com/KhronosGroup/glTF/issues/2003) |
@@ -57,6 +63,7 @@ Once a prefix is approved, it should be added to the [glTF Validator's list of k
| `POLUTROPON` | Polutropon Games | https://polutropon.games/ `ybalrid at polutropon.games` | [#1632](https://github.com/KhronosGroup/glTF/issues/1632) |
| `PTC` | PTC Inc. | https://www.ptc.com/ | [#1851](https://github.com/KhronosGroup/glTF/issues/1851) |
| `S8S` | Soft8Soft | https://www.soft8soft.com/ | [#1240](https://github.com/KhronosGroup/glTF/issues/1240) |
+| `SE` | Schneider Electric SE | https://www.se.com/ | [#2134](https://github.com/KhronosGroup/glTF/issues/2134) |
| `SEIN` | Hiloteam | https://seinjs.com/ | [#1840](https://github.com/KhronosGroup/glTF/issues/1840) |
| `SHAPEDIVER` | ShapeDiver GmbH | https://www.shapediver.com/ | [#2103](https://github.com/KhronosGroup/glTF/issues/2103) |
| `SI` | Smithsonian Institution | https://www.si.edu/ | [#1410](https://github.com/KhronosGroup/glTF/issues/1410) |
@@ -64,7 +71,10 @@ Once a prefix is approved, it should be added to the [glTF Validator's list of k
| `SKYLINE` | Skyline Software Systems, Inc. | https://www.skylinesoft.com/ | [#1704](https://github.com/KhronosGroup/glTF/issues/1704) |
| `SNAP` | Snap, Inc. | https://snap.com/ | [#2125](https://github.com/KhronosGroup/glTF/issues/2125) |
| `SPECTRUM` | Spectrum | https://spectrumcustomizer.com/ | [#1804](https://github.com/KhronosGroup/glTF/issues/1804) |
+| `TENCENT` | Tencent, Inc. | https://www.tencent.com/ | [#2118](https://github.com/KhronosGroup/glTF/issues/2118) |
| `TRYON` | TRYON Technology Ltd. | https://tryon.technology | [#1785](https://github.com/KhronosGroup/glTF/issues/1785) |
+| `UNITY` | Unity Software Inc. | https://unity.com | [#2185](https://github.com/KhronosGroup/glTF/issues/2185) |
+| `USSF` | US Space Force | https://www.spaceforce.mil/ | [#2177](https://github.com/KhronosGroup/glTF/issues/2177) |
| `UX3D` | UX3D GmbH | https://ux3d.io/ | [#1896](https://github.com/KhronosGroup/glTF/pull/1896) |
| `VRMC` | VRM Consortium | https://vrm-consortium.org/ | [#1874](https://github.com/KhronosGroup/glTF/issues/1874) |
| `WEB3D` | The Web3D Consortium, Inc. | https://www.web3d.org/ | |
diff --git a/extensions/README.md b/extensions/README.md
index 6bb1cc4b11..228c4b7eec 100644
--- a/extensions/README.md
+++ b/extensions/README.md
@@ -16,7 +16,9 @@ The following extensions have been ratified by the Khronos Group:
* [KHR_draco_mesh_compression](2.0/Khronos/KHR_draco_mesh_compression/README.md)
* [KHR_lights_punctual](2.0/Khronos/KHR_lights_punctual/README.md)
* [KHR_materials_clearcoat](2.0/Khronos/KHR_materials_clearcoat/README.md)
+* [KHR_materials_emissive_strength](2.0/Khronos/KHR_materials_emissive_strength/README.md)
* [KHR_materials_ior](2.0/Khronos/KHR_materials_ior/README.md)
+* [KHR_materials_iridescence](2.0/Khronos/KHR_materials_iridescence/README.md)
* [KHR_materials_sheen](2.0/Khronos/KHR_materials_sheen/README.md)
* [KHR_materials_specular](2.0/Khronos/KHR_materials_specular/README.md)
* [KHR_materials_transmission](2.0/Khronos/KHR_materials_transmission/README.md)
@@ -83,12 +85,11 @@ extensions, Khronos extensions, or inclusion in a future version of the glTF spe
| Extension | Status |
|-----------|--------|
-| [KHR_materials_emissive_strength](https://github.com/KhronosGroup/glTF/pull/1994) | Ready for testing. |
-| [KHR_materials_iridescence](https://github.com/KhronosGroup/glTF/pull/2027) | Ready for testing. |
+| [KHR_animation_pointer](https://github.com/KhronosGroup/glTF/pull/2147) | Ready for testing. |
+| [KHR_audio](https://github.com/KhronosGroup/glTF/pull/2137) | Ready for testing. |
| [KHR_materials_anisotropy](https://github.com/KhronosGroup/glTF/pull/1798) | Ready for testing. |
-| [KHR_materials_translucency](https://github.com/KhronosGroup/glTF/pull/1825) | In development. |
+| [KHR_materials_diffuse_transmission](https://github.com/KhronosGroup/glTF/pull/1825) | Ready for testing. |
| [KHR_materials_sss](https://github.com/KhronosGroup/glTF/pull/1928) | In development. |
-| [KHR_animation2](https://github.com/KhronosGroup/glTF/pull/2033) | In development. |
## Extensions for glTF 1.0