This package supports the bi-directional translation between MaterialX material graphs and the glTF Procedural Textures extension.
- The Khronos extensions can be found here:
- The MaterialX specification documents can be found here
- The 1.39 release (or patch releases) of MaterialX available on PyPi is required.
- The
jsonschema
package if Schema validation is desired
The Github repository can be forked / cloned locally and the package built using pip
as follows from the root folder:
pip install .
All dependencies listed will be installed if required.
To convert from a MaterialX document to produce a glTF JSON document the materialx_to_gltf.py
utility script may be used.
The following is an example converting a sample file found in the test folder. The results are saved to a file called checkerboard_graph.gltf
.
python -m gltf_materialx_converter mtlx "tests/data/checkerboard_graph.mtlx"
or
python source/gltf_materialx_converter/materialx_to_gltf.py "tests/data/checkerboard_graph.mtlx"
to run the local script.
To convert from a document containing glTF procedural content to produce a MaterialX document the gltf_to_materialx.py
utility script may be used.
The following is an example converting a sample file found in the test folder. The results are saved to a file called checkerboard_graph_fromgltf.mtlx
.
python -m gltf_materialx_converter gltf "tests/data/checkerboard_graph.gltf"
or
python source/gltf_materialx_converter/gltf_to_materialx.py "tests/data/checkerboard_graph.gltf"
to run the local script.
The following is a simple example of using the API to convert from MaterialX to glTF and then back to MaterialX.
# Import support modules import MaterialX as mx import json # Import conversion module utilities from gltf_materialx_converter import converter as MxGLTFPT from gltf_materialx_converter import utilities as MxGLTFPTUtil input_file = "my_file.mtlx" # Replace with desired file name # Set up definitions and read in a sample file stdlib, libFiles = MxGLTFPTUtil.load_standard_libraries() mxdoc = MxGLTFPTUtil.create_working_document([stdlib]) mx.readFromXmlFile(mxdoc, input_file) # Instantiate a converter converter = MxGLTFPT.glTFMaterialXConverter() # Convert to glTF (JSON) json_string, status = converter.materialX_to_glTF(mxdoc) # Write result to disk gltf_file = input_file.replace('.mtlx', '.gltf') with open(gltf_file, 'w') as f: f.write(json_string) # Convert from glTF to MaterialX mxdoc2 = converter.gltf_string_to_materialX(json_string, stdlib)
A sample Jupyter
notebook which can be run interactively is available here
API documentation can be found here
Documentation can be generated by running doxygen
from the "documents" folder.
It is assumed that Doxygen
has been installed locally.
The following command can be used to run tests from the root folder:
python -m unittest discover -s tests -p "test_*.py"
Only specific configurations of MaterialX can be mapped to glTF Texture Procedurals.
- There must be a
surfacematerial
material node - There must be a
glTF PBR
orunlit
node connected to the surface shader input of the material. - A single
nodegraph
with acolor3
output node which is connected to the base color on the surface shader. The constant node can be replaced with the desired set of nodes, and one or more inputs may be specified to route data into thenodegraph
.
Any document level qualifiers must be pre-resolved when converting rom MaterialX. This includes any fileprefix
qualifiers for image file names.
Description | Documents | Reference Image |
---|---|---|
A sample minimal graph routing a constant color to the downstream shader.
There are no inputs specified on the `nodegraph`.
graph TB
gltf_Material([surfacematerial:material])
style gltf_Material fill:#090, color:#FFF
gltf_Shader[gltf_pbr:surfaceshader]
subgraph gltf_procedural
gltf_procedural_output_color4([output:color3])
style gltf_procedural_output_color4 fill:#09D, color:#FFF
gltf_procedural_constant_color4([constant:color3:1,1,1])
style gltf_procedural_constant_color4 fill:#888, color:#000
end
gltf_Shader --"surfaceshader"--> gltf_Material
gltf_procedural_constant_color4 --> gltf_procedural_output_color4
gltf_procedural_output_color4 --"base_color"--> gltf_Shader
|
MTLX, GLTF, MTLX from GLTF, USD |
The following is a set of example files used for unit testing. The term "Compound nodes" refers to nodes which are implemented as node graphs themselves ("functional graphs" in MaterialX terminology)
For each MaterialX
file the resulting glTF
file is given, along with a diagram of how the graph looks and reference image.
A sample conversion from MaterialX to USDShade
network is provided where applicable.
Examples
Description | Documents | Reference Image |
---|---|---|
The following is a simple graph which adds two colors together.
graph TB
subgraph graph1
graph1_myin1([input:1,0,0])
style graph1_myin1 fill:#09D, color:#FFF
graph1_myin2([input:0.94902, 0.768627, 0.109804])
style graph1_myin2 fill:#09D, color:#FFF
graph1_output_color4([output])
style graph1_output_color4 fill:#09D, color:#FFF
graph1_add_color4[add]
end
Default([surfacematerial])
style Default fill:#090, color:#FFF
gltf_mat[gltf_pbr]
graph1_myin2 --"in1"--> graph1_add_color4
graph1_myin1 --"in2"--> graph1_add_color4
graph1_add_color4 --> graph1_output_color4
gltf_mat --"surfaceshader"--> Default
graph1_output_color4 --"base_color"--> gltf_mat
|
MTLX, GLTF, MTLX from GLTF, USD | |
The following is a pattern graph that produces a checkerboard pattern. The two input colors, and a texture coordinate tiling option are exposed on the node graph. The output is a color which is routed to a downstream glTF PBR shading node (glTF material).
graph TB
subgraph NG_main
NG_main_uvtiling([input:vector2:8,8])
style NG_main_uvtiling fill:#09D, color:#FFF
NG_main_color1([input:color3:1,0.094118,0.031373])
style NG_main_color1 fill:#09D, color:#FFF
NG_main_color2([input:color3:0.035294,0.090196,0.878431])
style NG_main_color2 fill:#09D, color:#FFF
NG_main_output_N_mtlxmix_out([output:color3])
style NG_main_output_N_mtlxmix_out fill:#09D, color:#FFF
NG_main_N_mtlxmix[mix:color3]
NG_main_N_mtlxdotproduct[dotproduct:float]
NG_main_N_mtlxmult[multiply:vector2]
NG_main_N_mtlxsubtract[subtract:vector2]
NG_main_N_mtlxfloor[floor:vector2]
NG_main_N_modulo[modulo:float]
NG_main_Texcoord[texcoord:vector2:0]
end
Gltf_pbr[gltf_pbr:surfaceshader]
MAT_Gltf_pbr([surfacematerial:material])
style MAT_Gltf_pbr fill:#090, color:#FFF
NG_main_N_mtlxmix --> NG_main_output_N_mtlxmix_out
NG_main_color1 --"fg"--> NG_main_N_mtlxmix
NG_main_color2 --"bg"--> NG_main_N_mtlxmix
NG_main_N_modulo --"mix"--> NG_main_N_mtlxmix
NG_main_N_mtlxfloor --"in1"--> NG_main_N_mtlxdotproduct
NG_main_Texcoord --"in1"--> NG_main_N_mtlxmult
NG_main_uvtiling --"in2"--> NG_main_N_mtlxmult
NG_main_N_mtlxmult --"in1"--> NG_main_N_mtlxsubtract
NG_main_N_mtlxsubtract --"in"--> NG_main_N_mtlxfloor
NG_main_N_mtlxdotproduct --"in1"--> NG_main_N_modulo
NG_main_output_N_mtlxmix_out --"base_color"--> Gltf_pbr
Gltf_pbr --"surfaceshader"--> MAT_Gltf_pbr
|
MTLX, GLTF, MTLX from GLTF, USD | |
Pattern graph only without any materials.
graph TB
subgraph splittb_graph
splittb_graph_output_color4([output_color4])
style splittb_graph_output_color4 fill:#09D, color:#FFF
splittb_graph_splittb_color4[splittb_color4]
splittb_graph_texcoord_vector[texcoord_vector:0]
end
subgraph checker_graph
checker_graph_output_color5([output_color5])
style checker_graph_output_color5 fill:#09D, color:#FFF
checker_graph_checkerboard_color4[checkerboard_color4]
checker_graph_texcoord_vector3[texcoord_vector3:0]
end
splittb_graph_texcoord_vector --"texcoord"--> splittb_graph_splittb_color4
splittb_graph_splittb_color4 --> splittb_graph_output_color4
checker_graph_texcoord_vector3 --"texcoord"--> checker_graph_checkerboard_color4
checker_graph_checkerboard_color4 --> checker_graph_output_color5
|
MTLX, GLTF, MTLX from GLTF, | |
Pattern connected to an unsupported (non-glTF) PBR downstream shader.
graph TB
subgraph splittb_graph
splittb_graph_output_color4([output_color4])
style splittb_graph_output_color4 fill:#09D, color:#FFF
splittb_graph_splittb_color4[splittb_color4]
splittb_graph_texcoord_vector3[texcoord_vector3:0]
end
subgraph checker_graph
checker_graph_output_color5([output_color5])
style checker_graph_output_color5 fill:#09D, color:#FFF
checker_graph_checkerboard_color4[checkerboard_color4]
checker_graph_texcoord_vector3[texcoord_vector3:0]
end
standard_surface_surfaceshader1[standard_surface_surfaceshader1]
surfacematerial_material1([surfacematerial_material1])
style surfacematerial_material1 fill:#090, color:#FFF
surfacematerial_material2([surfacematerial_material2])
style surfacematerial_material2 fill:#090, color:#FFF
standard_surface_surfaceshader2[standard_surface_surfaceshader2]
splittb_graph_splittb_color4 --> splittb_graph_output_color4
splittb_graph_texcoord_vector3 --"texcoord"--> splittb_graph_splittb_color4
checker_graph_checkerboard_color4 --> checker_graph_output_color5
checker_graph_texcoord_vector3 --"texcoord"--> checker_graph_checkerboard_color4
splittb_graph_output_color4 --"base_color"--> standard_surface_surfaceshader1
standard_surface_surfaceshader1 --"surfaceshader"--> surfacematerial_material1
standard_surface_surfaceshader2 --"surfaceshader"--> surfacematerial_material2
checker_graph_output_color5 --"base_color"--> standard_surface_surfaceshader2
|
MTLX, GLTF, MTLX from GLTF USD, | (original) (skipping material ) |
Pattern graph using a file texture
graph TB
subgraph nodegraph1
nodegraph1_output_color3([output_color3:color3])
style nodegraph1_output_color3 fill:#09D, color:#FFF
nodegraph1_image_color3[image_color3:color3]
nodegraph1_place2d_vector2[place2d_vector2:vector2]
nodegraph1_texcoord_vector2[texcoord_vector2:vector2:1]
end
gltf_pbr_surfaceshader[gltf_pbr_surfaceshader:surfaceshader]
surfacematerial([surfacematerial:material])
style surfacematerial fill:#090, color:#FFF
nodegraph1_image_color3 --> nodegraph1_output_color3
nodegraph1_place2d_vector2 --"texcoord"--> nodegraph1_image_color3
nodegraph1_texcoord_vector2 --"texcoord"--> nodegraph1_place2d_vector2
nodegraph1_output_color3 --"base_color"--> gltf_pbr_surfaceshader
gltf_pbr_surfaceshader --"surfaceshader"--> surfacematerial
|
MTLX, GLTF, MTLX from GLTF, USD | |
Pattern graph using using multiple file textures with different texture placements and a shared input stream.
graph TB
gltf_pbr_surfaceshader[gltf_pbr:surfaceshader]
surfacematerial([surfacematerial:material])
style surfacematerial fill:#090, color:#FFF
subgraph nodegraph1
nodegraph1_output_color3([output:color3])
style nodegraph1_output_color3 fill:#09D, color:#FFF
nodegraph1_texcoord_vector2[texcoord:vector2:0]
nodegraph1_place2d_vector3[place2d:vector2]
nodegraph1_multiply_color4[multiply:color3]
nodegraph1_image_color4[image:color3]
nodegraph1_image_color3[image:color3]
nodegraph1_place2d_vector2[place2d:vector2]
end
nodegraph1_output_color3 --"base_color"--> gltf_pbr_surfaceshader
gltf_pbr_surfaceshader --"surfaceshader"--> surfacematerial
nodegraph1_multiply_color4 --> nodegraph1_output_color3
nodegraph1_texcoord_vector2 --"texcoord"--> nodegraph1_place2d_vector3
nodegraph1_image_color3 --"in1"--> nodegraph1_multiply_color4
nodegraph1_image_color4 --"in2"--> nodegraph1_multiply_color4
nodegraph1_place2d_vector3 --"texcoord"--> nodegraph1_image_color4
nodegraph1_place2d_vector2 --"texcoord"--> nodegraph1_image_color3
nodegraph1_texcoord_vector2 --"texcoord"--> nodegraph1_place2d_vector2
|
MTLX, GLTF, MTLX from GLTF, USD | |
Pattern graph using using multiple file textures routed to different outputs. Each output
is connected to a different downstream shader.
graph TB
gltf_pbr_surfaceshader[gltf_pbr:surfaceshader]
surfacematerial([surfacematerial:material])
style surfacematerial fill:#090, color:#FFF
surfacematerial1([surfacematerial:material])
style surfacematerial1 fill:#090, color:#FFF
gltf_pbr_surfaceshader1[gltf_pbr:surfaceshader]
subgraph nodegraph1
nodegraph1_output_color4([output:color3])
style nodegraph1_output_color4 fill:#09D, color:#FFF
nodegraph1_output_color3([output:color3])
style nodegraph1_output_color3 fill:#09D, color:#FFF
nodegraph1_texcoord_vector2[texcoord:vector2:0]
nodegraph1_place2d_vector3[place2d:vector2]
nodegraph1_place2d_vector2[place2d:vector2]
nodegraph1_image_color4[image:color3]
nodegraph1_image_color3[image:color3]
end
nodegraph1_output_color3 --"base_color"--> gltf_pbr_surfaceshader
gltf_pbr_surfaceshader --"surfaceshader"--> surfacematerial
gltf_pbr_surfaceshader1 --"surfaceshader"--> surfacematerial1
nodegraph1_output_color4 --"base_color"--> gltf_pbr_surfaceshader1
nodegraph1_texcoord_vector2 --"texcoord"--> nodegraph1_place2d_vector3
nodegraph1_texcoord_vector2 --"texcoord"--> nodegraph1_place2d_vector2
nodegraph1_place2d_vector3 --"texcoord"--> nodegraph1_image_color4
nodegraph1_image_color4 --> nodegraph1_output_color4
nodegraph1_image_color3 --> nodegraph1_output_color3
nodegraph1_place2d_vector2 --"texcoord"--> nodegraph1_image_color3
|
MTLX, GLTF, MTLX from GLTF, USD | |
Procedural graph with intermediary node for shader translation (from standard surface to glTF PBR)
graph LR
surfacematerial_material1([surfacematerial_material1])
style surfacematerial_material1 fill:#090, color:#FFF
gltf_pbr[gltf_pbr]
subgraph translation_graph
translation_graph_base_color_out([base_color_out])
style translation_graph_base_color_out fill:#09D, color:#FFF
translation_graph_metallic_out([metallic_out])
style translation_graph_metallic_out fill:#09D, color:#FFF
translation_graph_roughness_out([roughness_out])
style translation_graph_roughness_out fill:#09D, color:#FFF
translation_graph_transmission_out([transmission_out])
style translation_graph_transmission_out fill:#09D, color:#FFF
translation_graph_thickness_out([thickness_out])
style translation_graph_thickness_out fill:#09D, color:#FFF
translation_graph_attenuation_color_out([attenuation_color_out])
style translation_graph_attenuation_color_out fill:#09D, color:#FFF
translation_graph_sheen_color_out([sheen_color_out])
style translation_graph_sheen_color_out fill:#09D, color:#FFF
translation_graph_sheen_roughness_out([sheen_roughness_out])
style translation_graph_sheen_roughness_out fill:#09D, color:#FFF
translation_graph_clearcoat_out([clearcoat_out])
style translation_graph_clearcoat_out fill:#09D, color:#FFF
translation_graph_clearcoat_roughness_out([clearcoat_roughness_out])
style translation_graph_clearcoat_roughness_out fill:#09D, color:#FFF
translation_graph_emissive_out([emissive_out])
style translation_graph_emissive_out fill:#09D, color:#FFF
translation_graph_ss_to_gltf[ss_to_gltf]
end
gltf_pbr --"surfaceshader"--> surfacematerial_material1
translation_graph_base_color_out --"base_color"--> gltf_pbr
translation_graph_metallic_out --"metallic"--> gltf_pbr
translation_graph_roughness_out --"roughness"--> gltf_pbr
translation_graph_transmission_out --"transmission"--> gltf_pbr
translation_graph_sheen_color_out --"sheen_color"--> gltf_pbr
translation_graph_sheen_roughness_out --"sheen_roughness"--> gltf_pbr
translation_graph_clearcoat_out --"clearcoat"--> gltf_pbr
translation_graph_clearcoat_roughness_out --"clearcoat_roughness"--> gltf_pbr
translation_graph_emissive_out --"emissive"--> gltf_pbr
translation_graph_thickness_out --"thickness"--> gltf_pbr
translation_graph_attenuation_color_out --"attenuation_color"--> gltf_pbr
translation_graph_ss_to_gltf --"base_color_out"--> translation_graph_base_color_out
translation_graph_ss_to_gltf --"metallic_out"--> translation_graph_metallic_out
translation_graph_ss_to_gltf --"roughness_out"--> translation_graph_roughness_out
translation_graph_ss_to_gltf --"transmission_out"--> translation_graph_transmission_out
translation_graph_ss_to_gltf --"thickness_out"--> translation_graph_thickness_out
translation_graph_ss_to_gltf --"attenuation_color_out"--> translation_graph_attenuation_color_out
translation_graph_ss_to_gltf --"sheen_color_out"--> translation_graph_sheen_color_out
translation_graph_ss_to_gltf --"sheen_roughness_out"--> translation_graph_sheen_roughness_out
translation_graph_ss_to_gltf --"clearcoat_out"--> translation_graph_clearcoat_out
translation_graph_ss_to_gltf --"clearcoat_roughness_out"--> translation_graph_clearcoat_roughness_out
translation_graph_ss_to_gltf --"emissive_out"--> translation_graph_emissive_out
|
MTLX, GLTF, MTLX from GLTF | |
Example where the root shader is an "unlit shader". Shader is mapped to a ramp.
graph TB
subgraph unlit_graph
unlit_graph_output_color4([output_color4:color3])
style unlit_graph_output_color4 fill:#09D, color:#FFF
unlit_graph_ramplr_color4[ramplr_color4:color3]
end
unlitshader[unlitshader:surfaceshader]
MAT_unlitshader([MAT_unlitshader:material])
style MAT_unlitshader fill:#090, color:#FFF
unlit_graph_ramplr_color4 --> unlit_graph_output_color4
unlit_graph_output_color4 --"emission_color"--> unlitshader
unlitshader --"surfaceshader"--> MAT_unlitshader
|
MTLX, GLTF, MTLX from GLTF USD | |
Example MaterialX version of "boombox" example (from Khronos sample assets) that shows file name resolving.
graph LR
subgraph boombox_graph
boombox_graph_out_Image([out_Image])
style boombox_graph_out_Image fill:#09D, color:#FFF
boombox_graph_texcoord1[texcoord1:0]
boombox_graph_Image[Image]
end
SR_boombox[SR_boombox]
Material_boombox([Material_boombox])
style Material_boombox fill:#090, color:#FFF
boombox_graph_texcoord1 --"texcoord"--> boombox_graph_Image
boombox_graph_Image --> boombox_graph_out_Image
boombox_graph_out_Image --"base_color"--> SR_boombox
SR_boombox --"surfaceshader"--> Material_boombox
|
MTLX, GLTF, MTLX from GLTF, USD | |
Example with various port data types: integer, vec2, vec3, vec4, color3, color4, integer, matrix33, matrix44
graph LR
glTF_Material([surfacematerial:material])
style glTF_Material fill:#090, color:#FFF
glTF_Shader[gltf_pbr:surfaceshader]
subgraph mygraph
mygraph_out([output:color3])
style mygraph_out fill:#09D, color:#FFF
mygraph_out1([output:color3])
style mygraph_out1 fill:#09D, color:#FFF
mygraph_out2([output:color3])
style mygraph_out2 fill:#09D, color:#FFF
mygraph_out3([output:color3])
style mygraph_out3 fill:#09D, color:#FFF
mygraph_out4([output:color3])
style mygraph_out4 fill:#09D, color:#FFF
mygraph_out6([output:color3])
style mygraph_out6 fill:#09D, color:#FFF
mygraph_out7([output:color3])
style mygraph_out7 fill:#09D, color:#FFF
mygraph_out5([output:color3])
style mygraph_out5 fill:#09D, color:#FFF
mygraph_out8([output:color3])
style mygraph_out8 fill:#09D, color:#FFF
mygraph_convert_color4[convert:color3]
mygraph_convert_color5[convert:color3]
mygraph_convert_color6[convert:color3]
mygraph_convert_color7[convert:color3]
mygraph_determinant_float1[determinant:float]
mygraph_convert_color8[convert:color3]
mygraph_convert_color9[convert:color3]
mygraph_determinant_float2[determinant:float]
mygraph_convert_color10[convert:color3]
mygraph_mix_color3[mix:color3]
mygraph_mix_float1[mix:float]
mygraph_mix_color5[mix:color4]
mygraph_mix_vector2[mix:vector2]
mygraph_multiply_matrix34[multiply:matrix33]
mygraph_multiply_matrix45[multiply:matrix44]
mygraph_constant_integer1([constant:integer:1])
style mygraph_constant_integer1 fill:#888, color:#000
mygraph_mix_vector3[mix:vector3]
mygraph_convert_color11[convert:color3]
mygraph_mix_vector5[mix:vector4]
end
glTF_Shader --"surfaceshader"--> glTF_Material
mygraph_out --"base_color"--> glTF_Shader
mygraph_mix_color3 --> mygraph_out
mygraph_mix_float1 --"in"--> mygraph_convert_color4
mygraph_convert_color4 --> mygraph_out1
mygraph_mix_color5 --"in"--> mygraph_convert_color5
mygraph_convert_color5 --> mygraph_out2
mygraph_mix_vector3 --"in"--> mygraph_convert_color6
mygraph_convert_color6 --> mygraph_out3
mygraph_mix_vector2 --"in"--> mygraph_convert_color7
mygraph_multiply_matrix34 --"in"--> mygraph_determinant_float1
mygraph_convert_color7 --> mygraph_out4
mygraph_determinant_float1 --"in"--> mygraph_convert_color8
mygraph_determinant_float2 --"in"--> mygraph_convert_color9
mygraph_multiply_matrix45 --"in"--> mygraph_determinant_float2
mygraph_convert_color9 --> mygraph_out6
mygraph_convert_color10 --> mygraph_out7
mygraph_constant_integer1 --"in"--> mygraph_convert_color10
mygraph_convert_color8 --> mygraph_out5
mygraph_convert_color11 --> mygraph_out8
mygraph_mix_vector5 --"in"--> mygraph_convert_color11
|
MTLX, GLTF, MTLX from GLTF | |
Example glTF file which requires name identifier generation to convert to MaterialX (a named based system) | MTLX, GLTF, MTLX from GLTF |
All reference images are rendered using the MaterialXView
sample application which is available as part of
MaterialX releases. The release
version used matches the version requirement for this package.
A sample utility called test_render
is provided which will scan all files MaterialX XML files in a given folder hierarchy and use the path to MaterialXView
to
render into the same folder.
Example:
python utilities/test_render.py tests/data -r 512 -c <path to MaterialXView>
where <path to MaterialXView>
is the path to the MaterialXView executable with
a the resolution set to 512 by 512.
Sample build scripts are provided in the utilities
folder as follows:
build.sh
: Will pull from head of the repo, install dependencies, and build the package.build_docs.sh
: Will build only the documentation. Called frombuild.sh
. Doxygen is assumed to be installed. The README files are generated from the template Markdown file:utilitites/README_template.md.
This will install the top level as well as the API documentation versions of this file with appropriate formatting to support theMermaid
graphs used to node graph diagrams.build_tests.sh
: Will run unit tests as well as command line tests.
build.sh
is called within the check-in workflow defined in .github/workflows/main.yml