,
+ "outputs": [],
+ "nodes": []
+}
+```
+
+Below is the actual interface for the “checkerboard” definition as specified within MaterialX. The graph nodes have been omitted for clarity.
+
+
+glTF definition
+
+```JSON
+{
+ "procedural_definitions": [
+ {
+ // Definition
+ "name": "ND_checkerboard_color3",
+ "nodetype": "nodedef",
+ "node": "checkerboard",
+ "nodegroup": "procedural",
+ "inputs": [
+ {
+ "name": "color1",
+ "doc": "The first color used in the checkerboard pattern.",
+ "type": "color3",
+ "value": [
+ 1.0,
+ 1.0,
+ 1.0
+ ]
+ },
+ {
+ "name": "color2",
+ "doc": "The second color used in the checkerboard pattern.",
+ "type": "color3",
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ {
+ "name": "uvtiling",
+ "doc": "The tiling of the checkerboard pattern along each axis, with higher values producing smaller squares. Default is (8, 8).",
+ "type": "vector2",
+ "value": [
+ 8,
+ 8
+ ]
+ },
+ {
+ "name": "uvoffset",
+ "doc": "The offset of the checkerboard pattern along each axis. Default is (0, 0).",
+ "type": "vector2",
+ "value": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "name": "texcoord",
+ "doc": "The input 2d space. Default is the first texture coordinates.",
+ "type": "vector2",
+ "defaultgeomprop": "UV0"
+ }
+ ],
+ "outputs": [
+ {
+ "name": "out",
+ "type": "color3"
+ }
+ ]
+ },
+
+// Functional node graph
+ {
+ "name": "NG_checkerboard_color3",
+ "nodetype": "nodegraph",
+ "type": "color3",
+ "nodedef": 0,
+ "outputs": [
+ {
+ "name": "out",
+ "type": "color3"
+ }
+ ],
+ "nodes": [
+ // Nodes omitted...
+ ]
+ }
+ }
+```
+
+
+
+
+The corresponding definition and functional graph in MaterialX looks like this.
+
+MaterialX definition
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+## Structure Review
+
+The following diagrams show the overall structure of the extension.
+
+The following diagram shows the bindings between materials and compound graphs as well as structure and connections for a graph.
+
+
+The following diagram shows the breakdown of a procedural graph definition and its associated node functional graph implementation.
+
+
+
+## JSON Schema
+
+The JSON schema for this extension is defined in the schema folder.
+
+[material.KHR_texture_procedurals.schema.json](schema/material.KHR_texture_procedurals_schema.json)
+
+## Checkerboard Example
+
+The following is a "checkerboard" pattern which is defined as a procedural graph. This graph is mapped to the "base color" on a material.
+
+```mermaid
+
+graph LR;
+ NG_checkerboard_color3_N_mtlxmix[mix] --> NG_checkerboard_color3_out([out])
+ style NG_checkerboard_color3_out fill:#0C0, color:#111
+ NG_checkerboard_color3_color2INT([color2]) ==.bg==> NG_checkerboard_color3_N_mtlxmix[mix]
+ style NG_checkerboard_color3_color2INT fill:#0CF, color:#111
+ NG_checkerboard_color3_color1INT([color1]) ==.fg==> NG_checkerboard_color3_N_mtlxmix[mix]
+ style NG_checkerboard_color3_color1INT fill:#0CF, color:#111
+ NG_checkerboard_color3_N_modulo[modulo] --".mix"--> NG_checkerboard_color3_N_mtlxmix[mix]
+ NG_checkerboard_color3_N_mtlxdotproduct[dotproduct] --".in1"--> NG_checkerboard_color3_N_modulo[modulo]
+ NG_checkerboard_color3_N_mtlxfloor[floor] --".in1"--> NG_checkerboard_color3_N_mtlxdotproduct[dotproduct]
+ NG_checkerboard_color3_N_mtlxsubtract[subtract] --".in"--> NG_checkerboard_color3_N_mtlxfloor[floor]
+ NG_checkerboard_color3_uvoffsetINT([uvoffset]) ==.in2==> NG_checkerboard_color3_N_mtlxsubtract[subtract]
+ style NG_checkerboard_color3_uvoffsetINT fill:#0CF, color:#111
+ NG_checkerboard_color3_N_mtlxmult[multiply] --".in1"--> NG_checkerboard_color3_N_mtlxsubtract[subtract]
+ NG_checkerboard_color3_texcoordINT([texcoord]) ==.in1==> NG_checkerboard_color3_N_mtlxmult[multiply]
+ style NG_checkerboard_color3_texcoordINT fill:#0CF, color:#111
+ NG_checkerboard_color3_uvtilingINT([uvtiling]) ==.in2==> NG_checkerboard_color3_N_mtlxmult[multiply]
+ style NG_checkerboard_color3_uvtilingINT fill:#0CF, color:#111
+```
+Example `checkerboard` graph from MaterialX
+
+
+glTF Graph
+
+```JSON
+{
+ "materials": [
+ {
+ "name": "gltf_pbr_surfaceshader",
+ "pbrMetallicRoughness": {
+ "baseColorTexture": {
+ "index": 0,
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "index": 0
+ }
+ }
+ }
+ }
+ }
+ ],
+ "textures": [
+ {
+ "source": 0
+ }
+ ],
+ "images": [
+ {
+ "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z/AfAAQAAf/zKSWvAAAAAElFTkSuQmCC",
+ "name": "KHR_texture_procedural_fallback"
+ }
+ ],
+ "extensionsUsed": [
+ "KHR_texture_procedurals"
+ ],
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "mimetype": "application/mtlx+json;version=1.38",
+ "procedurals": [
+ {
+ "name": "My_Checker",
+ "nodetype": "nodegraph",
+ "type": "color3",
+ "inputs": [
+ {
+ "name": "color1",
+ "nodetype": "input",
+ "type": "color3",
+ "value": [
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ {
+ "name": "color2",
+ "nodetype": "input",
+ "type": "color3",
+ "value": [
+ 0.0,
+ 1.0,
+ 0.0
+ ]
+ },
+ {
+ "name": "uvtiling",
+ "nodetype": "input",
+ "type": "vector2",
+ "value": [
+ 8.0,
+ 8.0
+ ]
+ },
+ {
+ "name": "uvoffset",
+ "nodetype": "input",
+ "type": "vector2",
+ "value": [
+ 0.0,
+ 0.0
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "name": "out",
+ "nodetype": "output",
+ "type": "color3",
+ "node": 5
+ }
+ ],
+ "nodes": [
+ {
+ "name": "N_mtlxmult",
+ "nodetype": "multiply",
+ "type": "vector2",
+ "inputs": [
+ {
+ "name": "in1",
+ "nodetype": "input",
+ "type": "vector2",
+ "node": 6
+ },
+ {
+ "name": "in2",
+ "nodetype": "input",
+ "type": "vector2",
+ "input": 2
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "vector2"
+ }
+ ]
+ },
+ {
+ "name": "N_mtlxsubtract",
+ "nodetype": "subtract",
+ "type": "vector2",
+ "inputs": [
+ {
+ "name": "in1",
+ "nodetype": "input",
+ "type": "vector2",
+ "node": 0
+ },
+ {
+ "name": "in2",
+ "nodetype": "input",
+ "type": "vector2",
+ "input": 3
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "vector2"
+ }
+ ]
+ },
+ {
+ "name": "N_mtlxfloor",
+ "nodetype": "floor",
+ "type": "vector2",
+ "inputs": [
+ {
+ "name": "in",
+ "nodetype": "input",
+ "type": "vector2",
+ "node": 1
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "vector2"
+ }
+ ]
+ },
+ {
+ "name": "N_mtlxdotproduct",
+ "nodetype": "dotproduct",
+ "type": "float",
+ "inputs": [
+ {
+ "name": "in1",
+ "nodetype": "input",
+ "type": "vector2",
+ "node": 2
+ },
+ {
+ "name": "in2",
+ "nodetype": "input",
+ "type": "vector2",
+ "value": [
+ 1.0,
+ 1.0
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "float"
+ }
+ ]
+ },
+ {
+ "name": "N_modulo",
+ "nodetype": "modulo",
+ "type": "float",
+ "inputs": [
+ {
+ "name": "in1",
+ "nodetype": "input",
+ "type": "float",
+ "node": 3
+ },
+ {
+ "name": "in2",
+ "nodetype": "input",
+ "type": "float",
+ "value": 2.0
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "float"
+ }
+ ]
+ },
+ {
+ "name": "N_mtlxmix",
+ "nodetype": "mix",
+ "type": "color3",
+ "inputs": [
+ {
+ "name": "bg",
+ "nodetype": "input",
+ "type": "color3",
+ "input": 1
+ },
+ {
+ "name": "fg",
+ "nodetype": "input",
+ "type": "color3",
+ "input": 0
+ },
+ {
+ "name": "mix",
+ "nodetype": "input",
+ "type": "float",
+ "node": 4
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "color3"
+ }
+ ]
+ },
+ {
+ "name": "texcoord",
+ "nodetype": "texcoord",
+ "type": "vector2",
+ "inputs": [
+ {
+ "name": "index",
+ "nodetype": "input",
+ "type": "integer",
+ "value": 1
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "vector2"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
+```
+
+
+
+
+The equivalent MaterialX representation is:
+
+
+MaterialX Graph
+
+```XML
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+
+The OpenUSD representation looks like this:
+
+
+OpenUSD Graph
+
+```c++
+def "NodeGraphs"
+ {
+ def Shader "N_mtlxmix"
+ {
+ uniform token info:id = "ND_mix_color3"
+ color3f inputs:bg = (0, 0, 0)
+ color3f inputs:fg = (1, 1, 1)
+ float inputs:mix = 0
+ float inputs:mix.connect =
+ color3f outputs:out
+ }
+
+ def Shader "N_mtlxdotproduct"
+ {
+ uniform token info:id = "ND_dotproduct_vector2"
+ float2 inputs:in1 = (0, 0)
+ float2 inputs:in1.connect =
+ float2 inputs:in2 = (1, 1)
+ float outputs:out
+ }
+
+ def Shader "N_mtlxmult"
+ {
+ uniform token info:id = "ND_multiply_vector2"
+ float2 inputs:in1 = (0, 0)
+ float2 inputs:in1.connect =
+ float2 inputs:in2 = (8, 8)
+ float2 outputs:out
+ }
+
+ def Shader "N_mtlxsubtract"
+ {
+ uniform token info:id = "ND_subtract_vector2"
+ float2 inputs:in1 = (0, 0)
+ float2 inputs:in1.connect =
+ float2 inputs:in2 = (0, 0)
+ float2 outputs:out
+ }
+
+ def Shader "N_mtlxfloor"
+ {
+ uniform token info:id = "ND_floor_vector2"
+ float2 inputs:in = (0, 0)
+ float2 inputs:in.connect =
+ float2 outputs:out
+ }
+
+ def Shader "N_modulo"
+ {
+ uniform token info:id = "ND_modulo_float"
+ float inputs:in1 = 0
+ float inputs:in1.connect =
+ float inputs:in2 = 2
+ float outputs:out
+ }
+
+ def Shader "Texcoord"
+ {
+ uniform token info:id = "ND_texcoord_vector2"
+ int inputs:index = 0
+ float2 outputs:out
+ }
+ }
+```
+
+
+
+#### Checkerboard Variants
+
+In the example below we create variants by declaring custom `checkerboard definition and using instances of this definition instances within a graph.
+
+The inputs on each node instance are specified to to create a “red” and “green” variants.
+
+
+Variants
+
+```JSON
+{
+ "procedurals": [
+ // Checkerboard variants graph
+ {
+ "name": "checkboard_variants",
+ "nodetype": "nodegraph",
+ "nodes": [
+ {
+ "name": "green_checkerboard",
+ "nodetype": "checkerboard",
+ "type": "color3",
+ "inputs": [
+ {
+ "name": "color1",
+ "type": "color3",
+ "value": [
+ 0,
+ 1,
+ 0
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "name": "out",
+ "type": "color3"
+ }
+ ]
+ },
+ {
+ "name" : "red_checkboard",
+ "nodetype": "checkerboard",
+ "type": "color3",
+ "inputs": [
+ {
+ "name": "color1",
+ "type": "color3",
+ "value": [
+ 1,
+ 0,
+ 0
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "name": "out",
+ "type": "color3"
+ }
+ ]
+ }
+ ],
+ // Route the outputs of the checkerboard nodes
+ "outputs": [
+ {
+ "name": "green_out",
+ "type": "color3",
+ "node": 0
+ },
+ {
+ "name": "red_out",
+ "type": "color3",
+ "node": 1
+ }
+ ]
+ }
+ ]
+}
+```
+
+
+
+These procedural graphs can be bound to downstream materials as desired by chosing the appropriate output node.
+
+
+Variant Binding
+
+```JSON
+{
+ // Material references
+ "materials": [
+ {
+ "name": "green_checker",
+ "pbrMetallicRoughness": {
+ "baseColorTexture": {
+ "index": 0,
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "index": 0, // graph with variants
+ "output": 0 // "green checker" variant
+ }
+ }
+ }
+ },
+ "name": "red_checker",
+ "pbrMetallicRoughness": {
+ "baseColorTexture": {
+ "index": 0,
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "index": 0, // graph with variants
+ "output": 1 // "red checker" variant
+ }
+ }
+ }
+ }
+ }
+ ]
+}
+```
+
+
+
+## Resources
+
+- [MaterialX Specification Documents](https://github.com/AcademySoftwareFoundation/MaterialX/tree/main/documents/Specification). Refer top level folder documents only. The *v1.38* folder contains the specification which is not the target.
+- Libraries usable for procedural definitions:
+ - [stdlib](https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/stdlib/stdlib_defs.mtlx) : Standard library nodes.
+ - [nprlib](https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/nprlib/nprlib_defs.mtlx) : Non-photo-realistic rendering nodes
+ - [cmlib](https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/cmlib/cmlib_defs.mtlx) : Color managenement nodes (OCIO based)
+ - The nodes listed by group (`nodegroup`) are listed [here](
+ https://materialx.nanmucreative.com/documents/definitions/definitions_by_group.html)
+ - Groups of interest include:
+ - `adjustment` : Smothstep is probably of most interest. Suggest to move to `math` group.
+ - `channel` : Tuple channel operations
+ - `colortransform` : Color space transformations
+ - `conditional` : Conditional logic
+ - `math` : Mathematical operations
+ - `npr` : Base nodes for non-photo-realistic rendering nodes
+ - `procedural*` : Procedural nodes. This grouping will be clarified for the 1.39 release. Includes noise functions.
+ - `textur2d` : 2D texture nodes including texture lookups
+ - `geometric` : Geometry binding nodes
+ - `translation` : Shading mode translation.
+
+- OpenUSD
+ - [USDShade Schema](https://openusd.org/dev/api/usd_shade_page_front.html)
+ - [Shader Definition Registry](https://openusd.org/docs/api/sdr_page_front.html)
+- glTF
+ - [glTF stream names](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html). Note that currently there are no stream names for multiple sets of _tangents_, _bitangents_, _normals_ or _positions_.
+
+### glTF Versus MaterialX and OpenUSD
+
+The aim is (as much as possible) to preserve the"simplest" most consistent conventions from glTF, MaterialX and OpenUSD.
+
+| Feature | | | |
+| --- | --- | --- | --- |
+| **Object String Identifiers** | Yes | Yes | Optional |
+| **Numeric Tuples** | string | list () | array [] |
+| **Connection Syntax**" | string (name in context) | Absolute Path | numeric index |
+| **Explicit Node Outputs** | No | Yes | Yes |
+| **Node Type Grouping** | No | No | Yes |
+| **Reference to nodedef on node instance** | Yes | Yes | No |
+| **NodeGraph Nesting** | "Yes" (not implemented) | Yes | No |
+| **Optional Input Overrides on Nodes** | Yes | Yes | Yes |
+| **Referencing** | Yes | Yes | No |
+| **Definition Versioning** | Yes | Yes | Yes |
+| **Meta-Data** | Yes | Yes | Yes |
+| **Node Definition** | Yes | Yes | Yes |
+
+## Appendix: Full Khronos Copyright Statement
+
+Copyright 2024 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.
+
+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.
+
+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.
+
+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 and confirm the implementation as conformant under
+the process defined by Khronos for this specification; see https://www.khronos.org/conformance/adopters/file-format-adopter-program.
+
+Where this Specification identifies specific sections of external references, only those specifically identified sections define normative functionality. The Khronos Intellectual Property Rights Policy excludes external references to materials and associated enabling technology not created by Khronos from the Scope of this Specification, and any licenses that may be required to implement such referenced materials and associated technologies must be obtained separately and may involve royalty payments.
+
+Khronos® is a registered trademark, and glTF™ is a trademark of The Khronos Group Inc. 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_texture_procedurals/figures/KHR_procedural_diagrams_classes.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_classes.png
new file mode 100644
index 0000000000..f686be2782
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_classes.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_classes.svg b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_classes.svg
new file mode 100644
index 0000000000..05d11f2290
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_classes.svg
@@ -0,0 +1,3 @@
+
+
+Procedural Input + nodetype: "input" Procedural Output + nodetype: "output" Procedural Node + nodetype: Classification + outputs: Output_Port[] + [ inputs: Input_Port[] ] Compound NodeGraph + nodetype: "nodegraph" + type: TypeDef | "multioutput" <<interface>> Port + [name] : string + nodetype : string + type: TypeDef + [ "input" | "output" | "node" | "texture" : integer ] + ui <meta-data> Input Port + value: Value + [defaultgromprop] : string Output Port «enumeration» Value + integer[2..4] + float[2..4] + float[3][3] + float[4][4] + "string" + boolean «interface» Procedural + [ name : string ] + nodetype : Classification + type : TypeDef «string» Classification + MTLX Stdlib classifications + e.g. add, noise, etc + Custom classifications «enumeration» TypeDef + "vec2", "vec3", "vec4" + "color3", "color4" + "string" + "boolean" + "matrix33", "matrix44" + "integer", "integer2", "integer3", "integer4" gltF Texture Procedural interface / enumeration
gltF Texture Procedural ( Immutable / Unconnectable )
gltF Texture Procedural ( Mutable/ Connectable )
Functional NodeGraph + nodetype: "nodegraph" + nodedef: integer + outputs: Input_Port[] + type: TypeDef | "multioutput" Procedural Definition + node: Classification + nodetype: "nodedef" + nodegroup: string + inputs: Input_Port[] + outputs : Output_Port[] + version: string + <additional meta_data>
\ No newline at end of file
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_connections.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_connections.png
new file mode 100644
index 0000000000..18bcd82621
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_connections.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_connections.svg b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_connections.svg
new file mode 100644
index 0000000000..5cfc0a3bb7
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/KHR_procedural_diagrams_connections.svg
@@ -0,0 +1,3 @@
+
+
+mimetype:
application/mtlx+json;version=<MTLX version>
KHR_texture_procedurals extension
MTLX "texcoord" + index:integer MTLX "geom*" + index: integer MTLX "image" + index:integer + filename: string "filename" transferred to Image URI
Procedural Node + name:string + nodetype: Classification gltF Texture Procedural Element
gltF Texture Procedural ( Immutable / Unconnectable )
gltF Texture Procedural ( Mutable/ Connectable )
\ No newline at end of file
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/OpenUSD.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/OpenUSD.png
new file mode 100644
index 0000000000..9580a19518
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/OpenUSD.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/baked_marble.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/baked_marble.png
new file mode 100644
index 0000000000..90293ffdd9
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/baked_marble.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/breakdown.svg b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/breakdown.svg
new file mode 100644
index 0000000000..60951d5c79
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/breakdown.svg
@@ -0,0 +1,3 @@
+
+
+mimetype: mtx-json version: 1.39
\ No newline at end of file
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/breakdown2.svg b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/breakdown2.svg
new file mode 100644
index 0000000000..cafc8c406b
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/breakdown2.svg
@@ -0,0 +1,3 @@
+
+
+mimetype: mtx-json version: 1.39
\ No newline at end of file
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/checker_graph.svg b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/checker_graph.svg
new file mode 100644
index 0000000000..873c382bb8
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/checker_graph.svg
@@ -0,0 +1,2 @@
+
+My_Checker
.surfaceshader
.base_color
.bg
.fg
.mix
.in1
.in1
.in
.in2
.in1
.in1
.in2
N_modulo
N_mtlxdotproduct
N_mtlxfloor
N_mtlxmix
My_Checker_N_mtlxmult
N_mtlxsubtract
color1
color2
texcoord
uvoffset
uvtiling
gltf_pbr_surfaceshader
surfacematerial
\ No newline at end of file
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/glTF.svg b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/glTF.svg
new file mode 100644
index 0000000000..cda5f6e5d2
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/glTF.svg
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/interop.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/interop.png
new file mode 100644
index 0000000000..324277fe24
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/interop.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/materialx.svg b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/materialx.svg
new file mode 100644
index 0000000000..42ae2465bd
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/materialx.svg
@@ -0,0 +1 @@
+MaterialXLogo
\ No newline at end of file
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/procedural_marble.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/procedural_marble.png
new file mode 100644
index 0000000000..59e930aa63
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/procedural_marble.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/referencing.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/referencing.png
new file mode 100644
index 0000000000..f192197c2e
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/referencing.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/texture_override.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/texture_override.png
new file mode 100644
index 0000000000..ebcd5cf769
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/texture_override.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/texture_sampling.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/texture_sampling.png
new file mode 100644
index 0000000000..5adf0cf551
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/texture_sampling.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/validation.png b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/validation.png
new file mode 100644
index 0000000000..1b5ac87798
Binary files /dev/null and b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/validation.png differ
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/figures/version_upgrade.svg b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/version_upgrade.svg
new file mode 100644
index 0000000000..c7017ffd9a
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/figures/version_upgrade.svg
@@ -0,0 +1,3 @@
+
+
+mimetype: mtx-json version: 1.39
MaterialXLogo mimetype: mtx-json version: 1.39
mimetype: mtx-json version: 1.38
MaterialXLogo
\ No newline at end of file
diff --git a/extensions/2.0/Khronos/KHR_texture_procedurals/schema/material.KHR_texture_procedurals_schema.json b/extensions/2.0/Khronos/KHR_texture_procedurals/schema/material.KHR_texture_procedurals_schema.json
new file mode 100644
index 0000000000..0a5d58a5cb
--- /dev/null
+++ b/extensions/2.0/Khronos/KHR_texture_procedurals/schema/material.KHR_texture_procedurals_schema.json
@@ -0,0 +1,355 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "KHR_texture_procedurals glTF Procedural Texture Extension",
+ "type": "object",
+ "description": "Extension to support procedural texture graphs and definitions",
+ "definitions" : {
+
+ "port" :
+ {
+ "doc" : "A stand-alone, node or nodegraph port object",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "nodetype": { "type": "string" },
+ "type": { "type": "string" }
+ },
+ "required": ["nodetype", "type"]
+ },
+
+ "typedef":
+ {
+ "_doc:" : "Supported type definition strings",
+ "type" : "string",
+ "enum": ["float", "integer", "boolean", "string", "filename", "color3", "color4", "vector2", "vector3", "vector4", "matrix33", "matrix44", "multioutput" ]
+ },
+
+ "value":
+ {
+ "doc": "An input value. Can be a single number, boolean, string, or array of numbers",
+ "oneOf": [
+ {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 16,
+ "items": { "type": "number" }
+ },
+ { "type": "string" },
+ { "type": "boolean" },
+ { "type": "number" }
+ ]
+ },
+
+ "graph_input" :
+ {
+ "doc" : "A input port on a node graph. Either a value or a connection to a texture is required",
+ "allOf": [
+ { "$ref": "#/definitions/port" },
+ { "type" : "object",
+ "properties": {
+ "name": { "type": "string" },
+ "nodetype": { "type": "string", "const" : "input" },
+ "type": { "$ref": "#/definitions/typedef" },
+ "value": { "$ref": "#/definitions/value" }
+ },
+ "required": ["nodetype", "type"],
+ "oneOf" : [
+ {
+ "properties": { "value": { "$ref": "#/definitions/value" } },
+ "required": ["value"]
+ },
+ {
+ "properties": { "texture": { "type": "integer" }},
+ "required": ["texture"]
+ }
+ ]
+ }
+ ]
+ },
+
+ "node_input" :
+ {
+ "doc" : "A input port on a node. Either a value or a connection must be specified",
+ "allOf": [
+ { "$ref": "#/definitions/port" },
+ { "type" : "object",
+ "properties": {
+ "name": { "type": "string" },
+ "nodetype": { "type": "string", "const": "input" },
+ "type": { "$ref": "#/definitions/typedef" }
+ },
+ "required": ["nodetype", "type"],
+ "oneOf" : [
+ {
+ "properties": { "value": { "$ref": "#/definitions/value" } },
+ "required": ["value"]
+ },
+ {
+ "properties": {
+ "node": {
+ "type": "integer",
+ "_doc": "A connection to a node in the nodes array"
+ },
+ "output": {
+ "type": "integer",
+ "_doc": "A connection to an output on the node. Required if > 1 output on the node"
+ }
+ },
+ "required": ["node"]
+ },
+ {
+ "_doc": "A connection to a graph input",
+ "properties": { "input": { "type": "integer" }},
+ "required": ["input"]
+ },
+ {
+ "_doc:" : "A connection to a texture in the textures array",
+ "properties": { "texture": { "type": "integer" }},
+ "required": ["texture"]
+ }
+ ]
+ }
+ ]
+ },
+
+ "output_port" : {
+ "_doc": "A stand-alone, node or nodegraph output port",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "nodetype": { "type": "string" },
+ "type": { "$ref": "#/definitions/typedef" }
+ },
+ "required": ["nodetype", "type"]
+ },
+
+ "node" : {
+ "_doc": "A node in a node graph",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "nodetype": {
+ "_doc": "A standard library node category or one defined in procedural_definitions",
+ "type": "string"
+ },
+ "type": { "type": "string" },
+ "inputs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/node_input"
+ }
+ },
+ "outputs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/output_port"
+ }
+ }
+ },
+ "required" : ["nodetype", "type", "outputs"]
+ },
+
+ "nodegraph" : {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "nodetype": {
+ "type": "string",
+ "const": "nodegraph"
+ },
+ "type": { "$ref": "#/definitions/typedef" },
+
+ "inputs": {
+ "type": "array",
+ "items" : {"$ref": "#/definitions/graph_input"}
+ },
+
+ "outputs": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/output_port" }
+ },
+
+ "nodes": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/node" }
+ }
+ },
+ "required" : ["nodetype", "type", "outputs", "nodes"]
+ },
+
+ "definition_item" : {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "nodetype": { "type": "string" },
+ "type": { "$ref": "#/definitions/typedef" }
+ },
+ "required" : ["nodetype", "type"]
+ },
+
+ "nodedef" : {
+ "_doc": "A node definition",
+ "allOf": [
+ { "$ref": "#/definitions/definition_item" },
+ { "type" : "object",
+ "properties": {
+ "node" : {
+ "_doc": "Node classification used by nodetype references",
+ "type": "string"
+ },
+ "nodetype" : {
+ "type" : "string",
+ "const" : "nodedef"
+ },
+ "version": {
+ "_doc" : "Version of the classification",
+ "type": "string"
+ },
+ "nodegroup": {
+ "_doc" : "Grouping. Should be provided",
+ "type": "string",
+ "default": "texture2d"
+ },
+ "isdefaultversion": { "type": "boolean" },
+
+ "inputs": {
+ "type": "array",
+ "items" : {"$ref": "#/definitions/graph_input"}
+ },
+
+ "outputs": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/output_port" }
+ }
+ },
+ "required" : ["node", "outputs", "inputs"]
+ }
+ ]
+ },
+
+ "nodegraph_implementatnion" : {
+ "_doc": "A node graph that is a definition's implementation.",
+ "allOf": [
+ { "$ref": "#/definitions/definition_item" },
+ { "type" : "object",
+ "properties": {
+ "nodetype" : {
+ "type" : "string",
+ "const" : "nodegraph"
+ },
+ "nodedef": {
+ "_doc": "The node definition for this function",
+ "type": "number"
+ },
+
+ "outputs": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/output_port" }
+ },
+
+ "nodes": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/node" }
+ }
+ },
+ "required" : ["nodedef", "outputs", "nodes"]
+ }
+ ]
+ }
+ },
+
+ "properties": {
+ "materials": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "extensions": {
+ "type": "object",
+ "properties": {
+ "KHR_materials_unlit": { "type": "object" }
+ }
+ },
+ "name": { "type": "string" },
+ "pbrMetallicRoughness": {
+ "type": "object",
+ "properties": {
+ "baseColorTexture": {
+ "type": "object",
+ "properties": {
+ "index": { "type": "integer" },
+ "extensions": {
+ "type": "object",
+ "properties": {
+ "KHR_texture_procedurals": {
+ "type": "object",
+ "properties": {
+ "index": { "type": "integer" },
+ "output": { "type": "integer" }
+ },
+ "required": ["index"]
+ }
+ },
+ "required": ["KHR_texture_procedurals"]
+ }
+ }
+ }
+ }
+ }
+ },
+ "required": ["pbrMetallicRoughness"]
+ }
+ },
+ "textures": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "source": { "type": "integer" }
+ },
+ "required": ["source"]
+ }
+ },
+ "images": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "uri": { "type": "string" },
+ "name": { "type": "string" }
+ },
+ "required": ["uri"]
+ }
+ },
+ "extensionsUsed": {
+ "type": "array",
+ "items": { "type": "string" },
+ "contains": { "enum": ["KHR_texture_procedurals"] }
+ },
+ "extensions": {
+ "type": "object",
+ "properties": {
+ "KHR_texture_procedurals": {
+ "type": "object",
+ "properties": {
+
+ "procedurals": {
+ "_doc": "A list of procedural texture graphs",
+ "type": "array",
+ "items": { "$ref": "#/definitions/nodegraph" }
+ },
+
+ "procedural_definitions": {
+ "_doc": "A list of procedural node definitions and corresponding implementations",
+ "type": "array",
+ "items": { "$ref": "#/definitions/definition_item" }
+ }
+ },
+ "required": ["procedurals"]
+ }
+ },
+ "required": ["KHR_texture_procedurals"]
+ }
+ },
+ "required": ["materials", "extensionsUsed", "extensions"]
+}
diff --git a/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/README.md b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/README.md
new file mode 100644
index 0000000000..e25dbb72ae
--- /dev/null
+++ b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/README.md
@@ -0,0 +1,704 @@
+# EXT\_texture\_procedurals\_mx\_1\_39
+
+## Contributors
+
+- Ashwin Bhat, Autodesk, ashwin.bhat@autodesk.com
+- Alexey Knyazev, Individual Contributor, [@lexaknyazev](https://github.com/lexaknyazev)
+- Bernard Kwok, Individual Contributor, [@kwokcb](https://github.com/kwokcb)
+- Ed Mackey, AGI, [@emackey](https://twitter.com/emackey)
+- Lutz Kettner, NVIDIA, lkettner@nvidia.com
+- Richard Sahlin, IKEA [@rsahlin](https://github.com/rsahlin)
+- Timothy Blut, NVIDIA, tblut@nvidia.com
+
+Copyright 2024 The Khronos Group Inc.
+See [Appendix](#appendix-full-khronos-copyright-statement) for full Khronos Copyright Statement.
+
+## Status
+
+Draft
+
+## Dependencies
+
+Written against the glTF 2.0 spec and KHR_texture_procedurals
+
+## Overview
+
+This extension provides a mechanism to author procedural pattern graphs using node elements defined in MaterialX Specification 1.39.
+
+### Table of Contents
+
+- [Motivation](#motivation)
+- [Extension Declaration](#extension-declaration)
+- [JSON Schema](#json-schema)
+- [Example](#Example)
+- [Resources](#resources)
+
+### Motivation
+
+While `KHR_texture_procedurals` defines the schema to represent a procedural graph to extend the capabilities of glTF materials beyond what is possible with traditional texture maps.
+
+For seamless interoperability this extension defines the schema for nodes or elements of the procedural graph.
+
+More specifically this extension defines support for nodes in the MaterialX 1.39 specification. This ensures that the procedural graphs can be easily converted to MaterialX and USDShade graphs.
+
+
+## Extension Declaration
+
+Usage of the procedural structure is indicated by adding the `EXT_texture_procedurals_mx_` extension identifier to the `extensionsUsed` array. Where `` corresponds to the MaterialX version separated by an underscores. For example version 1.39 is represented as `EXT_texture_procedurals_mx_1_39`.
+
+It is required that `KHR_texture_procedurals` also be defined as this specifies the JSON schema for the procedural graphs.
+
+Note that:
+
+1. This is the only location that the `EXT_texture_procedurals_mx_1_39` extension identifier is allowed
+to be specified. The explicit meaning is that definitions from this version of MaterialX are used for the entire glTF asset.
+
+ Below is an example specifiy usage of MaterialX version 1.39.
+ ```json
+ {
+ "extensionsUsed": [
+ "KHR_texture_procedurals",
+ "EXT_texture_procedurals_mx_1_39"
+ ]
+ }
+ ```
+
+2. It is invalid to specify more than one version of MaterialX in the same glTF asset.
+
+Usage of a given extension is defined in the `extensions` object as follows:
+```json
+{
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "procedurals": []
+ }
+ }
+}
+```
+The `procedurals` array specifies the procedural graphs for a given set of nodes that matching the MaterialX version specified.
+
+## Handling MaterialX glTF PBR Nodes
+
+The glTF PBR node specified within MaterialX exposes a number of input ports which may not map 1:1 with the glTF PBR material for texture mapping. That is, `texture_info` mappings in glTF PBR may not map directly to the input ports of the MaterialX PBR node.
+
+One example is the mismatch of `metalicRoughnessTexture` which is a single packed 3 or 4 channel image which is minimally split into two input ports `metallic` and `roughness` on a glTF PBR shader in MaterialX.
+
+Below is the Boombox glTF example as expressed in MaterialX. The top image shows the mapping to the shader port connects and the bottom a subgraph which shows how an ORM image is split to the `metallic` and `roughness` and `occlusion` ports.
+
+
+
+
+Any channels mapped on the MaterialX glTF PBR node which do not correspond to a `texture_info` mapping should be ignored as being invalid or pre-processed to insert the appropriate node within the procedural graph to combine the outputs so that they are mappable. For the example, a `combine` node has been added. The
+split outputs can be reconstituted when converted back (e.g. to MaterialX) for an integration which uses separated inputs.
+
+
+
+## JSON Schema
+
+The JSON schema for this extension is defined in the schema folder.
+
+[material.EXT_texture_procedurals_mx_1_39.schema.json](schema/material.EXT_texture_procedurals_mx_1_39_schema.json)
+
+## Example
+
+The following is a "checkerboard" pattern which is defined as a procedural graph. This graph is mapped to the "base color" on a material.
+
+```mermaid
+
+graph LR;
+ NG_checkerboard_color3_N_mtlxmix[mix] --> NG_checkerboard_color3_out([out])
+ style NG_checkerboard_color3_out fill:#0C0, color:#111
+ NG_checkerboard_color3_color2INT([color2]) ==.bg==> NG_checkerboard_color3_N_mtlxmix[mix]
+ style NG_checkerboard_color3_color2INT fill:#0CF, color:#111
+ NG_checkerboard_color3_color1INT([color1]) ==.fg==> NG_checkerboard_color3_N_mtlxmix[mix]
+ style NG_checkerboard_color3_color1INT fill:#0CF, color:#111
+ NG_checkerboard_color3_N_modulo[modulo] --".mix"--> NG_checkerboard_color3_N_mtlxmix[mix]
+ NG_checkerboard_color3_N_mtlxdotproduct[dotproduct] --".in1"--> NG_checkerboard_color3_N_modulo[modulo]
+ NG_checkerboard_color3_N_mtlxfloor[floor] --".in1"--> NG_checkerboard_color3_N_mtlxdotproduct[dotproduct]
+ NG_checkerboard_color3_N_mtlxsubtract[subtract] --".in"--> NG_checkerboard_color3_N_mtlxfloor[floor]
+ NG_checkerboard_color3_uvoffsetINT([uvoffset]) ==.in2==> NG_checkerboard_color3_N_mtlxsubtract[subtract]
+ style NG_checkerboard_color3_uvoffsetINT fill:#0CF, color:#111
+ NG_checkerboard_color3_N_mtlxmult[multiply] --".in1"--> NG_checkerboard_color3_N_mtlxsubtract[subtract]
+ NG_checkerboard_color3_texcoordINT([texcoord]) ==.in1==> NG_checkerboard_color3_N_mtlxmult[multiply]
+ style NG_checkerboard_color3_texcoordINT fill:#0CF, color:#111
+ NG_checkerboard_color3_uvtilingINT([uvtiling]) ==.in2==> NG_checkerboard_color3_N_mtlxmult[multiply]
+ style NG_checkerboard_color3_uvtilingINT fill:#0CF, color:#111
+```
+Example `checkerboard` graph from MaterialX
+
+
+glTF Graph
+
+```JSON
+{
+ "materials": [
+ {
+ "name": "gltf_pbr_surfaceshader",
+ "pbrMetallicRoughness": {
+ "baseColorTexture": {
+ "index": 0,
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "index": 0
+ }
+ }
+ }
+ }
+ }
+ ],
+ "textures": [
+ {
+ "source": 0
+ }
+ ],
+ "images": [
+ {
+ "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z/AfAAQAAf/zKSWvAAAAAElFTkSuQmCC",
+ "name": "KHR_texture_procedural_fallback"
+ }
+ ],
+ "extensionsUsed": [
+ "EXT_texture_procedurals_mx_1_39",
+ "KHR_texture_procedurals"
+ ],
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "procedurals": [
+ {
+ "name": "My_Checker",
+ "nodetype": "nodegraph",
+ "type": "color3",
+ "inputs": [
+ {
+ "name": "color1",
+ "nodetype": "input",
+ "type": "color3",
+ "value": [
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ {
+ "name": "color2",
+ "nodetype": "input",
+ "type": "color3",
+ "value": [
+ 0.0,
+ 1.0,
+ 0.0
+ ]
+ },
+ {
+ "name": "uvtiling",
+ "nodetype": "input",
+ "type": "vector2",
+ "value": [
+ 8.0,
+ 8.0
+ ]
+ },
+ {
+ "name": "uvoffset",
+ "nodetype": "input",
+ "type": "vector2",
+ "value": [
+ 0.0,
+ 0.0
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "name": "out",
+ "nodetype": "output",
+ "type": "color3",
+ "node": 5
+ }
+ ],
+ "nodes": [
+ {
+ "name": "N_mtlxmult",
+ "nodetype": "multiply",
+ "type": "vector2",
+ "inputs": [
+ {
+ "name": "in1",
+ "nodetype": "input",
+ "type": "vector2",
+ "node": 6
+ },
+ {
+ "name": "in2",
+ "nodetype": "input",
+ "type": "vector2",
+ "input": 2
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "vector2"
+ }
+ ]
+ },
+ {
+ "name": "N_mtlxsubtract",
+ "nodetype": "subtract",
+ "type": "vector2",
+ "inputs": [
+ {
+ "name": "in1",
+ "nodetype": "input",
+ "type": "vector2",
+ "node": 0
+ },
+ {
+ "name": "in2",
+ "nodetype": "input",
+ "type": "vector2",
+ "input": 3
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "vector2"
+ }
+ ]
+ },
+ {
+ "name": "N_mtlxfloor",
+ "nodetype": "floor",
+ "type": "vector2",
+ "inputs": [
+ {
+ "name": "in",
+ "nodetype": "input",
+ "type": "vector2",
+ "node": 1
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "vector2"
+ }
+ ]
+ },
+ {
+ "name": "N_mtlxdotproduct",
+ "nodetype": "dotproduct",
+ "type": "float",
+ "inputs": [
+ {
+ "name": "in1",
+ "nodetype": "input",
+ "type": "vector2",
+ "node": 2
+ },
+ {
+ "name": "in2",
+ "nodetype": "input",
+ "type": "vector2",
+ "value": [
+ 1.0,
+ 1.0
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "float"
+ }
+ ]
+ },
+ {
+ "name": "N_modulo",
+ "nodetype": "modulo",
+ "type": "float",
+ "inputs": [
+ {
+ "name": "in1",
+ "nodetype": "input",
+ "type": "float",
+ "node": 3
+ },
+ {
+ "name": "in2",
+ "nodetype": "input",
+ "type": "float",
+ "value": 2.0
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "float"
+ }
+ ]
+ },
+ {
+ "name": "N_mtlxmix",
+ "nodetype": "mix",
+ "type": "color3",
+ "inputs": [
+ {
+ "name": "bg",
+ "nodetype": "input",
+ "type": "color3",
+ "input": 1
+ },
+ {
+ "name": "fg",
+ "nodetype": "input",
+ "type": "color3",
+ "input": 0
+ },
+ {
+ "name": "mix",
+ "nodetype": "input",
+ "type": "float",
+ "node": 4
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "color3"
+ }
+ ]
+ },
+ {
+ "name": "texcoord",
+ "nodetype": "texcoord",
+ "type": "vector2",
+ "inputs": [
+ {
+ "name": "index",
+ "nodetype": "input",
+ "type": "integer",
+ "value": 1
+ }
+ ],
+ "outputs": [
+ {
+ "nodetype": "output",
+ "name": "out",
+ "type": "vector2"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
+```
+
+
+
+
+The equivalent MaterialX representation is:
+
+
+MaterialX Graph
+
+```XML
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+
+The OpenUSD representation looks like this:
+
+
+OpenUSD Graph
+
+```c++
+def "NodeGraphs"
+ {
+ def Shader "N_mtlxmix"
+ {
+ uniform token info:id = "ND_mix_color3"
+ color3f inputs:bg = (0, 0, 0)
+ color3f inputs:fg = (1, 1, 1)
+ float inputs:mix = 0
+ float inputs:mix.connect =
+ color3f outputs:out
+ }
+
+ def Shader "N_mtlxdotproduct"
+ {
+ uniform token info:id = "ND_dotproduct_vector2"
+ float2 inputs:in1 = (0, 0)
+ float2 inputs:in1.connect =
+ float2 inputs:in2 = (1, 1)
+ float outputs:out
+ }
+
+ def Shader "N_mtlxmult"
+ {
+ uniform token info:id = "ND_multiply_vector2"
+ float2 inputs:in1 = (0, 0)
+ float2 inputs:in1.connect =
+ float2 inputs:in2 = (8, 8)
+ float2 outputs:out
+ }
+
+ def Shader "N_mtlxsubtract"
+ {
+ uniform token info:id = "ND_subtract_vector2"
+ float2 inputs:in1 = (0, 0)
+ float2 inputs:in1.connect =
+ float2 inputs:in2 = (0, 0)
+ float2 outputs:out
+ }
+
+ def Shader "N_mtlxfloor"
+ {
+ uniform token info:id = "ND_floor_vector2"
+ float2 inputs:in = (0, 0)
+ float2 inputs:in.connect =
+ float2 outputs:out
+ }
+
+ def Shader "N_modulo"
+ {
+ uniform token info:id = "ND_modulo_float"
+ float inputs:in1 = 0
+ float inputs:in1.connect =
+ float inputs:in2 = 2
+ float outputs:out
+ }
+
+ def Shader "Texcoord"
+ {
+ uniform token info:id = "ND_texcoord_vector2"
+ int inputs:index = 0
+ float2 outputs:out
+ }
+ }
+```
+
+
+
+#### Checkerboard Variants
+
+In the example below we create variants by declaring custom `checkerboard definition and using instances of this definition instances within a graph.
+
+The inputs on each node instance are specified to to create a “red” and “green” variants.
+
+
+Variants
+
+```JSON
+{
+ "procedurals": [
+ // Checkerboard variants graph
+ {
+ "name": "checkboard_variants",
+ "nodetype": "nodegraph",
+ "nodes": [
+ {
+ "name": "green_checkerboard",
+ "nodetype": "checkerboard",
+ "type": "color3",
+ "inputs": [
+ {
+ "name": "color1",
+ "type": "color3",
+ "value": [
+ 0,
+ 1,
+ 0
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "name": "out",
+ "type": "color3"
+ }
+ ]
+ },
+ {
+ "name" : "red_checkboard",
+ "nodetype": "checkerboard",
+ "type": "color3",
+ "inputs": [
+ {
+ "name": "color1",
+ "type": "color3",
+ "value": [
+ 1,
+ 0,
+ 0
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "name": "out",
+ "type": "color3"
+ }
+ ]
+ }
+ ],
+ // Route the outputs of the checkerboard nodes
+ "outputs": [
+ {
+ "name": "green_out",
+ "type": "color3",
+ "node": 0
+ },
+ {
+ "name": "red_out",
+ "type": "color3",
+ "node": 1
+ }
+ ]
+ }
+ ]
+}
+```
+
+
+
+These procedural graphs can be bound to downstream materials as desired by choosing the appropriate output node.
+
+
+Variant Binding
+
+```JSON
+{
+ // Material references
+ "materials": [
+ {
+ "name": "green_checker",
+ "pbrMetallicRoughness": {
+ "baseColorTexture": {
+ "index": 0,
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "index": 0, // graph with variants
+ "output": 0 // "green checker" variant
+ }
+ }
+ }
+ },
+ "name": "red_checker",
+ "pbrMetallicRoughness": {
+ "baseColorTexture": {
+ "index": 0,
+ "extensions": {
+ "KHR_texture_procedurals": {
+ "index": 0, // graph with variants
+ "output": 1 // "red checker" variant
+ }
+ }
+ }
+ }
+ }
+ ]
+}
+```
+
+
+
+## Resources
+
+- [MaterialX Specification Documents](https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/documents/Specification/MaterialX.Specification.md).
+- OpenUSD
+ - [USDShade Schema](https://openusd.org/dev/api/usd_shade_page_front.html)
+ - [Shader Definition Registry](https://openusd.org/docs/api/sdr_page_front.html)
+- glTF
+ - [glTF stream names](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html). Note that currently there are no stream names for multiple sets of _tangents_, _bitangents_, _normals_ or _positions_.
+
+### glTF Versus MaterialX and OpenUSD
+
+The aim is (as much as possible) to preserve the"simplest" most consistent conventions from glTF, MaterialX and OpenUSD.
+
+| Feature | | | |
+| --- | --- | --- | --- |
+| **Object String Identifiers** | Yes | Yes | Optional |
+| **Numeric Tuples** | string | list () | array [] |
+| **Connection Syntax**" | string (name in context) | Absolute Path | numeric index |
+| **Explicit Node Outputs** | No | Yes | Yes |
+| **Node Type Grouping** | No | No | Yes |
+| **Reference to nodedef on node instance** | Yes | Yes | No |
+| **NodeGraph Nesting** | "Yes" (not implemented) | Yes | No |
+| **Optional Input Overrides on Nodes** | Yes | Yes | Yes |
+| **Referencing** | Yes | Yes | No |
+| **Definition Versioning** | Yes | Yes | Yes |
+| **Meta-Data** | Yes | Yes | Yes |
+| **Node Definition** | Yes | Yes | Yes |
+
+## Appendix: Full Khronos Copyright Statement
+
+Copyright 2024 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.
+
+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.
+
+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.
+
+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 and confirm the implementation as conformant under
+the process defined by Khronos for this specification; see https://www.khronos.org/conformance/adopters/file-format-adopter-program.
+
+Where this Specification identifies specific sections of external references, only those specifically identified sections define normative functionality. The Khronos Intellectual Property Rights Policy excludes external references to materials and associated enabling technology not created by Khronos from the Scope of this Specification, and any licenses that may be required to implement such referenced materials and associated technologies must be obtained separately and may involve royalty payments.
+
+Khronos® is a registered trademark, and glTF™ is a trademark of The Khronos Group Inc. 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/Vendor/EXT_texture_procedurals_mx_1_39/figures/OpenUSD.png b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/OpenUSD.png
new file mode 100644
index 0000000000..9580a19518
Binary files /dev/null and b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/OpenUSD.png differ
diff --git a/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/boombox_mapping.png b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/boombox_mapping.png
new file mode 100644
index 0000000000..c28d1f0741
Binary files /dev/null and b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/boombox_mapping.png differ
diff --git a/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/boombox_mapping2.png b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/boombox_mapping2.png
new file mode 100644
index 0000000000..502f56b71a
Binary files /dev/null and b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/boombox_mapping2.png differ
diff --git a/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/combine_channels.png b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/combine_channels.png
new file mode 100644
index 0000000000..6688fb1654
Binary files /dev/null and b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/combine_channels.png differ
diff --git a/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/glTF.svg b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/glTF.svg
new file mode 100644
index 0000000000..cda5f6e5d2
--- /dev/null
+++ b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/glTF.svg
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/materialx.svg b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/materialx.svg
new file mode 100644
index 0000000000..42ae2465bd
--- /dev/null
+++ b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/figures/materialx.svg
@@ -0,0 +1 @@
+MaterialXLogo
\ No newline at end of file
diff --git a/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/schema/material.EXT_texture_procedurals_mx_1_39_schema.json b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/schema/material.EXT_texture_procedurals_mx_1_39_schema.json
new file mode 100644
index 0000000000..b46140bba1
--- /dev/null
+++ b/extensions/2.0/Vendor/EXT_texture_procedurals_mx_1_39/schema/material.EXT_texture_procedurals_mx_1_39_schema.json
@@ -0,0 +1,25 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "EXT_texture_procedurals_mx_1_39 MaterialX Procedural Texture Extension",
+ "type": "object",
+ "description": "Extension to define procedural texture graphs using elements defined in MaterialX Specification 1.39",
+ "definitions" : {},
+ "properties": {
+ "materials": {},
+ "textures": {},
+ "images": {},
+ "extensionsUsed": {
+ "type": "array",
+ "items": { "type": "string" },
+ "contains": { "enum": ["KHR_texture_procedurals", "EXT_texture_procedurals_mx_1_39"] }
+ },
+ "extensions": {
+ "type": "object",
+ "properties": {
+
+ },
+ "required": ["KHR_texture_procedurals"]
+ }
+ },
+ "required": ["materials", "extensionsUsed", "extensions"]
+}