@needle-tools/materialx
Version:
MaterialX material support for three.js and Needle Engine – render physically based MaterialX shaders in the browser via WebAssembly
984 lines (898 loc) • 1.51 MB
Plain Text
if(MATERIALX_BUILD_DATA_LIBRARY)
# Build generated products from the MaterialX data library.
# Initially, this step is a simple copy across folders, but our intent
# is for it to include meaningful work in the future.
set(DATA_LIBRARY_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/DataLibraryBuild)
file(GLOB_RECURSE MATERIALX_DATA_LIBRARY_SOURCE_FILES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
LIST_DIRECTORIES false
*.mtlx
*.md
*.glsl
*.osl
*.h
*.metal)
foreach(SOURCE_FILE IN LISTS MATERIALX_DATA_LIBRARY_SOURCE_FILES)
set(SOURCE_FILEPATH ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE})
set(DEST_FILEPATH ${DATA_LIBRARY_BUILD_DIR}/${SOURCE_FILE})
add_custom_command(
OUTPUT ${DEST_FILEPATH}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SOURCE_FILEPATH} ${DEST_FILEPATH}
DEPENDS ${SOURCE_FILEPATH})
list(APPEND MATERIALX_DATA_LIBRARY_BUILD_FILES ${DEST_FILEPATH})
endforeach()
add_custom_target(MaterialXBuildData ALL
DEPENDS ${MATERIALX_DATA_LIBRARY_BUILD_FILES})
set(DATA_LIBRARY_DIR ${DATA_LIBRARY_BUILD_DIR})
else()
set(DATA_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(NOT SKBUILD)
install(DIRECTORY ${DATA_LIBRARY_DIR}/
DESTINATION "${MATERIALX_INSTALL_STDLIB_PATH}"
PATTERN "CMakeLists.txt" EXCLUDE)
endif()
if(MATERIALX_BUILD_PYTHON)
set(MATERIALX_PYTHON_LIBRARIES_PATH "${MATERIALX_PYTHON_FOLDER_NAME}/${MATERIALX_INSTALL_STDLIB_PATH}")
if(SKBUILD)
set(MATERIALX_PYTHON_LIBRARIES_PATH "${SKBUILD_PLATLIB_DIR}/MaterialX/libraries")
endif()
install(DIRECTORY ${DATA_LIBRARY_DIR}/
DESTINATION "${MATERIALX_PYTHON_LIBRARIES_PATH}"
PATTERN "CMakeLists.txt" EXCLUDE)
endif()
set(MATERIALX_DATA_LIBRARY_DIR ${DATA_LIBRARY_DIR} PARENT_SCOPE)
# MaterialX Data Libraries
This folder contains the standard data libraries for MaterialX, providing declarations and graph definitions for the MaterialX nodes, and source code for all supported shader generators.
## Standard Pattern Library
- [stdlib](stdlib)
- [stdlib_defs.mtlx](stdlib/stdlib_defs.mtlx) : Nodedef declarations.
- [stdlib_ng.mtlx](stdlib/stdlib_ng.mtlx) : Nodegraph definitions.
- [genglsl](stdlib/genglsl): GLSL language support.
- [lib](stdlib/genglsl/lib) : Shader utility files.
- [stdlib_genglsl_impl.mtlx](stdlib/genglsl/stdlib_genglsl_impl.mtlx) : Mapping from declarations to implementations.
- [genosl](stdlib/genosl): OSL language support.
- [lib](stdlib/genosl/lib) : Shader utility files.
- [stdlib_genosl_impl.mtlx](stdlib/genosl/stdlib_genosl_impl.mtlx) : Mapping from declarations to implementations.
- [genmdl](stdlib/genmdl): MDL language support.
- [stdlib_genmdl_impl.mtlx](stdlib/genmdl/stdlib_genmdl_impl.mtlx) : Mapping from declarations to implementations.
- Additional MaterialX support libraries for MDL are located in the [source/MaterialXGenMdl/mdl/materialx](../source/MaterialXGenMdl/mdl/materialx) package folder
- [genmsl](stdlib/genmsl): MSL language support.
- [lib](stdlib/genmsl/lib) : Shader utility files.
- [stdlib_genmsl_impl.mtlx](stdlib/genmsl/stdlib_genmsl_impl.mtlx) : Mapping from declarations to implementations.
## Physically Based Shading Library
- [pbrlib](pbrlib)
- [pbrlib_defs.mtlx](pbrlib/pbrlib_defs.mtlx) : Nodedef declarations.
- [pbrlib_ng.mtlx](pbrlib/pbrlib_ng.mtlx) : Nodegraph definitions.
- [genglsl](pbrlib/genglsl) : GLSL language support
- [lib](pbrlib/genglsl/lib) : Shader utility files.
- [pbrlib_genglsl_impl.mtlx](pbrlib/genglsl/pbrlib_genglsl_impl.mtlx) : Mapping from declarations to implementations.
- [genosl](pbrlib/genosl) : OSL language support
- [lib](pbrlib/genosl/lib) : Shader utility files.
- [pbrlib_genosl_impl.mtlx](pbrlib/genosl/pbrlib_genosl_impl.mtlx) : Mapping from declarations to implementations.
- [genmdl](pbrlib/genmdl) : MDL language support
- [pbrlib_genmdl_impl.mtlx](pbrlib/genmdl/pbrlib_genmdl_impl.mtlx) : Mapping from declarations to implementations.
- [genmsl](pbrlib/genmsl) : MSL language support
- [pbrlib_genmsl_impl.mtlx](pbrlib/genmsl/pbrlib_genmsl_impl.mtlx) : Mapping from declarations to implementations.
## BxDF Graph Library
- [bxdf](bxdf)
- [standard_surface.mtlx](bxdf/standard_surface.mtlx) : Graph definition of the [Autodesk Standard Surface](https://autodesk.github.io/standard-surface/) shading model.
- [gltf_pbr.mtlx](bxdf/gltf_pbr.mtlx) : Graph definition of the [glTF PBR](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#appendix-b-brdf-implementation) shading model.
- [usd_preview_surface.mtlx](bxdf/usd_preview_surface.mtlx) : Graph definition of the [UsdPreviewSurface](https://openusd.org/release/spec_usdpreviewsurface.html) shading model.
- [lama](bxdf/lama) : Graph definitions of the [MaterialX Lama](https://rmanwiki.pixar.com/display/REN24/MaterialX+Lama) node set.
## Color Management Library
- MaterialX shader generation natively supports a small set of common spaces for input colors, with all color transforms implemented as language-independent MaterialX graphs.The canonical definitions of these color transforms may be found in the OpenColorIO configuration for [ACES 1.2](https://github.com/colour-science/OpenColorIO-Configs/tree/feature/aces-1.2-config/aces_1.2).
- lin_rec709
- g18_rec709
- g22_rec709
- rec709_display
- acescg (lin_ap1)
- g22_ap1
- srgb_texture
- lin_adobergb
- adobergb
- srgb_displayp3
- lin_displayp3
- [cmlib](cmlib)
- [cmlib_defs.mtlx](cmlib/cmlib_defs.mtlx) : Nodedef declarations.
- [cmlib_ng.mtlx](cmlib/cmlib_ng.mtlx) : Nodegraph definitions.
## Target Definitions
- Each target implementation requires a target definition for declaration / implementation correspondence to work.
- The [targets](targets) folder contains definition files for the following core targets:
- GLSL : `genglsl`
- OSL : `genosl`
- MDL : `genmdl`
- MSL : `genmsl`
- Any additional target files should be added under this folder and loaded in as required.
### Target Support
- GLSL target support is for version 4.0 or higher.
- OSL target support is for version 1.12.6 or higher.
- MDL target support is for version 1.6 or higher.
- Basic GLSL and MSL `lightshader` node definitions and implementations are provided for the following light types:
- point, directional, spot
- Shader generation does not currently support:
- `displacementshader` and `volumeshader` nodes for hardware shading targets (GLSL, MSL).
- `hextiledimage` and `hextilednormalmap` for OSL and MDL.
- `blur` the implementation passes through `in` unmodified in all shading languages.
<?xml version="1.0"?>
<materialx version="1.39" colorspace="lin_rec709">
<nodedef name="ND_disney_principled" node="disney_principled" nodegroup="pbr" doc="The Disney Principled BSDF">
<input name="baseColor" type="color3" value="0.16, 0.16, 0.16" uiname="Base Color" uifolder="Base" />
<input name="metallic" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Metallic" uifolder="Base" />
<input name="roughness" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Roughness" uifolder="Base" />
<input name="anisotropic" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Anisotropic" uifolder="Specular" />
<input name="specular" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Specular" uifolder="Specular" />
<input name="specularTint" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Specular Tint" uifolder="Specular" />
<input name="sheen" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Sheen" uifolder="Sheen" />
<input name="sheenTint" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Sheen Tint" uifolder="Sheen" />
<input name="clearcoat" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Clearcoat" uifolder="Clearcoat" />
<input name="clearcoatGloss" type="float" value="1.0" uimin="0.0" uimax="1.0" uiname="Clearcoat Gloss" uifolder="Clearcoat" />
<input name="specTrans" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Spec Trans" uifolder="Transmission" />
<input name="ior" type="float" value="1.5" uisoftmin="1.0" uisoftmax="3.0" uiname="IOR" uifolder="Transmission" />
<input name="subsurface" type="float" value="0.0" uiname="Subsurface" uifolder="Subsurface" />
<input name="subsurfaceDistance" type="color3" value="1.0, 1.0, 1.0" uiname="Subsurface Distance" uifolder="Subsurface" />
<output name="out" type="surfaceshader" />
</nodedef>
<nodegraph name="NG_disney_principled" nodedef="ND_disney_principled">
<!-- Diffuse Layer -->
<invert name="invert_metalness" type="float">
<input name="in" type="float" interfacename="metallic" />
</invert>
<burley_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" nodename="invert_metalness" />
<input name="color" type="color3" interfacename="baseColor" />
<input name="roughness" type="float" interfacename="roughness" />
</burley_diffuse_bsdf>
<!-- Subsurface Layer -->
<subsurface_bsdf name="subsurface_bsdf" type="BSDF">
<input name="color" type="color3" interfacename="baseColor" />
<input name="radius" type="color3" interfacename="subsurfaceDistance" />
</subsurface_bsdf>
<mix name="subsurface_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="diffuse_bsdf" />
<input name="fg" type="BSDF" nodename="subsurface_bsdf" />
<input name="mix" type="float" interfacename="subsurface" />
</mix>
<!-- Sheen Layer -->
<mix name="sheen_color" type="color3">
<input name="bg" type="color3" value="1, 1, 1" />
<input name="fg" type="color3" interfacename="baseColor" />
<input name="mix" type="float" interfacename="sheenTint" />
</mix>
<sheen_bsdf name="sheen_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="sheen" />
<input name="color" type="color3" nodename="sheen_color" />
</sheen_bsdf>
<layer name="sheen_layer" type="BSDF">
<input name="top" type="BSDF" nodename="sheen_bsdf" />
<input name="base" type="BSDF" nodename="subsurface_mix" />
</layer>
<!-- Transmission Layer -->
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="tint" type="color3" interfacename="baseColor" />
<input name="ior" type="float" interfacename="ior" />
<input name="roughness" type="vector2" value="0.0, 0.0" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<mix name="transmission_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="sheen_layer" />
<input name="fg" type="BSDF" nodename="transmission_bsdf" />
<input name="mix" type="float" interfacename="specTrans" />
</mix>
<!-- Dielectric Layer -->
<roughness_anisotropy name="specular_roughness" type="vector2">
<input name="roughness" type="float" interfacename="roughness" />
<input name="anisotropy" type="float" interfacename="anisotropic" />
</roughness_anisotropy>
<multiply name="dielectric_intensity" type="float">
<input name="in1" type="float" interfacename="specular" />
<input name="in2" type="float" value="0.08" />
</multiply>
<mix name="dielectric_tint" type="color3">
<input name="bg" type="color3" value="1, 1, 1" />
<input name="fg" type="color3" interfacename="baseColor" />
<input name="mix" type="float" interfacename="specularTint" />
</mix>
<generalized_schlick_bsdf name="dielectric_bsdf" type="BSDF">
<input name="weight" type="float" nodename="dielectric_intensity" />
<input name="color0" type="color3" nodename="dielectric_tint" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
</generalized_schlick_bsdf>
<layer name="dielectric_layer" type="BSDF">
<input name="top" type="BSDF" nodename="dielectric_bsdf" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>
<!-- Metallic Layer -->
<generalized_schlick_bsdf name="metallic_bsdf" type="BSDF">
<input name="color0" type="color3" interfacename="baseColor" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
</generalized_schlick_bsdf>
<mix name="metallic_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="dielectric_layer" />
<input name="fg" type="BSDF" nodename="metallic_bsdf" />
<input name="mix" type="float" interfacename="metallic" />
</mix>
<!-- Coat Layer -->
<multiply name="coat_intensity" type="float">
<input name="in1" type="float" interfacename="clearcoat" />
<input name="in2" type="float" value="0.04" />
</multiply>
<invert name="coat_roughness" type="float">
<input name="in" type="float" interfacename="clearcoatGloss" />
</invert>
<convert name="coat_roughness_vector" type="vector2">
<input name="in" type="float" nodename="coat_roughness" />
</convert>
<roughness_dual name="coat_roughness_dual" type="vector2">
<input name="roughness" type="vector2" nodename="coat_roughness_vector" />
</roughness_dual>
<generalized_schlick_bsdf name="coat_bsdf" type="BSDF">
<input name="weight" type="float" nodename="coat_intensity" />
<input name="roughness" type="vector2" nodename="coat_roughness_dual" />
</generalized_schlick_bsdf>
<layer name="coat_layer" type="BSDF">
<input name="top" type="BSDF" nodename="coat_bsdf" />
<input name="base" type="BSDF" nodename="metallic_mix" />
</layer>
<!-- Surface Constructor -->
<surface name="surface_constructor" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="coat_layer" />
</surface>
<!-- Output -->
<output name="out" type="surfaceshader" nodename="surface_constructor" />
</nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
<!-- An optimized graph implementation for hardware shading languages,
improving the effectiveness of dynamic branches. -->
<nodegraph name="IMPL_gltf_pbr_surfaceshader_optim" nodedef="ND_gltf_pbr_surfaceshader" target="genglsl">
<!-- Volume -->
<convert name="attenuation_color_vec" type="vector3">
<input name="in" type="color3" interfacename="attenuation_color" />
</convert>
<ln name="ln_attenuation_color_vec" type="vector3">
<input name="in" type="vector3" nodename="attenuation_color_vec" />
</ln>
<divide name="ln_attenuation_color_vec_over_distance" type="vector3">
<input name="in1" type="vector3" nodename="ln_attenuation_color_vec" />
<input name="in2" type="float" interfacename="attenuation_distance" />
</divide>
<multiply name="attenuation_coeff" type="vector3">
<input name="in1" type="vector3" nodename="ln_attenuation_color_vec_over_distance" />
<input name="in2" type="float" value="-1" />
</multiply>
<anisotropic_vdf name="isotropic_volume" type="VDF">
<!-- No scattering yet, so absorption_coeff == attenuation_coeff -->
<input name="absorption" type="vector3" nodename="attenuation_coeff" />
<input name="scattering" type="vector3" value="0, 0, 0" />
<input name="anisotropy" type="float" value="0" />
</anisotropic_vdf>
<!-- Base layer -->
<!-- Compute F0 and F90 of dielectric component -->
<subtract name="one_minus_ior" type="float">
<input name="in1" type="float" value="1" />
<input name="in2" type="float" interfacename="ior" />
</subtract>
<add name="one_plus_ior" type="float">
<input name="in1" type="float" value="1" />
<input name="in2" type="float" interfacename="ior" />
</add>
<divide name="ior_div" type="float">
<input name="in1" type="float" nodename="one_minus_ior" />
<input name="in2" type="float" nodename="one_plus_ior" />
</divide>
<multiply name="dielectric_f0_from_ior" type="float">
<input name="in1" type="float" nodename="ior_div" />
<input name="in2" type="float" nodename="ior_div" />
</multiply>
<multiply name="dielectric_f0_from_ior_specular_color" type="color3">
<input name="in1" type="color3" interfacename="specular_color" />
<input name="in2" type="float" nodename="dielectric_f0_from_ior" />
</multiply>
<min name="clamped_dielectric_f0_from_ior_specular_color" type="color3">
<input name="in1" type="color3" nodename="dielectric_f0_from_ior_specular_color" />
<input name="in2" type="float" value="1" />
</min>
<multiply name="dielectric_f0" type="color3">
<input name="in1" type="color3" nodename="clamped_dielectric_f0_from_ior_specular_color" />
<input name="in2" type="float" interfacename="specular" />
</multiply>
<multiply name="dielectric_f90" type="color3">
<input name="in1" type="color3" value="1, 1, 1" />
<input name="in2" type="float" interfacename="specular" />
</multiply>
<!-- Roughness -->
<combine2 name="roughness_uv" type="vector2">
<input name="in1" type="float" nodename="clamped_at" />
<input name="in2" type="float" nodename="clamped_ab" />
</combine2>
<clamp name="clamped_at" type="float">
<input name="in" type="float" nodename="at" />
<input name="low" type="float" value="0.00001" />
<input name="high" type="float" value="1.0" />
</clamp>
<clamp name="clamped_ab" type="float">
<input name="in" type="float" nodename="alpha_roughness" />
<input name="low" type="float" value="0.00001" />
<input name="high" type="float" value="1.0" />
</clamp>
<multiply name="alpha_roughness" type="float">
<input name="in1" type="float" interfacename="roughness" />
<input name="in2" type="float" interfacename="roughness" />
</multiply>
<multiply name="strength_2" type="float">
<input name="in1" type="float" interfacename="anisotropy_strength" />
<input name="in2" type="float" interfacename="anisotropy_strength" />
</multiply>
<mix name="at" type="float">
<input name="fg" type="float" value="1" />
<input name="bg" type="float" nodename="alpha_roughness" />
<input name="mix" type="float" nodename="strength_2" />
</mix>
<!-- Dielectric -->
<invert name="transmission_inv" type="float">
<input name="in" type="float" interfacename="transmission" />
</invert>
<oren_nayar_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" nodename="transmission_inv" />
<input name="color" type="color3" interfacename="base_color" />
<input name="normal" type="vector3" interfacename="normal" />
</oren_nayar_diffuse_bsdf>
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="transmission" />
<input name="tint" type="color3" interfacename="base_color" />
<input name="ior" type="float" interfacename="ior" />
<input name="roughness" type="vector2" nodename="roughness_uv" />
<input name="normal" type="vector3" interfacename="normal" />
<input name="tangent" type="vector3" nodename="selected_tangent" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<add name="transmission_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="diffuse_bsdf" />
<input name="in2" type="BSDF" nodename="transmission_bsdf" />
</add>
<invert name="iridescence_inv" type="float">
<input name="in" type="float" interfacename="iridescence" />
</invert>
<generalized_schlick_bsdf name="reflection_bsdf" type="BSDF">
<input name="weight" type="float" nodename="iridescence_inv" />
<input name="color0" type="color3" nodename="dielectric_f0" />
<input name="color90" type="color3" nodename="dielectric_f90" />
<input name="roughness" type="vector2" nodename="roughness_uv" />
<input name="normal" type="vector3" interfacename="normal" />
<input name="tangent" type="vector3" nodename="selected_tangent" />
<input name="scatter_mode" type="string" value="R" />
</generalized_schlick_bsdf>
<generalized_schlick_bsdf name="reflection_bsdf_tf" type="BSDF">
<input name="weight" type="float" interfacename="iridescence" />
<input name="color0" type="color3" nodename="dielectric_f0" />
<input name="color90" type="color3" nodename="dielectric_f90" />
<input name="roughness" type="vector2" nodename="roughness_uv" />
<input name="normal" type="vector3" interfacename="normal" />
<input name="tangent" type="vector3" nodename="selected_tangent" />
<input name="scatter_mode" type="string" value="R" />
<input name="thinfilm_thickness" type="float" interfacename="iridescence_thickness" />
<input name="thinfilm_ior" type="float" interfacename="iridescence_ior" />
</generalized_schlick_bsdf>
<add name="reflection_bsdf_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="reflection_bsdf" />
<input name="in2" type="BSDF" nodename="reflection_bsdf_tf" />
</add>
<layer name="dielectric_layer" type="BSDF">
<input name="top" type="BSDF" nodename="reflection_bsdf_blend" />
<input name="base" type="BSDF" nodename="transmission_blend" />
</layer>
<!-- Metal -->
<generalized_schlick_bsdf name="metal_bsdf" type="BSDF">
<input name="weight" type="float" nodename="iridescence_inv" />
<input name="color0" type="color3" interfacename="base_color" />
<input name="color90" type="color3" value="1, 1, 1" />
<input name="roughness" type="vector2" nodename="roughness_uv" />
<input name="normal" type="vector3" interfacename="normal" />
<input name="tangent" type="vector3" nodename="selected_tangent" />
</generalized_schlick_bsdf>
<generalized_schlick_bsdf name="metal_bsdf_tf" type="BSDF">
<input name="weight" type="float" interfacename="iridescence" />
<input name="color0" type="color3" interfacename="base_color" />
<input name="color90" type="color3" value="1, 1, 1" />
<input name="roughness" type="vector2" nodename="roughness_uv" />
<input name="normal" type="vector3" interfacename="normal" />
<input name="tangent" type="vector3" nodename="selected_tangent" />
<input name="thinfilm_thickness" type="float" interfacename="iridescence_thickness" />
<input name="thinfilm_ior" type="float" interfacename="iridescence_ior" />
</generalized_schlick_bsdf>
<add name="metal_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="metal_bsdf" />
<input name="in2" type="BSDF" nodename="metal_bsdf_tf" />
</add>
<!-- Dielectric/metal mix -->
<mix name="base_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="dielectric_layer" />
<input name="fg" type="BSDF" nodename="metal_blend" />
<input name="mix" type="float" interfacename="metallic" />
</mix>
<!-- Sheen layer -->
<!-- Compute sheen intensity = max(sheen_color.r, sheen_color.g, sheen_color.b) -->
<extract name="sheen_color_r" type="float">
<input name="in" type="color3" interfacename="sheen_color" />
<input name="index" type="integer" value="0" />
</extract>
<extract name="sheen_color_g" type="float">
<input name="in" type="color3" interfacename="sheen_color" />
<input name="index" type="integer" value="1" />
</extract>
<extract name="sheen_color_b" type="float">
<input name="in" type="color3" interfacename="sheen_color" />
<input name="index" type="integer" value="2" />
</extract>
<max name="sheen_color_max_rg" type="float">
<input name="in1" type="float" nodename="sheen_color_r" />
<input name="in2" type="float" nodename="sheen_color_g" />
</max>
<max name="sheen_intensity" type="float">
<input name="in1" type="float" nodename="sheen_color_max_rg" />
<input name="in2" type="float" nodename="sheen_color_b" />
</max>
<multiply name="sheen_roughness_sq" type="float">
<input name="in1" type="float" interfacename="sheen_roughness" />
<input name="in2" type="float" interfacename="sheen_roughness" />
</multiply>
<divide name="sheen_color_normalized" type="color3">
<input name="in1" type="color3" interfacename="sheen_color" />
<input name="in2" type="float" nodename="sheen_intensity" />
</divide>
<sheen_bsdf name="sheen_bsdf" type="BSDF">
<input name="weight" type="float" nodename="sheen_intensity" />
<input name="color" type="color3" nodename="sheen_color_normalized" />
<input name="roughness" type="float" nodename="sheen_roughness_sq" />
<input name="normal" type="vector3" interfacename="normal" />
</sheen_bsdf>
<layer name="sheen_layer" type="BSDF">
<input name="top" type="BSDF" nodename="sheen_bsdf" />
<input name="base" type="BSDF" nodename="base_mix" />
</layer>
<!-- Clearcoat -->
<roughness_anisotropy name="clearcoat_roughness_uv" type="vector2">
<input name="roughness" type="float" interfacename="clearcoat_roughness" />
</roughness_anisotropy>
<dielectric_bsdf name="clearcoat_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="clearcoat" />
<input name="roughness" type="vector2" nodename="clearcoat_roughness_uv" />
<input name="ior" type="float" value="1.5" />
<input name="normal" type="vector3" interfacename="clearcoat_normal" />
<input name="tangent" type="vector3" interfacename="tangent" />
</dielectric_bsdf>
<layer name="clearcoat_layer" type="BSDF">
<input name="top" type="BSDF" nodename="clearcoat_bsdf" />
<input name="base" type="BSDF" nodename="sheen_layer" />
</layer>
<!-- Emission -->
<multiply name="emission_color" type="color3">
<input name="in1" type="color3" interfacename="emissive" />
<input name="in2" type="float" interfacename="emissive_strength" />
</multiply>
<uniform_edf name="emission" type="EDF">
<input name="color" type="color3" nodename="emission_color" />
</uniform_edf>
<!-- Alpha -->
<ifgreatereq name="opacity_mask_cutoff" type="float">
<input name="value1" type="float" interfacename="alpha" />
<input name="value2" type="float" interfacename="alpha_cutoff" />
<input name="in1" type="float" value="1" />
<input name="in2" type="float" value="0" />
</ifgreatereq>
<ifequal name="opacity_mask" type="float">
<input name="value1" type="integer" interfacename="alpha_mode" />
<input name="value2" type="integer" value="1" />
<input name="in1" type="float" nodename="opacity_mask_cutoff" />
<input name="in2" type="float" interfacename="alpha" />
</ifequal>
<ifequal name="opacity" type="float">
<input name="value1" type="integer" interfacename="alpha_mode" />
<input name="value2" type="integer" value="0" />
<input name="in1" type="float" value="1" />
<input name="in2" type="float" nodename="opacity_mask" />
</ifequal>
<!-- Anisotropy -->
<multiply name="rad_2_deg" type="float">
<input name="in1" type="float" interfacename="anisotropy_rotation" />
<input name="in2" type="float" value="-57.295780" />
</multiply>
<rotate3d name="rotate_tangent" type="vector3">
<input name="in" type="vector3" interfacename="tangent" />
<input name="amount" type="float" nodename="rad_2_deg" />
<input name="axis" type="vector3" interfacename="normal" />
</rotate3d>
<normalize name="normalize_tangent" type="vector3">
<input name="in" type="vector3" nodename="rotate_tangent" />
</normalize>
<absval name="abs_anisotropy_rotation" type="float">
<input name="in" type="float" interfacename="anisotropy_rotation"/>
</absval>
<ifgreater name="selected_tangent" type="vector3">
<input name="value1" type="float" nodename="abs_anisotropy_rotation" />
<input name="value2" type="float" value="0.0" />
<input name="in1" type="vector3" nodename="normalize_tangent" />
<input name="in2" type="vector3" interfacename="tangent" />
</ifgreater>
<!-- Surface -->
<surface name="shader_constructor" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="clearcoat_layer" />
<input name="edf" type="EDF" nodename="emission" />
<input name="opacity" type="float" nodename="opacity" />
</surface>
<output name="out" type="surfaceshader" nodename="shader_constructor" />
</nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
<!-- An optimized graph implementation for hardware shading languages,
improving the effectiveness of dynamic branches. -->
<nodegraph name="NG_open_pbr_surface_surfaceshader_optim" nodedef="ND_open_pbr_surface_surfaceshader" target="genglsl">
<!-- Roughening due to coat-->
<power name="coat_roughness_to_power_4" type="float">
<input name="in1" type="float" interfacename="coat_roughness" />
<input name="in2" type="float" value="4.0" />
</power>
<multiply name="two_times_coat_roughness_to_power_4" type="float">
<input name="in1" type="float" nodename="coat_roughness_to_power_4" />
<input name="in2" type="float" value="2.0" />
</multiply>
<power name="specular_roughness_to_power_4" type="float">
<input name="in1" type="float" interfacename="specular_roughness" />
<input name="in2" type="float" value="4.0" />
</power>
<add name="add_coat_and_spec_roughnesses_to_power_4" type="float">
<input name="in1" type="float" nodename="two_times_coat_roughness_to_power_4" />
<input name="in2" type="float" nodename="specular_roughness_to_power_4" />
</add>
<min name="min_1_add_coat_and_spec_roughnesses_to_power_4" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" nodename="add_coat_and_spec_roughnesses_to_power_4" />
</min>
<power name="coat_affected_specular_roughness" type="float">
<input name="in1" type="float" nodename="min_1_add_coat_and_spec_roughnesses_to_power_4" />
<input name="in2" type="float" value="0.25" />
</power>
<mix name="effective_specular_roughness" type="float">
<input name="fg" type="float" nodename="coat_affected_specular_roughness" />
<input name="bg" type="float" interfacename="specular_roughness" />
<input name="mix" type="float" interfacename="coat_weight" />
</mix>
<!-- Calculate main specular roughness -->
<open_pbr_anisotropy name="main_roughness" type="vector2">
<input name="roughness" type="float" nodename="effective_specular_roughness" />
<input name="anisotropy" type="float" interfacename="specular_roughness_anisotropy" />
</open_pbr_anisotropy>
<!-- Subsurface (thin-walled) -->
<max name="subsurface_color_nonnegative" type="color3">
<input name="in1" type="color3" interfacename="subsurface_color" />
<input name="in2" type="float" value="0.0" />
</max>
<oren_nayar_diffuse_bsdf name="subsurface_thin_walled_reflection_bsdf" type="BSDF">
<input name="color" type="color3" nodename="subsurface_color_nonnegative" />
<input name="roughness" type="float" interfacename="base_diffuse_roughness" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
</oren_nayar_diffuse_bsdf>
<subtract name="one_minus_subsurface_scatter_anisotropy" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" interfacename="subsurface_scatter_anisotropy" />
</subtract>
<multiply name="subsurface_thin_walled_brdf_factor" type="color3">
<input name="in1" type="color3" interfacename="subsurface_color" />
<input name="in2" type="float" nodename="one_minus_subsurface_scatter_anisotropy" />
</multiply>
<multiply name="subsurface_thin_walled_reflection" type="BSDF">
<input name="in1" type="BSDF" nodename="subsurface_thin_walled_reflection_bsdf" />
<input name="in2" type="color3" nodename="subsurface_thin_walled_brdf_factor" />
</multiply>
<translucent_bsdf name="subsurface_thin_walled_transmission_bsdf" type="BSDF">
<input name="color" type="color3" nodename="subsurface_color_nonnegative" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
</translucent_bsdf>
<add name="one_plus_subsurface_scatter_anisotropy" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" interfacename="subsurface_scatter_anisotropy" />
</add>
<multiply name="subsurface_thin_walled_btdf_factor" type="color3">
<input name="in1" type="color3" interfacename="subsurface_color" />
<input name="in2" type="float" nodename="one_plus_subsurface_scatter_anisotropy" />
</multiply>
<multiply name="subsurface_thin_walled_transmission" type="BSDF">
<input name="in1" type="BSDF" nodename="subsurface_thin_walled_transmission_bsdf" />
<input name="in2" type="color3" nodename="subsurface_thin_walled_btdf_factor" />
</multiply>
<mix name="subsurface_thin_walled" type="BSDF">
<input name="fg" type="BSDF" nodename="subsurface_thin_walled_reflection" />
<input name="bg" type="BSDF" nodename="subsurface_thin_walled_transmission" />
<input name="mix" type="float" value="0.5" />
</mix>
<!-- Subsurface (non-thin-walled) -->
<multiply name="subsurface_radius_scaled" type="color3">
<input name="in1" type="color3" interfacename="subsurface_radius_scale" />
<input name="in2" type="float" interfacename="subsurface_radius" />
</multiply>
<subsurface_bsdf name="subsurface_bsdf" type="BSDF">
<input name="color" type="color3" nodename="subsurface_color_nonnegative" />
<input name="radius" type="color3" nodename="subsurface_radius_scaled" />
<input name="anisotropy" type="float" interfacename="subsurface_scatter_anisotropy" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
</subsurface_bsdf>
<!-- Opaque Dielectric Base -->
<max name="base_color_nonnegative" type="color3">
<input name="in1" type="color3" interfacename="base_color" />
<input name="in2" type="float" value="0.0" />
</max>
<oren_nayar_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="base_weight" />
<input name="color" type="color3" nodename="base_color_nonnegative" />
<input name="roughness" type="float" interfacename="base_diffuse_roughness" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
<input name="energy_compensation" type="boolean" value="true" />
</oren_nayar_diffuse_bsdf>
<convert name="subsurface_selector" type="float">
<input name="in" type="boolean" interfacename="geometry_thin_walled" />
</convert>
<mix name="selected_subsurface" type="BSDF">
<input name="fg" type="BSDF" nodename="subsurface_thin_walled" />
<input name="bg" type="BSDF" nodename="subsurface_bsdf" />
<input name="mix" type="float" nodename="subsurface_selector" />
</mix>
<mix name="opaque_base" type="BSDF">
<input name="fg" type="BSDF" nodename="selected_subsurface" />
<input name="bg" type="BSDF" nodename="diffuse_bsdf" />
<input name="mix" type="float" interfacename="subsurface_weight" />
</mix>
<!-- Dielectric Base VDF -->
<convert name="transmission_color_vector" type="vector3">
<input name="in" type="color3" interfacename="transmission_color" />
</convert>
<ln name="transmission_color_ln" type="vector3">
<input name="in" type="vector3" nodename="transmission_color_vector" />
</ln>
<multiply name="extinction_coeff_denom" type="vector3">
<input name="in1" type="vector3" nodename="transmission_color_ln" />
<input name="in2" type="float" value="-1.0" />
</multiply>
<convert name="transmission_depth_vector" type="vector3">
<input name="in" type="float" interfacename="transmission_depth" />
</convert>
<divide name="extinction_coeff" type="vector3">
<input name="in1" type="vector3" nodename="extinction_coeff_denom" />
<input name="in2" type="vector3" nodename="transmission_depth_vector" />
</divide>
<convert name="transmission_scatter_vector" type="vector3">
<input name="in" type="color3" interfacename="transmission_scatter" />
</convert>
<divide name="scattering_coeff" type="vector3">
<input name="in1" type="vector3" nodename="transmission_scatter_vector" />
<input name="in2" type="vector3" nodename="transmission_depth_vector" />
</divide>
<subtract name="absorption_coeff" type="vector3">
<input name="in1" type="vector3" nodename="extinction_coeff" />
<input name="in2" type="vector3" nodename="scattering_coeff" />
</subtract>
<extract name="absorption_coeff_x" type="float">
<input name="in" type="vector3" nodename="absorption_coeff" />
<input name="index" type="integer" value="0" />
</extract>
<extract name="absorption_coeff_y" type="float">
<input name="in" type="vector3" nodename="absorption_coeff" />
<input name="index" type="integer" value="1" />
</extract>
<extract name="absorption_coeff_z" type="float">
<input name="in" type="vector3" nodename="absorption_coeff" />
<input name="index" type="integer" value="2" />
</extract>
<min name="absorption_coeff_min_x_y" type="float">
<input name="in1" type="float" nodename="absorption_coeff_x" />
<input name="in2" type="float" nodename="absorption_coeff_y" />
</min>
<min name="absorption_coeff_min" type="float">
<input name="in1" type="float" nodename="absorption_coeff_min_x_y" />
<input name="in2" type="float" nodename="absorption_coeff_z" />
</min>
<convert name="absorption_coeff_min_vector" type="vector3">
<input name="in" type="float" nodename="absorption_coeff_min" />
</convert>
<subtract name="absorption_coeff_shifted" type="vector3">
<input name="in1" type="vector3" nodename="absorption_coeff" />
<input name="in2" type="vector3" nodename="absorption_coeff_min_vector" />
</subtract>
<ifgreater name="if_absorption_coeff_shifted" type="vector3">
<input name="value1" type="float" value="0.0" />
<input name="value2" type="float" nodename="absorption_coeff_min" />
<input name="in1" type="vector3" nodename="absorption_coeff_shifted" />
<input name="in2" type="vector3" nodename="absorption_coeff" />
</ifgreater>
<ifgreater name="if_volume_absorption" type="vector3">
<input name="value1" type="float" interfacename="transmission_depth" />
<input name="value2" type="float" value="0.0" />
<input name="in1" type="vector3" nodename="if_absorption_coeff_shifted" />
<input name="in2" type="vector3" value="0.0,0.0,0.0" />
</ifgreater>
<ifgreater name="if_volume_scattering" type="vector3">
<input name="value1" type="float" interfacename="transmission_depth" />
<input name="value2" type="float" value="0.0" />
<input name="in1" type="vector3" nodename="scattering_coeff" />
<input name="in2" type="vector3" value="0.0,0.0,0.0" />
</ifgreater>
<anisotropic_vdf name="dielectric_volume" type="VDF">
<input name="absorption" type="vector3" nodename="if_volume_absorption" />
<input name="scattering" type="vector3" nodename="if_volume_scattering" />
<input name="anisotropy" type="float" interfacename="transmission_scatter_anisotropy" />
</anisotropic_vdf>
<!-- Thin-film Thickness -->
<multiply name="thin_film_thickness_nm" type="float">
<input name="in1" type="float" interfacename="thin_film_thickness" />
<input name="in2" type="float" value="1000.0" />
</multiply>
<!-- Dielectric Base -->
<!-- apply IOR ratio inversion method to avoid TIR artifact (as in Coat TIR section of spec) -->
<divide name="specular_to_coat_ior_ratio" type="float">
<input name="in1" type="float" interfacename="specular_ior" />
<input name="in2" type="float" interfacename="coat_ior" />
</divide>
<divide name="coat_to_specular_ior_ratio" type="float">
<input name="in1" type="float" interfacename="coat_ior" />
<input name="in2" type="float" interfacename="specular_ior" />
</divide>
<ifgreater name="specular_to_coat_ior_ratio_tir_fix" type="float">
<input name="value1" type="float" nodename="specular_to_coat_ior_ratio" />
<input name="value2" type="float" value="1.0" />
<input name="in1" type="float" nodename="specular_to_coat_ior_ratio" />
<input name="in2" type="float" nodename="coat_to_specular_ior_ratio" />
</ifgreater>
<mix name="eta_s" type="float">
<input name="fg" type="float" nodename="specular_to_coat_ior_ratio_tir_fix" />
<input name="bg" type="float" interfacename="specular_ior" />
<input name="mix" type="float" interfacename="coat_weight" />
</mix>
<subtract name="eta_s_minus_one" type="float">
<input name="in1" type="float" nodename="eta_s" />
<input name="in2" type="float" value="1.0" />
</subtract>
<add name="eta_s_plus_one" type="float">
<input name="in1" type="float" nodename="eta_s" />
<input name="in2" type="float" value="1.0" />
</add>
<divide name="specular_F0_sqrt" type="float">
<input name="in1" type="float" nodename="eta_s_minus_one" />
<input name="in2" type="float" nodename="eta_s_plus_one" />
</divide>
<multiply name="specular_F0" type="float">
<input name="in1" type="float" nodename="specular_F0_sqrt" />
<input name="in2" type="float" nodename="specular_F0_sqrt" />
</multiply>
<multiply name="scaled_specular_F0" type="float">
<input name="in1" type="float" interfacename="specular_weight" />
<input name="in2" type="float" nodename="specular_F0" />
</multiply>
<clamp name="scaled_specular_F0_clamped" type="float">
<input name="in" type="float" nodename="scaled_specular_F0" />
<input name="low" type="float" value="0.0" />
<input name="high" type="float" value="0.99999" />
</clamp>
<sqrt name="sqrt_scaled_specular_F0" type="float">
<input name="in" type="float" nodename="scaled_specular_F0_clamped" />
</sqrt>
<sign name="sign_eta_s_minus_one" type="float">
<input name="in" type="float" nodename="eta_s_minus_one" />
</sign>
<multiply name="modulated_eta_s_epsilon" type="float">
<input name="in1" type="float" nodename="sign_eta_s_minus_one" />
<input name="in2" type="float" nodename="sqrt_scaled_specular_F0" />
</multiply>
<subtract name="one_minus_modulated_eta_s_epsilon" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" nodename="modulated_eta_s_epsilon" />
</subtract>
<add name="one_plus_modulated_eta_s_epsilon" type="float">
<input name="in1" type="float" value="1.0" />
<input name="in2" type="float" nodename="modulated_eta_s_epsilon" />
</add>
<divide name="modulated_eta_s" type="float">
<input name="in1" type="float" nodename="one_plus_modulated_eta_s_epsilon" />
<input name="in2" type="float" nodename="one_minus_modulated_eta_s_epsilon" />
</divide>
<ifgreater name="if_transmission_tint" type="color3">
<input name="value1" type="float" interfacename="transmission_depth" />
<input name="value2" type="float" value="0.0" />
<input name="in1" type="color3" value="1.0, 1.0, 1.0" />
<input name="in2" type="color3" interfacename="transmission_color" />
</ifgreater>
<dielectric_bsdf name="dielectric_transmission" type="BSDF">
<input name="tint" type="color3" nodename="if_transmission_tint" />
<input name="ior" type="float" nodename="modulated_eta_s" />
<input name="roughness" type="vector2" nodename="main_roughness" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
<input name="tangent" type="vector3" interfacename="geometry_tangent" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<layer name="dielectric_volume_transmission" type="BSDF">
<input name="top" type="BSDF" nodename="dielectric_transmission" />
<input name="base" type="VDF" nodename="dielectric_volume" />
</layer>
<mix name="dielectric_substrate" type="BSDF">
<input name="fg" type="BSDF" nodename="dielectric_volume_transmission" />
<input name="bg" type="BSDF" nodename="opaque_base" />
<input name="mix" type="float" interfacename="transmission_weight" />
</mix>
<invert name="thin_film_weight_inv" type="float">
<input name="in" type="float" interfacename="thin_film_weight" />
</invert>
<dielectric_bsdf name="dielectric_reflection" type="BSDF">
<input name="weight" type="float" nodename="thin_film_weight_inv" />
<input name="tint" type="color3" interfacename="specular_color" />
<input name="ior" type="float" nodename="modulated_eta_s" />
<input name="roughness" type="vector2" nodename="main_roughness" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
<input name="tangent" type="vector3" interfacename="geometry_tangent" />
<input name="scatter_mode" type="string" value="R" />
</dielectric_bsdf>
<dielectric_bsdf name="dielectric_reflection_tf" type="BSDF">
<input name="weight" type="float" interfacename="thin_film_weight" />
<input name="tint" type="color3" interfacename="specular_color" />
<input name="ior" type="float" nodename="modulated_eta_s" />
<input name="roughness" type="vector2" nodename="main_roughness" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
<input name="tangent" type="vector3" interfacename="geometry_tangent" />
<input name="scatter_mode" type="string" value="R" />
<input name="thinfilm_thickness" type="float" nodename="thin_film_thickness_nm" />
<input name="thinfilm_ior" type="float" interfacename="thin_film_ior" />
</dielectric_bsdf>
<add name="dielectric_reflection_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="dielectric_reflection" />
<input name="in2" type="BSDF" nodename="dielectric_reflection_tf" />
</add>
<layer name="dielectric_base" type="BSDF">
<input name="top" type="BSDF" nodename="dielectric_reflection_blend" />
<input name="base" type="BSDF" nodename="dielectric_substrate" />
</layer>
<!-- Metal Layer -->
<multiply name="metal_reflectivity" type="color3">
<input name="in1" type="color3" interfacename="base_color" />
<input name="in2" type="float" interfacename="base_weight" />
</multiply>
<multiply name="metal_edgecolor" type="color3">
<input name="in1" type="color3" interfacename="specular_color" />
<input name="in2" type="float" interfacename="specular_weight" />
</multiply>
<multiply name="specular_weight_tf" type="float">
<input name="in1" type="float" interfacename="specular_weight" />
<input name="in2" type="float" interfacename="thin_film_weight" />
</multiply>
<multiply name="specular_weight_tf_inv" type="float">
<input name="in1" type="float" interfacename="specular_weight" />
<input name="in2" type="float" nodename="thin_film_weight_inv" />
</multiply>
<generalized_schlick_bsdf name="metal_bsdf" type="BSDF">
<input name="weight" type="float" nodename="specular_weight_tf_inv" />
<input name="color0" type="color3" nodename="metal_reflectivity" />
<input name="color82" type="color3" nodename="metal_edgecolor" />
<input name="roughness" type="vector2" nodename="main_roughness" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
<input name="tangent" type="vector3" interfacename="geometry_tangent" />
</generalized_schlick_bsdf>
<generalized_schlick_bsdf name="metal_bsdf_tf" type="BSDF">
<input name="weight" type="float" nodename="specular_weight_tf" />
<input name="color0" type="color3" nodename="metal_reflectivity" />
<input name="color82" type="color3" nodename="metal_edgecolor" />
<input name="roughness" type="vector2" nodename="main_roughness" />
<input name="normal" type="vector3" interfacename="geometry_normal" />
<input name="tangent" type="vector3" interfacename="geometry_tangent" />
<input name="thinfilm_thickness" type="float" nodename="thin_film_thickness_nm" />
<input name="thinfilm_ior" type="float" interfacename="thin_film_ior" />
</generalized_schlick_bsdf>
<add name="metal_bsdf_tf_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="metal_bsdf" />
<input name="in2" type="BSDF" nodename="metal_bsdf_tf" />
</add>
<mix name="base_substrate" type="BSDF">
<input name="fg" type="BSDF" nodename="metal_bsdf_tf_blend" />
<input name="bg" type="BSDF" nodename="dielectric_base" />
<input name="mix" type="float" interfacename="base_metalness" />
</mix>
<!-- Coat darkening calculation -->
<!-- approximate Kcoat, "internal diffu