# 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.
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)
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations of common light nodes, used in code generation for hardware
    shading languages that require explicit light loops.

    These nodes are a required implementation detail for hardware shader
    generation, and are not themselves part of the MaterialX standard.
  -->

  <!-- ======================================================================== -->
  <!-- Light shader nodes                                                       -->
  <!-- ======================================================================== -->

  <!--
    Node: <point_light>
  -->
  <nodedef name="ND_point_light" node="point_light" nodegroup="light" doc="A light shader node of 'point' type.">
    <input name="position" type="vector3" doc="Light source position." />
    <input name="color" type="color3" doc="Light color." />
    <input name="intensity" type="float" doc="Light intensity." />
    <input name="decay_rate" type="float" value="2.0" doc="Light decay exponent. Defaults to 2 for quadratic decay." />
    <output name="out" type="lightshader" />
  </nodedef>

  <!--
    Node: <directional_light>
  -->
  <nodedef name="ND_directional_light" node="directional_light" nodegroup="light" doc="A light shader node of 'directional' type.">
    <input name="direction" type="vector3" doc="Light source direction." />
    <input name="color" type="color3" doc="Light color." />
    <input name="intensity" type="float" doc="Light intensity." />
    <output name="out" type="lightshader" />
  </nodedef>

  <!--
    Node: <spot_light>
  -->
  <nodedef name="ND_spot_light" node="spot_light" nodegroup="light" doc="A light shader node of 'spot' type.">
    <input name="position" type="vector3" doc="Light source position." />
    <input name="direction" type="vector3" doc="Light source direction." />
    <input name="color" type="color3" doc="Light color." />
    <input name="intensity" type="float" doc="Light intensity." />
    <input name="decay_rate" type="float" value="2.0" doc="Light decay exponent. Defaults to 2 for quadratic decay." />
    <input name="inner_angle" type="float" doc="Inner cone angle." />
    <input name="outer_angle" type="float" doc="Outer cone angle." />
    <output name="out" type="lightshader" />
  </nodedef>

</materialx>
void mx_point_light(LightData light, float3 position, thread lightshader& result)
{
    result.direction = light.position - position;
    float distance = length(result.direction) + M_FLOAT_EPS;
    float attenuation = pow(distance + 1.0, light.decay_rate + M_FLOAT_EPS);
    result.intensity = light.color * light.intensity / attenuation;
    result.direction /= distance;
}
void mx_spot_light(LightData light, float3 position, thread lightshader& result)
{
    result.direction = light.position - position;
    float distance = length(result.direction) + M_FLOAT_EPS;
    float attenuation = pow(distance + 1.0, light.decay_rate + M_FLOAT_EPS);
    result.intensity = light.color * light.intensity / attenuation;
    result.direction /= distance;
    float low = min(light.inner_angle, light.outer_angle);
    float high = light.inner_angle;
    float cosDir = dot(result.direction, -light.direction);
    float spotAttenuation = smoothstep(low, high, cosDir);
    result.intensity *= spotAttenuation;
}
void mx_directional_light(LightData light, float3 position, thread lightshader& result)
{
    result.direction = -light.direction;
    result.intensity = light.color * light.intensity;
}
<?xml version="1.0"?>
<materialx version="1.39">

  <!-- <point_light> -->
  <implementation name="IM_point_light_genmsl" nodedef="ND_point_light" file="mx_point_light.metal" function="mx_point_light" target="genmsl" />

  <!-- <directional_light> -->
  <implementation name="IM_directional_light_genmsl" nodedef="ND_directional_light" file="mx_directional_light.metal" function="mx_directional_light" target="genmsl" />

  <!-- <spot_light> -->
  <implementation name="IM_spot_light_genmsl" nodedef="ND_spot_light" file="mx_spot_light.metal" function="mx_spot_light" target="genmsl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <!-- <point_light> -->
  <implementation name="IM_point_light_genglsl" nodedef="ND_point_light" file="mx_point_light.glsl" function="mx_point_light" target="genglsl" />

  <!-- <directional_light> -->
  <implementation name="IM_directional_light_genglsl" nodedef="ND_directional_light" file="mx_directional_light.glsl" function="mx_directional_light" target="genglsl" />

  <!-- <spot_light> -->
  <implementation name="IM_spot_light_genglsl" nodedef="ND_spot_light" file="mx_spot_light.glsl" function="mx_spot_light" target="genglsl" />

</materialx>
void mx_spot_light(LightData light, vec3 position, out lightshader result)
{
    result.direction = light.position - position;
    float distance = length(result.direction) + M_FLOAT_EPS;
    float attenuation = pow(distance + 1.0, light.decay_rate + M_FLOAT_EPS);
    result.intensity = light.color * light.intensity / attenuation;
    result.direction /= distance;
    float low = min(light.inner_angle, light.outer_angle);
    float high = light.inner_angle;
    float cosDir = dot(result.direction, -light.direction);
    float spotAttenuation = smoothstep(low, high, cosDir);
    result.intensity *= spotAttenuation;
}
void mx_directional_light(LightData light, vec3 position, out lightshader result)
{
    result.direction = -light.direction;
    result.intensity = light.color * light.intensity;
}
void mx_point_light(LightData light, vec3 position, out lightshader result)
{
    result.direction = light.position - position;
    float distance = length(result.direction) + M_FLOAT_EPS;
    float attenuation = pow(distance + 1.0, light.decay_rate + M_FLOAT_EPS);
    result.intensity = light.color * light.intensity / attenuation;
    result.direction /= distance;
}
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations of standard data types and nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- Data types                                                               -->
  <!-- ======================================================================== -->

  <typedef name="boolean" />
  <typedef name="integer" />
  <typedef name="float" />
  <typedef name="color3" semantic="color" />
  <typedef name="color4" semantic="color" />
  <typedef name="vector2" />
  <typedef name="vector3" />
  <typedef name="vector4" />
  <typedef name="matrix33" />
  <typedef name="matrix44" />
  <typedef name="string" />
  <typedef name="filename" />
  <typedef name="geomname" />
  <typedef name="surfaceshader" semantic="shader" context="surface" />
  <typedef name="displacementshader" semantic="shader" context="displacement" />
  <typedef name="volumeshader" semantic="shader" context="volume" />
  <typedef name="lightshader" semantic="shader" context="light" />
  <typedef name="material" semantic="material" />
  <typedef name="none" />

  <typedef name="integerarray" />
  <typedef name="floatarray" />
  <typedef name="color3array" semantic="color" />
  <typedef name="color4array" semantic="color" />
  <typedef name="vector2array" />
  <typedef name="vector3array" />
  <typedef name="vector4array" />
  <typedef name="stringarray" />
  <typedef name="geomnamearray" />

  <!-- ======================================================================== -->
  <!-- Units and unit types                                                     -->
  <!-- ======================================================================== -->

  <unittypedef name="distance" />
  <unitdef name="UD_stdlib_distance" unittype="distance">
    <unit name="nanometer" scale="0.000000001" />
    <unit name="micron" scale="0.000001" />
    <unit name="millimeter" scale="0.001" />
    <unit name="centimeter" scale="0.01" />
    <unit name="inch" scale="0.0254" />
    <unit name="foot" scale="0.3048" />
    <unit name="yard" scale="0.9144" />
    <unit name="meter" scale="1.0" />
    <unit name="kilometer" scale="1000.0" />
    <unit name="mile" scale="1609.344" />
  </unitdef>

  <unittypedef name="angle" />
  <unitdef name="UD_stdlib_angle" unittype="angle">
    <unit name="degree" scale="1.0" />
    <unit name="radian" scale="57.295779513" />
  </unitdef>

  <!-- ======================================================================== -->
  <!-- Geometric Properties                                                     -->
  <!-- ======================================================================== -->

  <geompropdef name="Pobject" type="vector3" geomprop="position" space="object" />
  <geompropdef name="Nobject" type="vector3" geomprop="normal" space="object" />
  <geompropdef name="Tobject" type="vector3" geomprop="tangent" space="object" index="0" />
  <geompropdef name="Bobject" type="vector3" geomprop="bitangent" space="object" index="0" />
  <geompropdef name="Pworld" type="vector3" geomprop="position" space="world" />
  <geompropdef name="Nworld" type="vector3" geomprop="normal" space="world" />
  <geompropdef name="Tworld" type="vector3" geomprop="tangent" space="world" index="0" />
  <geompropdef name="Bworld" type="vector3" geomprop="bitangent" space="world" index="0" />
  <geompropdef name="UV0" type="vector2" geomprop="texcoord" index="0" />

  <!-- ======================================================================== -->
  <!-- Materials                                                                -->
  <!-- ======================================================================== -->

  <!-- Surface material -->
  <nodedef name="ND_surfacematerial" node="surfacematerial" nodegroup="material">
    <input name="surfaceshader" type="surfaceshader" value="" />
    <input name="backsurfaceshader" type="surfaceshader" value="" />
    <input name="displacementshader" type="displacementshader" value="" />
    <output name="out" type="material" />
  </nodedef>

  <!-- Volume material -->
  <nodedef name="ND_volumematerial" node="volumematerial" nodegroup="material">
    <input name="volumeshader" type="volumeshader" value="" />
    <output name="out" type="material" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Shader nodes                                                             -->
  <!-- ======================================================================== -->

  <!--
    Node: <surface_unlit>
    An unlit surface shader node. Represents a surface that can emit and transmit light, 
    but does not receive illumination from light sources or other surfaces.
  -->
  <nodedef name="ND_surface_unlit" node="surface_unlit" nodegroup="shader" doc="Construct a surface shader from emission and transmission values.">
    <input name="emission" type="float" value="1.0" doc="Surface emission amount." />
    <input name="emission_color" type="color3" value="1,1,1" doc="Surface emission color." />
    <input name="transmission" type="float" value="0.0" doc="Surface transmission amount." />
    <input name="transmission_color" type="color3" value="1,1,1" doc="Surface transmission color." />
    <input name="opacity" type="float" value="1.0" doc="Surface cutout opacity." />
    <output name="out" type="surfaceshader" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Texture nodes                                                            -->
  <!-- ======================================================================== -->

  <!--
    Node: <image>
    Samples data from a single image, or from a layer within a multi-layer image.
  -->
  <nodedef name="ND_image_float" node="image" nodegroup="texture2d">
    <input name="file" type="filename" value="" uiname="Filename" uniform="true" />
    <input name="layer" type="string" value="" uiname="Layer" uniform="true" />
    <input name="default" type="float" value="0.0" uiname="Default Color" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uiname="Texture Coordinates" />
    <input name="uaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode U" uniform="true" />
    <input name="vaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode V" uniform="true" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uiname="Filter Type" uniform="true" />
    <input name="framerange" type="string" value="" uiname="Frame Range" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uiname="Frame Offset" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uiname="Frame End Action" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_image_color3" node="image" nodegroup="texture2d">
    <input name="file" type="filename" value="" uiname="Filename" uniform="true" />
    <input name="layer" type="string" value="" uiname="Layer" uniform="true" />
    <input name="default" type="color3" value="0.0, 0.0, 0.0" uiname="Default Color" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uiname="Texture Coordinates" />
    <input name="uaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode U" uniform="true" />
    <input name="vaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode V" uniform="true" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uiname="Filter Type" uniform="true" />
    <input name="framerange" type="string" value="" uiname="Frame Range" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uiname="Frame Offset" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uiname="Frame End Action" uniform="true" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_image_color4" node="image" nodegroup="texture2d">
    <input name="file" type="filename" value="" uiname="Filename" uniform="true" />
    <input name="layer" type="string" value="" uiname="Layer" uniform="true" />
    <input name="default" type="color4" value="0.0, 0.0, 0.0, 0.0" uiname="Default Color" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uiname="Texture Coordinates" />
    <input name="uaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode U" uniform="true" />
    <input name="vaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode V" uniform="true" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uiname="Filter Type" uniform="true" />
    <input name="framerange" type="string" value="" uiname="Frame Range" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uiname="Frame Offset" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uiname="Frame End Action" uniform="true" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_image_vector2" node="image" nodegroup="texture2d">
    <input name="file" type="filename" value="" uiname="Filename" uniform="true" />
    <input name="layer" type="string" value="" uiname="Layer" uniform="true" />
    <input name="default" type="vector2" value="0.0, 0.0" uiname="Default Color" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uiname="Texture Coordinates" />
    <input name="uaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode U" uniform="true" />
    <input name="vaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode V" uniform="true" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uiname="Filter Type" uniform="true" />
    <input name="framerange" type="string" value="" uiname="Frame Range" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uiname="Frame Offset" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uiname="Frame End Action" uniform="true" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_image_vector3" node="image" nodegroup="texture2d">
    <input name="file" type="filename" value="" uiname="Filename" uniform="true" />
    <input name="layer" type="string" value="" uiname="Layer" uniform="true" />
    <input name="default" type="vector3" value="0.0, 0.0, 0.0" uiname="Default Color" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uiname="Texture Coordinates" />
    <input name="uaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode U" uniform="true" />
    <input name="vaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode V" uniform="true" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uiname="Filter Type" uniform="true" />
    <input name="framerange" type="string" value="" uiname="Frame Range" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uiname="Frame Offset" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uiname="Frame End Action" uniform="true" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_image_vector4" node="image" nodegroup="texture2d">
    <input name="file" type="filename" value="" uiname="Filename" uniform="true" />
    <input name="layer" type="string" value="" uiname="Layer" uniform="true" />
    <input name="default" type="vector4" value="0.0, 0.0, 0.0, 0.0" uiname="Default Color" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uiname="Texture Coordinates" />
    <input name="uaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode U" uniform="true" />
    <input name="vaddressmode" type="string" value="periodic" enum="constant,clamp,periodic,mirror" uiname="Address Mode V" uniform="true" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uiname="Filter Type" uniform="true" />
    <input name="framerange" type="string" value="" uiname="Frame Range" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uiname="Frame Offset" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uiname="Frame End Action" uniform="true" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <tiledimage> Supplemental Node
    Samples data from a single image, with provisions for tiling and offsetting the image
    across uv space.
  -->
  <nodedef name="ND_tiledimage_float" node="tiledimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="realworldimagesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="realworldtilesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_tiledimage_color3" node="tiledimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="color3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="realworldimagesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="realworldtilesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_tiledimage_color4" node="tiledimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="realworldimagesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="realworldtilesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_tiledimage_vector2" node="tiledimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="vector2" value="0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="realworldimagesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="realworldtilesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_tiledimage_vector3" node="tiledimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="realworldimagesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="realworldtilesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_tiledimage_vector4" node="tiledimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="realworldimagesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="realworldtilesize" type="vector2" value="1.0, 1.0" unittype="distance" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <latlongimage> Supplemental Node
    Samples an equiangular map with adjustable rotation offset.
  -->
  <nodedef name="ND_latlongimage" node="latlongimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" uiname="Filename" />
    <input name="default" type="color3" value="0.0, 0.0, 0.0" uiname="Default Color" />
    <input name="viewdir" type="vector3" value="0.0, 0.0, 1.0" uiname="View Direction" />
    <input name="rotation" type="float" value="0.0" unittype="angle" unit="degree" uimin="0" uimax="360" uiname="Longitude Offset" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  
  <!--
    Node: <hextiledimage> Supplemental Node
    Samples data from a single image, with provisions for hex-tiling and randomizing the image
    across uv space.
  -->
  <nodedef name="ND_hextiledimage_color3" node="hextiledimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="color3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="tiling" type="vector2" value="1.0, 1.0" />
    <input name="rotation" type="float" value="1.0" />
    <input name="rotationrange" type="vector2" value="0.0, 360.0" />
    <input name="scale" type="float" value="1.0" />
    <input name="scalerange" type="vector2" value="0.5, 2.0" />
    <input name="offset" type="float" value="1.0" />
    <input name="offsetrange" type="vector2" value="0.0, 1.0" />
    <input name="falloff" type="float" value="0.5" />
    <input name="falloffcontrast" type="float" value="0.5" />
    <input name="lumacoeffs" type="color3" value="0.2722287, 0.6740818, 0.0536895" enum="acescg, rec709, rec2020, rec2100" enumvalues="0.2722287,0.6740818,0.0536895, 0.2126,0.7152,0.0722, 0.2627,0.6780,0.0593, 0.2627,0.6780,0.0593" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_hextiledimage_color4" node="hextiledimage" nodegroup="texture2d">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="tiling" type="vector2" value="1.0, 1.0" />
    <input name="rotation" type="float" value="1.0" />
    <input name="rotationrange" type="vector2" value="0.0, 360.0" />
    <input name="scale" type="float" value="1.0" />
    <input name="scalerange" type="vector2" value="0.5, 2.0" />
    <input name="offset" type="float" value="1.0" />
    <input name="offsetrange" type="vector2" value="0.0, 1.0" />
    <input name="falloff" type="float" value="0.5" />
    <input name="falloffcontrast" type="float" value="0.5" />
    <input name="lumacoeffs" type="color3" value="0.2722287, 0.6740818, 0.0536895" enum="acescg, rec709, rec2020, rec2100" enumvalues="0.2722287,0.6740818,0.0536895, 0.2126,0.7152,0.0722, 0.2627,0.6780,0.0593, 0.2627,0.6780,0.0593" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <triplanarprojection> Supplemental Node
    Samples data from three images, or layers within multi-layer images, and projects a tiled
    representation of the images along each of the three respective coordinate axes, computing
    an adjustable weighted blend of the three samples using the geometric normal.
  -->
  <nodedef name="ND_triplanarprojection_float" node="triplanarprojection" nodegroup="texture3d">
    <input name="filex" type="filename" value="" uniform="true" />
    <input name="filey" type="filename" value="" uniform="true" />
    <input name="filez" type="filename" value="" uniform="true" />
    <input name="layerx" type="string" value="" uniform="true" />
    <input name="layery" type="string" value="" uniform="true" />
    <input name="layerz" type="string" value="" uniform="true" />
    <input name="default" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="normal" type="vector3" defaultgeomprop="Nobject" />
    <input name="upaxis" type="integer" value="2" enum="X,Y,Z" enumvalues="0,1,2" uniform="true" />
    <input name="blend" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_triplanarprojection_color3" node="triplanarprojection" nodegroup="texture3d">
    <input name="filex" type="filename" value="" uniform="true" />
    <input name="filey" type="filename" value="" uniform="true" />
    <input name="filez" type="filename" value="" uniform="true" />
    <input name="layerx" type="string" value="" uniform="true" />
    <input name="layery" type="string" value="" uniform="true" />
    <input name="layerz" type="string" value="" uniform="true" />
    <input name="default" type="color3" value="0.0, 0.0, 0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="normal" type="vector3" defaultgeomprop="Nobject" />
    <input name="upaxis" type="integer" value="2" enum="X,Y,Z" enumvalues="0,1,2" uniform="true" />
    <input name="blend" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_triplanarprojection_color4" node="triplanarprojection" nodegroup="texture3d">
    <input name="filex" type="filename" value="" uniform="true" />
    <input name="filey" type="filename" value="" uniform="true" />
    <input name="filez" type="filename" value="" uniform="true" />
    <input name="layerx" type="string" value="" uniform="true" />
    <input name="layery" type="string" value="" uniform="true" />
    <input name="layerz" type="string" value="" uniform="true" />
    <input name="default" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="normal" type="vector3" defaultgeomprop="Nobject" />
    <input name="upaxis" type="integer" value="2" enum="X,Y,Z" enumvalues="0,1,2" uniform="true" />
    <input name="blend" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_triplanarprojection_vector2" node="triplanarprojection" nodegroup="texture3d">
    <input name="filex" type="filename" value="" uniform="true" />
    <input name="filey" type="filename" value="" uniform="true" />
    <input name="filez" type="filename" value="" uniform="true" />
    <input name="layerx" type="string" value="" uniform="true" />
    <input name="layery" type="string" value="" uniform="true" />
    <input name="layerz" type="string" value="" uniform="true" />
    <input name="default" type="vector2" value="0.0, 0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="normal" type="vector3" defaultgeomprop="Nobject" />
    <input name="upaxis" type="integer" value="2" enum="X,Y,Z" enumvalues="0,1,2" uniform="true" />
    <input name="blend" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_triplanarprojection_vector3" node="triplanarprojection" nodegroup="texture3d">
    <input name="filex" type="filename" value="" uniform="true" />
    <input name="filey" type="filename" value="" uniform="true" />
    <input name="filez" type="filename" value="" uniform="true" />
    <input name="layerx" type="string" value="" uniform="true" />
    <input name="layery" type="string" value="" uniform="true" />
    <input name="layerz" type="string" value="" uniform="true" />
    <input name="default" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="normal" type="vector3" defaultgeomprop="Nobject" />
    <input name="upaxis" type="integer" value="2" enum="X,Y,Z" enumvalues="0,1,2" uniform="true" />
    <input name="blend" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_triplanarprojection_vector4" node="triplanarprojection" nodegroup="texture3d">
    <input name="filex" type="filename" value="" uniform="true" />
    <input name="filey" type="filename" value="" uniform="true" />
    <input name="filez" type="filename" value="" uniform="true" />
    <input name="layerx" type="string" value="" uniform="true" />
    <input name="layery" type="string" value="" uniform="true" />
    <input name="layerz" type="string" value="" uniform="true" />
    <input name="default" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="normal" type="vector3" defaultgeomprop="Nobject" />
    <input name="upaxis" type="integer" value="2" enum="X,Y,Z" enumvalues="0,1,2" uniform="true" />
    <input name="blend" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="filtertype" type="string" value="linear" enum="closest,linear,cubic" uniform="true" />
    <input name="framerange" type="string" value="" uniform="true" />
    <input name="frameoffset" type="integer" value="0" uniform="true" />
    <input name="frameendaction" type="string" value="constant" enum="constant,clamp,periodic,mirror" uniform="true" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Procedural nodes                                                         -->
  <!-- ======================================================================== -->

  <!--
    Node: <constant>
    A constant value. When exposed as a public parameter, this is a way to create a
    value that can be accessed in multiple places in the opgraph.
  -->
  <nodedef name="ND_constant_float" node="constant" nodegroup="procedural">
    <input name="value" type="float" value="0.0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_constant_color3" node="constant" nodegroup="procedural">
    <input name="value" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_constant_color4" node="constant" nodegroup="procedural">
    <input name="value" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_constant_vector2" node="constant" nodegroup="procedural">
    <input name="value" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_constant_vector3" node="constant" nodegroup="procedural">
    <input name="value" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_constant_vector4" node="constant" nodegroup="procedural">
    <input name="value" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_constant_boolean" node="constant" nodegroup="procedural">
    <input name="value" type="boolean" value="false" />
    <output name="out" type="boolean" default="false" />
  </nodedef>
  <nodedef name="ND_constant_integer" node="constant" nodegroup="procedural">
    <input name="value" type="integer" value="0" />
    <output name="out" type="integer" default="0" />
  </nodedef>
  <nodedef name="ND_constant_matrix33" node="constant" nodegroup="procedural">
    <input name="value" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <output name="out" type="matrix33" default="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
  </nodedef>
  <nodedef name="ND_constant_matrix44" node="constant" nodegroup="procedural">
    <input name="value" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <output name="out" type="matrix44" default="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
  </nodedef>
  <nodedef name="ND_constant_string" node="constant" nodegroup="procedural">
    <input name="value" type="string" value="" uniform="true" />
    <output name="out" type="string" default="" />
  </nodedef>
  <nodedef name="ND_constant_filename" node="constant" nodegroup="procedural">
    <input name="value" type="filename" value="" uniform="true" />
    <output name="out" type="filename" default="" />
  </nodedef>

  <!--
    Node: <ramp>
    A ramp that supports up to 10 control points.
  -->
  <nodedef name="ND_ramp" node="ramp" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="type" type="integer" value="0" enum="standard,radial,circular,box" enumvalues="0,1,2,3" />
    <input name="interpolation" type="integer" value="1" enum="linear,smooth,step" enumvalues="0,1,2" />
    <input name="num_intervals" type="integer" value="2" uimin="2" uimax="10" />
    <input name="interval1" type="float" value="0" uimin="0" uimax="1" />
    <input name="color1" type="color4" value="0,0,0,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval2" type="float" value="1" uimin="0" uimax="1" />
    <input name="color2" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval3" type="float" value="1" uimin="0" uimax="1" />
    <input name="color3" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval4" type="float" value="1" uimin="0" uimax="1" />
    <input name="color4" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval5" type="float" value="1" uimin="0" uimax="1" />
    <input name="color5" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval6" type="float" value="1" uimin="0" uimax="1" />
    <input name="color6" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval7" type="float" value="1" uimin="0" uimax="1" />
    <input name="color7" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval8" type="float" value="1" uimin="0" uimax="1" />
    <input name="color8" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval9" type="float" value="1" uimin="0" uimax="1" />
    <input name="color9" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval10" type="float" value="1" uimin="0" uimax="1" />
    <input name="color10" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <output name="out" type="color4" />
  </nodedef>

  <!--
    Node <ramp_gradient>
    A helper node that handles a single control point within a <ramp>.
  -->
  <nodedef name="ND_ramp_gradient" node="ramp_gradient" nodegroup="procedural2d">
    <input name="x" type="float" value="0" uimin="0" uimax="1" />
    <input name="interval1" type="float" value="0" uimin="0" uimax="1" />
    <input name="interval2" type="float" value="1" uimin="0" uimax="1" />
    <input name="color1" type="color4" value="0,0,0,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="color2" type="color4" value="1,1,1,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interpolation" type="integer" value="1" enum="linear,smooth,step" enumvalues="0,1,2" />
    <input name="prev_color" type="color4" value="0,0,0,1" uimin="0,0,0,0" uimax="1,1,1,1" />
    <input name="interval_num" type="integer" value="1" />
    <input name="num_intervals" type="integer" value="2" />
    <output name="out" type="color4" />
  </nodedef>

  <!--
    Node: <ramplr>
    A left-to-right bilinear value ramp.
  -->
  <nodedef name="ND_ramplr_float" node="ramplr" nodegroup="procedural2d">
    <input name="valuel" type="float" value="0.0" />
    <input name="valuer" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_ramplr_color3" node="ramplr" nodegroup="procedural2d">
    <input name="valuel" type="color3" value="0.0, 0.0, 0.0" />
    <input name="valuer" type="color3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramplr_color4" node="ramplr" nodegroup="procedural2d">
    <input name="valuel" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valuer" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramplr_vector2" node="ramplr" nodegroup="procedural2d">
    <input name="valuel" type="vector2" value="0.0, 0.0" />
    <input name="valuer" type="vector2" value="0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramplr_vector3" node="ramplr" nodegroup="procedural2d">
    <input name="valuel" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="valuer" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramplr_vector4" node="ramplr" nodegroup="procedural2d">
    <input name="valuel" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valuer" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <ramptb>
    A top-to-bottom bilinear value ramp.
  -->
  <nodedef name="ND_ramptb_float" node="ramptb" nodegroup="procedural2d">
    <input name="valuet" type="float" value="0.0" />
    <input name="valueb" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_ramptb_color3" node="ramptb" nodegroup="procedural2d">
    <input name="valuet" type="color3" value="0.0, 0.0, 0.0" />
    <input name="valueb" type="color3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramptb_color4" node="ramptb" nodegroup="procedural2d">
    <input name="valuet" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valueb" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramptb_vector2" node="ramptb" nodegroup="procedural2d">
    <input name="valuet" type="vector2" value="0.0, 0.0" />
    <input name="valueb" type="vector2" value="0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramptb_vector3" node="ramptb" nodegroup="procedural2d">
    <input name="valuet" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="valueb" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramptb_vector4" node="ramptb" nodegroup="procedural2d">
    <input name="valuet" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valueb" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <ramp4> Supplemental Node
    A 4-corner bilinear value ramp.
  -->
  <nodedef name="ND_ramp4_float" node="ramp4" nodegroup="procedural2d">
    <input name="valuetl" type="float" value="0.0" />
    <input name="valuetr" type="float" value="0.0" />
    <input name="valuebl" type="float" value="0.0" />
    <input name="valuebr" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_ramp4_color3" node="ramp4" nodegroup="procedural2d">
    <input name="valuetl" type="color3" value="0.0, 0.0, 0.0" />
    <input name="valuetr" type="color3" value="0.0, 0.0, 0.0" />
    <input name="valuebl" type="color3" value="0.0, 0.0, 0.0" />
    <input name="valuebr" type="color3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramp4_color4" node="ramp4" nodegroup="procedural2d">
    <input name="valuetl" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valuetr" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valuebl" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valuebr" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramp4_vector2" node="ramp4" nodegroup="procedural2d">
    <input name="valuetl" type="vector2" value="0.0, 0.0" />
    <input name="valuetr" type="vector2" value="0.0, 0.0" />
    <input name="valuebl" type="vector2" value="0.0, 0.0" />
    <input name="valuebr" type="vector2" value="0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramp4_vector3" node="ramp4" nodegroup="procedural2d">
    <input name="valuetl" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="valuetr" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="valuebl" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="valuebr" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_ramp4_vector4" node="ramp4" nodegroup="procedural2d">
    <input name="valuetl" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valuetr" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valuebl" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="valuebr" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <splitlr>
    A left-right split matte, split at a specified u value.
  -->
  <nodedef name="ND_splitlr_float" node="splitlr" nodegroup="procedural2d">
    <input name="valuel" type="float" value="0.0" uiname="Left" />
    <input name="valuer" type="float" value="0.0" uiname="Right" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_splitlr_color3" node="splitlr" nodegroup="procedural2d">
    <input name="valuel" type="color3" value="0.0, 0.0, 0.0" uiname="Left" />
    <input name="valuer" type="color3" value="0.0, 0.0, 0.0" uiname="Right" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_splitlr_color4" node="splitlr" nodegroup="procedural2d">
    <input name="valuel" type="color4" value="0.0, 0.0, 0.0, 0.0" uiname="Left" />
    <input name="valuer" type="color4" value="0.0, 0.0, 0.0, 0.0" uiname="Right" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_splitlr_vector2" node="splitlr" nodegroup="procedural2d">
    <input name="valuel" type="vector2" value="0.0, 0.0" uiname="Left" />
    <input name="valuer" type="vector2" value="0.0, 0.0" uiname="Right" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_splitlr_vector3" node="splitlr" nodegroup="procedural2d">
    <input name="valuel" type="vector3" value="0.0, 0.0, 0.0" uiname="Left" />
    <input name="valuer" type="vector3" value="0.0, 0.0, 0.0" uiname="Right" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_splitlr_vector4" node="splitlr" nodegroup="procedural2d">
    <input name="valuel" type="vector4" value="0.0, 0.0, 0.0, 0.0" uiname="Left" />
    <input name="valuer" type="vector4" value="0.0, 0.0, 0.0, 0.0" uiname="Right" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <!--
    Node: <splittb>
    A top-bottom split matte, split at a specified v value.
  -->
  <nodedef name="ND_splittb_float" node="splittb" nodegroup="procedural2d">
    <input name="valuet" type="float" value="0.0" uiname="Top" />
    <input name="valueb" type="float" value="0.0" uiname="Bottom" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_splittb_color3" node="splittb" nodegroup="procedural2d">
    <input name="valuet" type="color3" value="0.0, 0.0, 0.0" uiname="Top" />
    <input name="valueb" type="color3" value="0.0, 0.0, 0.0" uiname="Bottom" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_splittb_color4" node="splittb" nodegroup="procedural2d">
    <input name="valuet" type="color4" value="0.0, 0.0, 0.0, 0.0" uiname="Top" />
    <input name="valueb" type="color4" value="0.0, 0.0, 0.0, 0.0" uiname="Bottom" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_splittb_vector2" node="splittb" nodegroup="procedural2d">
    <input name="valuet" type="vector2" value="0.0, 0.0" uiname="Top" />
    <input name="valueb" type="vector2" value="0.0, 0.0" uiname="Bottom" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_splittb_vector3" node="splittb" nodegroup="procedural2d">
    <input name="valuet" type="vector3" value="0.0, 0.0, 0.0" uiname="Top" />
    <input name="valueb" type="vector3" value="0.0, 0.0, 0.0" uiname="Bottom" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_splittb_vector4" node="splittb" nodegroup="procedural2d">
    <input name="valuet" type="vector4" value="0.0, 0.0, 0.0, 0.0" uiname="Top" />
    <input name="valueb" type="vector4" value="0.0, 0.0, 0.0, 0.0" uiname="Bottom" />
    <input name="center" type="float" value="0.5" uiname="Center" uimin="0.0" uimax="1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <noise2d>
    2D Perlin noise in 1, 2, 3 or 4 channels.
  -->
  <nodedef name="ND_noise2d_float" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_color3" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_color4" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_vector2" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector2" value="1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_vector3" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_vector4" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_color3FA" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_color4FA" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_vector2FA" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_vector3FA" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise2d_vector4FA" node="noise2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <noise3d>
    3D Perlin noise in 1, 2, 3 or 4 channels.
  -->
  <nodedef name="ND_noise3d_float" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_color3" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_color4" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_vector2" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector2" value="1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_vector3" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_vector4" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_color3FA" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_color4FA" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_vector2FA" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_vector3FA" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_noise3d_vector4FA" node="noise3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.0" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <fractal2d>
    2D Fractal noise in 1, 2, 3 or 4 channels.
  -->
  <nodedef name="ND_fractal2d_float" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_color3" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_color4" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_vector2" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector2" value="1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_vector3" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_vector4" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_color3FA" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_color4FA" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_vector2FA" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_vector3FA" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal2d_vector4FA" node="fractal2d" nodegroup="procedural2d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <fractal3d>
    3D Fractal noise in 1, 2, 3 or 4 channels.
  -->
  <nodedef name="ND_fractal3d_float" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_color3" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_color4" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_vector2" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector2" value="1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_vector3" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_vector4" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_color3FA" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_color4FA" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_vector2FA" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_vector3FA" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_fractal3d_vector4FA" node="fractal3d" nodegroup="procedural3d">
    <input name="amplitude" type="float" value="1.0" />
    <input name="octaves" type="integer" value="3" />
    <input name="lacunarity" type="float" value="2.0" />
    <input name="diminish" type="float" value="0.5" />
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <cellnoise2d>
    2D cellular noise in 1 channel.
  -->
  <nodedef name="ND_cellnoise2d_float" node="cellnoise2d" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>

  <!--
    Node: <cellnoise3d>
    3D cellular noise in 1 channel.
  -->
  <nodedef name="ND_cellnoise3d_float" node="cellnoise3d" nodegroup="procedural3d">
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <output name="out" type="float" default="0.0" />
  </nodedef>

  <!--
    Node: <worleynoise2d>
    2D Worley (voronoi) noise in 1, 2 or 3 channels.
  -->
  <nodedef name="ND_worleynoise2d_float" node="worleynoise2d" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="jitter" type="float" value="1.0" />
    <input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_worleynoise2d_vector2" node="worleynoise2d" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="jitter" type="float" value="1.0" />
    <input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_worleynoise2d_vector3" node="worleynoise2d" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="jitter" type="float" value="1.0" />
    <input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <worleynoise3d>
    3D Worley (voronoi) noise in 1, 2 or 3 channels.
  -->
  <nodedef name="ND_worleynoise3d_float" node="worleynoise3d" nodegroup="procedural3d">
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="jitter" type="float" value="1.0" />
    <input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_worleynoise3d_vector2" node="worleynoise3d" nodegroup="procedural3d">
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="jitter" type="float" value="1.0" />
    <input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_worleynoise3d_vector3" node="worleynoise3d" nodegroup="procedural3d">
    <input name="position" type="vector3" defaultgeomprop="Pobject" />
    <input name="jitter" type="float" value="1.0" />
    <input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <unifiednoise2d>
    Combines the available noises into an artist-friendly node, adding controls
    to adjust frequency, offset, jitter, etc... Where possible controls have
    been unified between noises; any noise-specific controls should live in a
    dedicated folder. These folders should be hidden by artist tools, unless their
    corresponding noise type is selected.
    
    The noise types are:
    
       0 - Perlin (noise2d/noise3d)
       1 - Cell (cellnoise2d/cellnoise3d)
       2 - Worley (worley2d/worley3d)
       3 - Fractal (fractal3d)
    
    The output is 1 channel, with controls to adjust the output range.
  -->
  <nodedef name="ND_unifiednoise2d_float" node="unifiednoise2d" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" uifolder="Common" defaultgeomprop="UV0" doc="The input 2d space. Default is the first texture coordinates." />
    <input name="freq" type="vector2" uiname="Frequency" uifolder="Common" value="1, 1" doc="Adjusts the noise frequency, with higher values producing smaller noise shapes. Default is (1,1)." />
    <input name="offset" type="vector2" uiname="Offset" uifolder="Common" value="0, 0" doc="Shift the noise in 2d space. Default is (0,0)." />
    <input name="jitter" type="float" uiname="Jitter" uifolder="Common" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Adjust uniformity of Worley noise; for other noise types jitters the results." />
    <input name="outmin" type="float" uiname="Output Min" uifolder="Post Process" value="0" doc="The lowest values fit to the noise. Default is 0.0." />
    <input name="outmax" type="float" uiname="Output Max" uifolder="Post Process" value="1" doc="The highest values fit to the noise. Default is 1.0." />
    <input name="clampoutput" type="boolean" uiname="Clamp Output" uifolder="Post Process" value="true" doc="Clamp the output to the min and max output values." />
    <input name="octaves" type="integer" uiname="Octaves" uifolder="Fractal" value="3" doc="The number of octaves of Fractal noise to be generated. Default is 3." />
    <input name="lacunarity" type="float" uiname="Lacunarity" uifolder="Fractal" value="2" doc="The exponential scale between successive octaves of Fractal noise. Default is 2.0." />
    <input name="diminish" type="float" uiname="Diminish" uifolder="Fractal" uisoftmin="0.0" uisoftmax="1.0" value="0.5" doc="The rate at which noise amplitude is diminished for each octave of Fractal noise. Default is 0.5." />
    <input name="type" type="integer" uiname="Noise Type" uifolder="Common" uisoftmin="0" uisoftmax="3" value="0" enum="Perlin,Cell,Worley,Fractal" enumvalues="0,1,2,3" doc="Menu to select the type of noise: Perlin, Cell, Worley, or Fractal. Default is Perlin." />
    <input name="style" uiname="Worley Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" doc="Sets the style of cell used when Noise Type is set to Worley." />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <unifiednoise3d>
    The 3d flavor of <unifiednoise2d>.
  -->
  <nodedef name="ND_unifiednoise3d_float" node="unifiednoise3d" nodegroup="procedural3d">
    <input name="position" type="vector3" uifolder="Common" defaultgeomprop="Pobject" doc="The input 3d space. Default is position in object-space." />
    <input name="freq" type="vector3" uiname="Frequency" uifolder="Common" value="1, 1, 1" doc="Adjusts the noise frequency, with higher values producing smaller noise shapes. Default is (1,1,1)." />
    <input name="offset" type="vector3" uiname="Offset" uifolder="Common" value="0, 0, 0" doc="Shift the noise in 3d space. Default is (0,0,0)." />
    <input name="jitter" type="float" uiname="Jitter" uifolder="Common" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Adjust uniformity of Worley noise; for other noise types jitters the results." />
    <input name="outmin" type="float" uiname="Output Min" uifolder="Post Process" value="0" doc="The lowest values fit to the noise. Default is 0.0." />
    <input name="outmax" type="float" uiname="Output Max" uifolder="Post Process" value="1" doc="The highest values fit to the noise. Default is 1.0." />
    <input name="clampoutput" type="boolean" uiname="Clamp Output" uifolder="Post Process" value="true" doc="Clamp the output to the min and max output values." />
    <input name="octaves" type="integer" uiname="Octaves" uifolder="Fractal" value="3" doc="The number of octaves of Fractal noise to be generated. Default is 3." />
    <input name="lacunarity" type="float" uiname="Lacunarity" uifolder="Fractal" value="2" doc="The exponential scale between successive octaves of Fractal noise. Default is 2.0." />
    <input name="diminish" type="float" uiname="Diminish" uifolder="Fractal" uisoftmin="0.0" uisoftmax="1.0" value="0.5" doc="The rate at which noise amplitude is diminished for each octave of Fractal noise. Default is 0.5." />
    <input name="type" type="integer" uiname="Noise Type" uifolder="Common" uisoftmin="0" uisoftmax="3" value="0" enum="Perlin,Cell,Worley,Fractal" enumvalues="0,1,2,3" doc="Menu to select the type of noise: Perlin, Cell, Worley, or Fractal. Default is Perlin." />
    <input name="style" uiname="Worley Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" doc="Sets the style of cell used when Noise Type is set to Worley." />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <randomfloat>
    Produces a randomized float, based on an 'input' signal and 'seed' value.
  -->
  <nodedef name="ND_randomfloat_float" node="randomfloat" nodegroup="procedural">
    <input name="in" type="float" uiname="Input" value="0.0" doc="Initial randomization seed." />
    <input name="min" type="float" uiname="Minimum" value="0.0" doc="The minimum output value." />
    <input name="max" type="float" uiname="Maximum" value="1.0" doc="The maximum output value." />
    <input name="seed" type="integer" uiname="Seed" value="0" doc="Additional seed." />
    <output name="out" type="float" />
  </nodedef>
  <nodedef name="ND_randomfloat_integer" node="randomfloat" nodegroup="procedural">
    <input name="in" type="integer" uiname="Input" value="0" />
    <input name="min" type="float" uiname="Minimum" value="0.0" />
    <input name="max" type="float" uiname="Maximum" value="1.0" />
    <input name="seed" type="integer" uiname="Seed" value="0" />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <randomcolor>
    Produces a randomized RGB color, based on an 'input' signal and 'seed' value.
  -->
  <nodedef name="ND_randomcolor_float" node="randomcolor" nodegroup="procedural3d">
    <input name="in" type="float" uiname="Input" uisoftmin="0.0" uisoftmax="10.0" value="0.0" />
    <input name="huelow" type="float" uiname="Hue Low" uisoftmin="0.0" uisoftmax="1.0" value="0" />
    <input name="huehigh" type="float" uiname="Hue High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="saturationlow" type="float" uiname="Saturation Low" uisoftmin="0.0" uisoftmax="1.0" value="0.825" />
    <input name="saturationhigh" type="float" uiname="Saturation High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="brightnesslow" type="float" uiname="Brightness Low" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="brightnesshigh" type="float" uiname="Brightness High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="seed" type="integer" uiname="Seed" value="0" />
    <output name="out" type="color3" />
  </nodedef>
  <nodedef name="ND_randomcolor_integer" node="randomcolor" nodegroup="procedural3d">
    <input name="in" type="integer" uiname="Input" uisoftmin="0" uisoftmax="10" value="0" />
    <input name="huelow" type="float" uiname="Hue Low" uisoftmin="0.0" uisoftmax="1.0" value="0" />
    <input name="huehigh" type="float" uiname="Hue High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="saturationlow" type="float" uiname="Saturation Low" uisoftmin="0.0" uisoftmax="1.0" value="0.825" />
    <input name="saturationhigh" type="float" uiname="Saturation High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="brightnesslow" type="float" uiname="Brightness Low" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="brightnesshigh" type="float" uiname="Brightness High" uisoftmin="0.0" uisoftmax="1.0" value="1" />
    <input name="seed" type="integer" uiname="Seed" value="0" />
    <output name="out" type="color3" />
  </nodedef>

  <!--
    Node: <checkerboard>
    A 2D checkerboard pattern.
  -->
  <nodedef name="ND_checkerboard_color3" node="checkerboard" nodegroup="procedural2d">
    <input name="color1" type="color3" uiname="Color 1" value="1.0, 1.0, 1.0" doc="The first color used in the checkerboard pattern." />
    <input name="color2" type="color3" uiname="Color 2" value="0.0, 0.0, 0.0" doc="The second color used in the checkerboard pattern." />
    <input name="uvtiling" type="vector2" uiname="UV Tiling" value="8, 8" doc="The tiling of the checkerboard pattern along each axis, with higher values producing smaller squares. Default is (8, 8)." />
    <input name="uvoffset" type="vector2" uiname="UV Offset" value="0, 0" doc="The offset of the checkerboard pattern along each axis. Default is (0, 0)." />
    <input name="texcoord" type="vector2" uiname="Texture Coordinates" defaultgeomprop="UV0" doc="The input 2d space. Default is the first texture coordinates." />
    <output name="out" type="color3" />
  </nodedef>

  <!--
    Node: <line>
    Returns 1 if texcoord is at less than radius distance from a line segment defined by point1 and point2; otherwise returns 0.
    Segment ends will be rounded.
    Uses formulas from Inigo Quilez SDF samples (iquilezles.org)
  -->
  <nodedef name="ND_line_float" node="line" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="center" type="vector2" value="0, 0" />
    <input name="radius" type="float" value="0.1" />
    <input name="point1" type="vector2" value="0.25, 0.25" />
    <input name="point2" type="vector2" value="0.75, 0.75" />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <circle>
    Returns 1 if texcoord is inside a circle defined by center and radius; otherwise returns 0.
  -->
  <nodedef name="ND_circle_float" node="circle" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="center" type="vector2" value="0, 0" />
    <input name="radius" type="float" value="0.5" />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <cloverleaf>
    Returns 1 if texcoord is inside a cloverleaf shape inscribed by a circle defined by center and radius; otherwise returns 0.
  -->
  <nodedef name="ND_cloverleaf_float" node="cloverleaf" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="center" type="vector2" value="0, 0" />
    <input name="radius" type="float" value="0.5" />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <hexagon>
    Returns 1 if texcoord is inside a hexagon shape inscribed by a circle defined by center and radius; otherwise returns 0.
    Uses formulas from Inigo Quilez SDF samples (iquilezles.org)
  -->
  <nodedef name="ND_hexagon_float" node="hexagon" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="center" type="vector2" value="0, 0" />
    <input name="radius" type="float" value="0.5" />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <grid>
    Creates a grid pattern with the given tiling, offset, and line thickness.
    Pattern can be regular or staggered.
  -->
  <nodedef name="ND_grid_color3" node="grid" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="thickness" type="float" value="0.05" />
    <input name="staggered" type="boolean" value="false" />
    <output name="out" type="color3" />
  </nodedef>

  <!--
    Node: <crosshatch>
    Creates a crosshatch pattern with the given tiling, offset, and line thickness.
    Pattern can be regular or staggered.
  -->
  <nodedef name="ND_crosshatch_color3" node="crosshatch" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="thickness" type="float" value="0.05" />
    <input name="staggered" type="boolean" value="false" />
    <output name="out" type="color3" />
  </nodedef>

  <!--
    Node: <tiledcircles>
    Creates a black and white pattern of circles with a defined tiling and size (diameter).
    Pattern can be regular or staggered.
  -->
  <nodedef name="ND_tiledcircles_color3" node="tiledcircles" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="size" type="float" value="0.5" />
    <input name="staggered" type="boolean" value="false" />
    <output name="out" type="color3" />
  </nodedef>

  <!--
    Node: <tiledcloverleafs>
    Creates a black and white pattern of cloverleafs with a defined tiling and size (diameter of the circles circumscribing the shape).
    Pattern can be regular or staggered.
  -->
  <nodedef name="ND_tiledcloverleafs_color3" node="tiledcloverleafs" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="size" type="float" value="0.5" />
    <input name="staggered" type="boolean" value="false" />
    <output name="out" type="color3" />
  </nodedef>

  <!--
    Node: <tiledhexagons>
    Creates a black and white pattern of hexagons with a defined tiling and size (diameter of the circles circumscribing the shape).
    Pattern can be regular or staggered.
  -->
  <nodedef name="ND_tiledhexagons_color3" node="tiledhexagons" nodegroup="procedural2d">
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="uvtiling" type="vector2" value="1.0, 1.0" />
    <input name="uvoffset" type="vector2" value="0.0, 0.0" />
    <input name="size" type="float" value="0.5" />
    <input name="staggered" type="boolean" value="false" />
    <output name="out" type="color3" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Geometric nodes                                                          -->
  <!-- ======================================================================== -->

  <!--
    Node: <position>
    The geometric position associated with the currently processed data,
    as defined in a specific coordinate space.
  -->
  <nodedef name="ND_position_vector3" node="position" nodegroup="geometric">
    <input name="space" type="string" value="object" enum="model,object,world" uniform="true" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <normal>
    The geometric normal associated with the currently processed data,
    as defined in a specific coordinate space.
  -->
  <nodedef name="ND_normal_vector3" node="normal" nodegroup="geometric">
    <input name="space" type="string" value="object" enum="model,object,world" uniform="true" />
    <output name="out" type="vector3" default="0.0, 1.0, 0.0" />
  </nodedef>

  <!--
    Node: <tangent>
    The geometric tangent vector associated with the currently processed data,
    as defined in a specific coordinate space.
  -->
  <nodedef name="ND_tangent_vector3" node="tangent" nodegroup="geometric">
    <input name="space" type="string" value="object" enum="model,object,world" uniform="true" />
    <input name="index" type="integer" value="0" uniform="true" />
    <output name="out" type="vector3" default="1.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <bitangent>
    The geometric bitangent vector associated with the currently processed data,
    as defined in a specific coordinate space.
  -->
  <nodedef name="ND_bitangent_vector3" node="bitangent" nodegroup="geometric">
    <input name="space" type="string" value="object" enum="model,object,world" uniform="true" />
    <input name="index" type="integer" value="0" uniform="true" />
    <output name="out" type="vector3" default="0.0, 0.0, 1.0" />
  </nodedef>

  <!--
    Node: <texcoord>
    The full 2D or 3D texture coordinates associated with the currently processed data.
  -->
  <nodedef name="ND_texcoord_vector2" node="texcoord" nodegroup="geometric">
    <input name="index" type="integer" value="0" uniform="true" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_texcoord_vector3" node="texcoord" nodegroup="geometric">
    <input name="index" type="integer" value="0" uniform="true" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <geomcolor>
    The color associated with the current geometry at the current position, generally
    bound via per-vertex color values.
  -->
  <nodedef name="ND_geomcolor_float" node="geomcolor" nodegroup="geometric">
    <input name="index" type="integer" value="0" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_geomcolor_color3" node="geomcolor" nodegroup="geometric">
    <input name="index" type="integer" value="0" uniform="true" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_geomcolor_color4" node="geomcolor" nodegroup="geometric">
    <input name="index" type="integer" value="0" uniform="true" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <geompropvalue>
    The value of the specified geometric property for the current geometry.
  -->
  <nodedef name="ND_geompropvalue_integer" node="geompropvalue" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="integer" value="0" />
    <output name="out" type="integer" default="0" />
  </nodedef>
  <nodedef name="ND_geompropvalue_boolean" node="geompropvalue" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="boolean" value="false" />
    <output name="out" type="boolean" default="false" />
  </nodedef>
  <nodedef name="ND_geompropvalue_float" node="geompropvalue" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="float" value="0.0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_geompropvalue_color3" node="geompropvalue" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_geompropvalue_color4" node="geompropvalue" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_geompropvalue_vector2" node="geompropvalue" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_geompropvalue_vector3" node="geompropvalue" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_geompropvalue_vector4" node="geompropvalue" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <geompropvalueuniform>
    The uniform, non-varying value of the specified geometric property for the current geometry.
  -->
  <nodedef name="ND_geompropvalueuniform_string" node="geompropvalueuniform" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="string" value="" uniform="true" />
    <output name="out" type="string" default="" uniform="true" />
  </nodedef>
  <nodedef name="ND_geompropvalueuniform_filename" node="geompropvalueuniform" nodegroup="geometric">
    <input name="geomprop" type="string" value="" uniform="true" />
    <input name="default" type="filename" value="" uniform="true" />
    <output name="out" type="filename" default="" uniform="true" />
  </nodedef>


  <!--
    Node: <bump>
    Offset the surface normal by a scalar value.
  -->
  <nodedef name="ND_bump_vector3" node="bump" nodegroup="geometric">
    <input name="height" type="float" uiname="Height" uisoftmin="0.0" uisoftmax="1.0" value="0" doc="Amount to offset the surface normal." />
    <input name="scale" type="float" uiname="Scale" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Scalar to adjust the height amount." />
    <input name="normal" type="vector3" uiname="Normal" defaultgeomprop="Nworld" doc="Surface normal; defaults to the current world-space normal." />
    <input name="tangent" type="vector3" uiname="Tangent" defaultgeomprop="Tworld" doc="Surface tangent vector, defaults to the current world-space tangent vector." />
    <input name="bitangent" type="vector3" uiname="Bitangent" defaultgeomprop="Bworld" doc="Surface bitangent vector, defaults to the current world-space bitangent vector." />
    <output name="out" type="vector3" doc="Offset surface normal; connect this to a shader's 'normal' input." />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Application nodes                                                        -->
  <!-- ======================================================================== -->

  <!--
    Node: <frame>
    The current frame number as defined by the host environment.
  -->
  <nodedef name="ND_frame_float" node="frame" nodegroup="application">
    <output name="out" type="float" default="1.0" />
  </nodedef>

  <!--
    Node: <time>
    The current time in seconds as defined by the host environment.
  -->
  <nodedef name="ND_time_float" node="time" nodegroup="application">
    <input name="fps" type="float" value="24.0" /> <!-- An unused input, to be removed in a future specification version -->
    <output name="out" type="float" default="0.0" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Math nodes                                                               -->
  <!-- ======================================================================== -->

  <!--
    Node: <add>
    Add "in2" value/stream to the incoming float/integer/color/vector/matrix.
  -->
  <nodedef name="ND_add_float" node="add" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_integer" node="add" nodegroup="math">
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_color3" node="add" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_color4" node="add" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_vector2" node="add" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_vector3" node="add" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_vector4" node="add" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_matrix33" node="add" nodegroup="math">
    <input name="in1" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <input name="in2" type="matrix33" value="0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_matrix44" node="add" nodegroup="math">
    <input name="in1" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <input name="in2" type="matrix44" value="0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_color3FA" node="add" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_color4FA" node="add" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_vector2FA" node="add" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_vector3FA" node="add" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_vector4FA" node="add" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_matrix33FA" node="add" nodegroup="math">
    <input name="in1" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_add_matrix44FA" node="add" nodegroup="math">
    <input name="in1" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <subtract>
    Subtract "in2" value/stream from the incoming float/integer/color/vector/matrix.
  -->
  <nodedef name="ND_subtract_float" node="subtract" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_integer" node="subtract" nodegroup="math">
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_color3" node="subtract" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_color4" node="subtract" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_vector2" node="subtract" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_vector3" node="subtract" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_vector4" node="subtract" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_matrix33" node="subtract" nodegroup="math">
    <input name="in1" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <input name="in2" type="matrix33" value="0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_matrix44" node="subtract" nodegroup="math">
    <input name="in1" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <input name="in2" type="matrix44" value="0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_color3FA" node="subtract" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_color4FA" node="subtract" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_vector2FA" node="subtract" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_vector3FA" node="subtract" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_vector4FA" node="subtract" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_matrix33FA" node="subtract" nodegroup="math">
    <input name="in1" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_subtract_matrix44FA" node="subtract" nodegroup="math">
    <input name="in1" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <multiply>
    Multiply the incoming float/color/vector by the "in2" value/stream, or multiply
    two matrices.
  -->
  <nodedef name="ND_multiply_float" node="multiply" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_color3" node="multiply" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_color4" node="multiply" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_vector2" node="multiply" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_vector3" node="multiply" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_vector4" node="multiply" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_matrix33" node="multiply" nodegroup="math">
    <input name="in1" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <input name="in2" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_matrix44" node="multiply" nodegroup="math">
    <input name="in1" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <input name="in2" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_color3FA" node="multiply" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_color4FA" node="multiply" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_vector2FA" node="multiply" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_vector3FA" node="multiply" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_multiply_vector4FA" node="multiply" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <divide>
    Divide an incoming float/color/vector by the "in2" value/stream; dividing a channel
    value by 0 results in floating-point "NaN".  Or, multiply one matrix by the
    inverse of a second matrix.
  -->
  <nodedef name="ND_divide_float" node="divide" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_color3" node="divide" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_color4" node="divide" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_vector2" node="divide" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_vector3" node="divide" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_vector4" node="divide" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_matrix33" node="divide" nodegroup="math">
    <input name="in1" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <input name="in2" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_matrix44" node="divide" nodegroup="math">
    <input name="in1" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <input name="in2" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_color3FA" node="divide" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_color4FA" node="divide" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_vector2FA" node="divide" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_vector3FA" node="divide" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_divide_vector4FA" node="divide" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <modulo>
    The remaining fraction after dividing one float/color/vector by another and
    subtracting the integer portion. The modula "in2" value cannot be 0.
  -->
  <nodedef name="ND_modulo_float" node="modulo" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_color3" node="modulo" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_color4" node="modulo" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_vector2" node="modulo" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_vector3" node="modulo" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_vector4" node="modulo" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_color3FA" node="modulo" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_color4FA" node="modulo" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_vector2FA" node="modulo" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_vector3FA" node="modulo" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_modulo_vector4FA" node="modulo" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <fract>
    The fraction of a float or vector.
  -->
  <nodedef name="ND_fract_float" node="fract" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_fract_color3" node="fract" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_fract_color4" node="fract" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_fract_vector2" node="fract" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_fract_vector3" node="fract" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_fract_vector4" node="fract" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <invert>
    Subtract the incoming float/color/vector from "amount" in all channels,
    outputting: amount - in.
  -->
  <nodedef name="ND_invert_float" node="invert" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <input name="amount" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_color3" node="invert" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_color4" node="invert" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_vector2" node="invert" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="amount" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_vector3" node="invert" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_vector4" node="invert" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_color3FA" node="invert" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_color4FA" node="invert" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_vector2FA" node="invert" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_vector3FA" node="invert" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invert_vector4FA" node="invert" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <absval>
    The per-channel absolute value of the incoming float/color/vector.
  -->
  <nodedef name="ND_absval_float" node="absval" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_absval_color3" node="absval" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_absval_color4" node="absval" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_absval_vector2" node="absval" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_absval_vector3" node="absval" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_absval_vector4" node="absval" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <floor>
    Find the nearest integer less than or equal to the parameter.
  -->
  <nodedef name="ND_floor_float" node="floor" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_floor_color3" node="floor" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_floor_color4" node="floor" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_floor_vector2" node="floor" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_floor_vector3" node="floor" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_floor_vector4" node="floor" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_floor_integer" node="floor" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="integer" defaultinput="in" />
  </nodedef>

  <!--
    Node: <ceil>
    Find the nearest integer greater than or equal to the parameter.
  -->
  <nodedef name="ND_ceil_float" node="ceil" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ceil_color3" node="ceil" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ceil_color4" node="ceil" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ceil_vector2" node="ceil" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ceil_vector3" node="ceil" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ceil_vector4" node="ceil" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ceil_integer" node="ceil" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="integer" defaultinput="in" />
  </nodedef>

  <!--
    Node: <round>
    Round incoming float/color/vector values.
  -->
  <nodedef name="ND_round_float" node="round" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_round_color3" node="round" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_round_color4" node="round" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_round_vector2" node="round" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_round_vector3" node="round" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_round_vector4" node="round" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_round_integer" node="round" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="integer" defaultinput="in" />
  </nodedef>

  <!--
    Node: <power>
    Raise incoming float/color/vector values to the "in2" power.
  -->
  <nodedef name="ND_power_float" node="power" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_color3" node="power" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_color4" node="power" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_vector2" node="power" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_vector3" node="power" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_vector4" node="power" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_color3FA" node="power" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_color4FA" node="power" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_vector2FA" node="power" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_vector3FA" node="power" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_power_vector4FA" node="power" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <safepower>
    Raise incoming float/color/vector values to the "in2" power.
    Negative "in1" values will result in negative output values. ie. out = sign(in1)*pow(abs(in1),in2)
  -->
  <nodedef name="ND_safepower_float" node="safepower" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_color3" node="safepower" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_color4" node="safepower" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_vector2" node="safepower" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_vector3" node="safepower" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_vector4" node="safepower" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_color3FA" node="safepower" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_color4FA" node="safepower" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_vector2FA" node="safepower" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_vector3FA" node="safepower" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_safepower_vector4FA" node="safepower" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>

  <!--
    Nodes: <sin>, <cos>, <tan>, <asin>, <acos>, <atan2>
    Standard trigonometric functions; angles are given in radians.
  -->
  <nodedef name="ND_sin_float" node="sin" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_cos_float" node="cos" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_tan_float" node="tan" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_asin_float" node="asin" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_acos_float" node="acos" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_atan2_float" node="atan2" nodegroup="math">
    <input name="iny" type="float" value="0.0" />
    <input name="inx" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="iny" />
  </nodedef>
  <nodedef name="ND_sin_vector2" node="sin" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_cos_vector2" node="cos" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_tan_vector2" node="tan" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_asin_vector2" node="asin" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_acos_vector2" node="acos" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_atan2_vector2" node="atan2" nodegroup="math">
    <input name="iny" type="vector2" value="1.0, 1.0" />
    <input name="inx" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="iny" />
  </nodedef>
  <nodedef name="ND_sin_vector3" node="sin" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_cos_vector3" node="cos" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_tan_vector3" node="tan" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_asin_vector3" node="asin" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_acos_vector3" node="acos" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_atan2_vector3" node="atan2" nodegroup="math">
    <input name="iny" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="inx" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="iny" />
  </nodedef>
  <nodedef name="ND_sin_vector4" node="sin" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_cos_vector4" node="cos" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_tan_vector4" node="tan" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_asin_vector4" node="asin" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_acos_vector4" node="acos" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_atan2_vector4" node="atan2" nodegroup="math">
    <input name="iny" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="inx" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="iny" />
  </nodedef>

  <!--
    Nodes: <sqrt>, <ln>, <exp>
    Standard math functions.
  -->
  <nodedef name="ND_sqrt_float" node="sqrt" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ln_float" node="ln" nodegroup="math">
    <input name="in" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_exp_float" node="exp" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_sqrt_vector2" node="sqrt" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ln_vector2" node="ln" nodegroup="math">
    <input name="in" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_exp_vector2" node="exp" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_sqrt_vector3" node="sqrt" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ln_vector3" node="ln" nodegroup="math">
    <input name="in" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_exp_vector3" node="exp" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_sqrt_vector4" node="sqrt" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_ln_vector4" node="ln" nodegroup="math">
    <input name="in" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_exp_vector4" node="exp" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <sign>
    Sign of eachinput channel: -1, 0 or +1
  -->
  <nodedef name="ND_sign_float" node="sign" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_sign_color3" node="sign" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_sign_color4" node="sign" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_sign_vector2" node="sign" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_sign_vector3" node="sign" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_sign_vector4" node="sign" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <clamp>
    Clamp incoming value to a specified range of values.
  -->
  <nodedef name="ND_clamp_float" node="clamp" nodegroup="math">
    <input name="in" type="float" value="0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_color3" node="clamp" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="low" type="color3" value="0.0, 0.0, 0.0" />
    <input name="high" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_color4" node="clamp" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="low" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="high" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_vector2" node="clamp" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="low" type="vector2" value="0.0, 0.0" />
    <input name="high" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_vector3" node="clamp" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="low" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="high" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_vector4" node="clamp" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="low" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="high" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_color3FA" node="clamp" nodegroup="math">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_color4FA" node="clamp" nodegroup="math">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_vector2FA" node="clamp" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_vector3FA" node="clamp" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_clamp_vector4FA" node="clamp" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <min>
    Select the minimum among incoming values.
  -->
  <nodedef name="ND_min_float" node="min" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_color3" node="min" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_color4" node="min" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_vector2" node="min" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_vector3" node="min" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_vector4" node="min" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_color3FA" node="min" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_color4FA" node="min" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_vector2FA" node="min" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_vector3FA" node="min" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_min_vector4FA" node="min" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <max>
    Select the maximum among incoming values.
  -->
  <nodedef name="ND_max_float" node="max" nodegroup="math">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_color3" node="max" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_color4" node="max" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_vector2" node="max" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_vector3" node="max" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_vector4" node="max" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_color3FA" node="max" nodegroup="math">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_color4FA" node="max" nodegroup="math">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_vector2FA" node="max" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_vector3FA" node="max" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_max_vector4FA" node="max" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <normalize>
    Outputs the normalized vector from the incoming vector stream.
  -->
  <nodedef name="ND_normalize_vector2" node="normalize" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_normalize_vector3" node="normalize" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_normalize_vector4" node="normalize" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <magnitude>
    Outputs the float magnitude (vector length) of the incoming vector stream.
  -->
  <nodedef name="ND_magnitude_vector2" node="magnitude" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_magnitude_vector3" node="magnitude" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_magnitude_vector4" node="magnitude" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>

  <!--
    Node: <distance>
    Measures the distance between two points in 2D, 3D, or 4D.
  -->
  <nodedef name="ND_distance_vector2" node="distance" nodegroup="math">
    <input name="in1" type="vector2" uiname="in1" value="0.0, 0.0" />
    <input name="in2" type="vector2" uiname="in2" value="0.0, 0.0" />
    <output name="out" type="float" />
  </nodedef>
  <nodedef name="ND_distance_vector3" node="distance" nodegroup="math">
    <input name="in1" type="vector3" uiname="in1" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" uiname="in2" value="0.0, 0.0, 0.0" />
    <output name="out" type="float" />
  </nodedef>
  <nodedef name="ND_distance_vector4" node="distance" nodegroup="math">
    <input name="in1" type="vector4" uiname="in1" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" uiname="in2" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <dotproduct>
    Perform a dot product of two 2-4 channel vectors
  -->
  <nodedef name="ND_dotproduct_vector2" node="dotproduct" nodegroup="math">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_dotproduct_vector3" node="dotproduct" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_dotproduct_vector4" node="dotproduct" nodegroup="math">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>

  <!--
    Node: <crossproduct>
    Perform a cross product of two vectors
  -->
  <nodedef name="ND_crossproduct_vector3" node="crossproduct" nodegroup="math">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <transformpoint>
    Transform a vector3 coordinate from one named space to another.
  -->
  <nodedef name="ND_transformpoint_vector3" node="transformpoint" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="fromspace" type="string" value="" uniform="true" />
    <input name="tospace" type="string" value="" uniform="true" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>

  <!--
    Node: <transformvector>
    Transform a vector from one named space to another.
  -->
  <nodedef name="ND_transformvector_vector3" node="transformvector" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="fromspace" type="string" value="" uniform="true" />
    <input name="tospace" type="string" value="" uniform="true" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <!--
    Node: <transformnormal>
    Transform a normal vector from one named space to another.
  -->
  <nodedef name="ND_transformnormal_vector3" node="transformnormal" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 1.0" />
    <input name="fromspace" type="string" value="" uniform="true" />
    <input name="tospace" type="string" value="" uniform="true" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>

  <!--
    Node: <transformmatrix>
    Transform a vector by a matrix.
  -->
  <nodedef name="ND_transformmatrix_vector2M3" node="transformmatrix" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="mat" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_transformmatrix_vector3" node="transformmatrix" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="mat" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_transformmatrix_vector3M4" node="transformmatrix" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="mat" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_transformmatrix_vector4" node="transformmatrix" nodegroup="math">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mat" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <normalmap>
    Transform a normal vector from object or tangent space into "world" space.
  -->
  <nodedef name="ND_normalmap_float" node="normalmap" nodegroup="math">
    <input name="in" type="vector3" value="0.5, 0.5, 1.0" />
    <input name="scale" type="float" value="1.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" />
    <input name="bitangent" type="vector3" defaultgeomprop="Bworld" />
    <output name="out" type="vector3" defaultinput="normal" />
  </nodedef>
  <nodedef name="ND_normalmap_vector2" node="normalmap" nodegroup="math">
    <input name="in" type="vector3" value="0.5, 0.5, 1.0" />
    <input name="scale" type="vector2" value="1.0, 1.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" />
    <input name="bitangent" type="vector3" defaultgeomprop="Bworld" />
    <output name="out" type="vector3" defaultinput="normal" />
  </nodedef>

  <!--
    Node: <hextilednormalmap> Supplemental Node
    Samples data from a single normalmap, with provisions for hex-tiling and randomizing the normalmap 
    across uv space.
  -->
  <nodedef name="ND_hextilednormalmap_vector3" node="hextilednormalmap" nodegroup="math">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="default" type="vector3" value="0.5, 0.5, 1.0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="tiling" type="vector2" value="1.0, 1.0" />
    <input name="rotation" type="float" value="1.0" />
    <input name="rotationrange" type="vector2" value="0.0, 360.0" />
    <input name="scale" type="float" value="1.0" />
    <input name="scalerange" type="vector2" value="0.5, 2.0" />
    <input name="offset" type="float" value="1.0" />
    <input name="offsetrange" type="vector2" value="0.0, 1.0" />
    <input name="falloff" type="float" value="0.5" />
    <input name="strength" type="float" value="1.0" />
    <input name="flip_g" type="boolean" value="false" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" />
    <input name="bitangent" type="vector3" defaultgeomprop="Bworld" />
    <output name="out" type="vector3" default="0.5, 0.5, 1.0" />
  </nodedef>

  <!--
    Node: <transpose>
    Output the transpose of the incoming matrix.
  -->
  <nodedef name="ND_transpose_matrix33" node="transpose" nodegroup="math">
    <input name="in" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <output name="out" type="matrix33" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_transpose_matrix44" node="transpose" nodegroup="math">
    <input name="in" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <output name="out" type="matrix44" defaultinput="in" />
  </nodedef>

  <!--
    Node: <determinant>
    Output the determinant of the incoming matrix.
  -->
  <nodedef name="ND_determinant_matrix33" node="determinant" nodegroup="math">
    <input name="in" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <output name="out" type="float" default="1.0" />
  </nodedef>
  <nodedef name="ND_determinant_matrix44" node="determinant" nodegroup="math">
    <input name="in" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <output name="out" type="float" default="1.0" />
  </nodedef>

  <!--
    Node: <invertmatrix>
    Invert an incoming matrix.
  -->
  <nodedef name="ND_invertmatrix_matrix33" node="invertmatrix" nodegroup="math">
    <input name="in" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <output name="out" type="matrix33" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_invertmatrix_matrix44" node="invertmatrix" nodegroup="math">
    <input name="in" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <output name="out" type="matrix44" defaultinput="in" />
  </nodedef>

  <!--
    Node: <rotate2d>
    Rotate a vector2 value about the origin.
  -->
  <nodedef name="ND_rotate2d_vector2" node="rotate2d" nodegroup="math">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="amount" type="float" value="0.0" unittype="angle" unit="degree" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>

  <!--
    Node: <rotate3d>
    Rotate a vector3 value about a specified unit axis vector
  -->
  <nodedef name="ND_rotate3d_vector3" node="rotate3d" nodegroup="math">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="0.0" unittype="angle" unit="degree" />
    <input name="axis" type="vector3" value="0.0, 1.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>

  <!--
    Node: <place2d> Supplemental Node
    Transform incoming UV texture coordinates from one 2D frame of reference to another.
    operationorder (integer enum): the order in which to perform the transform operations.
    "0" or "SRT" performs -pivot, scale, rotate, translate, +pivot as per the original
    implementation matching the behavior of certain DCC packages, and "1" or "TRS" performs
    -pivot, translate, rotate, scale, +pivot which does not introduce texture shear.
    Default is 0 "SRT" for backward compatibility.
  -->
  <nodedef name="ND_place2d_vector2" node="place2d" nodegroup="math">
    <input name="texcoord" type="vector2" value="0.0, 0.0" />
    <input name="pivot" type="vector2" value="0.0,0.0" />
    <input name="scale" type="vector2" value="1.0,1.0" />
    <input name="rotate" type="float" value="0.0" unittype="angle" unit="degree" />
    <input name="offset" type="vector2" value="0.0,0.0" />
    <input name="operationorder" type="integer" value="0" enum="SRT, TRS" enumvalues="0, 1" />
    <output name="out" type="vector2" defaultinput="texcoord" />
  </nodedef>

  <!--
    Node: <trianglewave>
    Generate a triangle wave from the given scalar input.
    The generated wave ranges from zero to one and repeats on integer boundaries.
  -->
  <nodedef name="ND_trianglewave_float" node="trianglewave" nodegroup="math">
    <input name="in" type="float" value="0" />
    <output name="out" type="float" />
  </nodedef>

  <!--
    Node: <reflect>
    Compute the reflection vector given an incident vector and unit surface normal.
  -->
  <nodedef name="ND_reflect_vector3" node="reflect" nodegroup="math" doc="Compute the reflection vector">
    <input name="in" type="vector3" value="1.0, 0.0, 0.0" doc="Incident vector" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" doc="Surface normal" />
    <output name="out" type="vector3" />
  </nodedef>

  <!--
    Node: <refract>
    Compute the refraction vector given an incident vector, unit surface normal,
    and index of refraction.
  -->
  <nodedef name="ND_refract_vector3" node="refract" nodegroup="math" doc="Compute the refraction vector">
    <input name="in" type="vector3" value="1.0, 0.0, 0.0" doc="Incident vector" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" doc="Surface normal" />
    <input name="ior" type="float" value="1.0" doc="Index of refraction" />
    <output name="out" type="vector3" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Adjustment nodes                                                         -->
  <!-- ======================================================================== -->

  <!--
    Node: <remap>
    Remap a value from one range of float/color/vector values to another.
  -->
  <nodedef name="ND_remap_float" node="remap" nodegroup="adjustment">
    <input name="in" type="float" value="0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_color3" node="remap" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="inlow" type="color3" value="0.0, 0.0, 0.0" />
    <input name="inhigh" type="color3" value="1.0, 1.0, 1.0" />
    <input name="outlow" type="color3" value="0.0, 0.0, 0.0" />
    <input name="outhigh" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_color4" node="remap" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inlow" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inhigh" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="outlow" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="outhigh" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_vector2" node="remap" nodegroup="adjustment">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="inlow" type="vector2" value="0.0, 0.0" />
    <input name="inhigh" type="vector2" value="1.0, 1.0" />
    <input name="outlow" type="vector2" value="0.0, 0.0" />
    <input name="outhigh" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_vector3" node="remap" nodegroup="adjustment">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="inlow" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="inhigh" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="outlow" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="outhigh" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_vector4" node="remap" nodegroup="adjustment">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inlow" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inhigh" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="outlow" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="outhigh" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_color3FA" node="remap" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_color4FA" node="remap" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_vector2FA" node="remap" nodegroup="adjustment">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_vector3FA" node="remap" nodegroup="adjustment">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_remap_vector4FA" node="remap" nodegroup="adjustment">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <smoothstep>
    Outputs a smooth (hermite-interpolated) remapping of input values from low-high
    to output 0-1.
  -->
  <nodedef name="ND_smoothstep_float" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="float" value="0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_color3" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="low" type="color3" value="0.0, 0.0, 0.0" />
    <input name="high" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_color4" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="low" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="high" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_vector2" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="low" type="vector2" value="0.0, 0.0" />
    <input name="high" type="vector2" value="1.0, 1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_vector3" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="low" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="high" type="vector3" value="1.0, 1.0, 1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_vector4" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="low" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="high" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_color3FA" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_color4FA" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_vector2FA" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_vector3FA" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_smoothstep_vector4FA" node="smoothstep" nodegroup="adjustment">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="low" type="float" value="0.0" />
    <input name="high" type="float" value="1.0" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <luminance>
    Output a grayscale image containing the luminance of the incoming RGB color in all color channels;
    the alpha channel is left unchanged if present.
  -->
  <nodedef name="ND_luminance_color3" node="luminance" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="lumacoeffs" type="color3" value="0.2722287, 0.6740818, 0.0536895" enum="acescg, rec709, rec2020, rec2100" enumvalues="0.2722287,0.6740818,0.0536895, 0.2126,0.7152,0.0722, 0.2627,0.6780,0.0593, 0.2627,0.6780,0.0593" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_luminance_color4" node="luminance" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="lumacoeffs" type="color3" value="0.2722287, 0.6740818, 0.0536895" enum="acescg, rec709, rec2020, rec2100" enumvalues="0.2722287,0.6740818,0.0536895, 0.2126,0.7152,0.0722, 0.2627,0.6780,0.0593, 0.2627,0.6780,0.0593" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>

  <!--
    Nodes: <rgbtohsv> and <hsvtorgb>
    Convert an incoming color between RGB and HSV space, with H and S ranging from 0-1.
  -->
  <nodedef name="ND_rgbtohsv_color3" node="rgbtohsv" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_rgbtohsv_color4" node="rgbtohsv" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_hsvtorgb_color3" node="hsvtorgb" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_hsvtorgb_color4" node="hsvtorgb" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <contrast> Supplemental Node
    Increase or decrease contrast of a float/color value using a linear slope multiplier.
  -->
  <nodedef name="ND_contrast_float" node="contrast" nodegroup="adjustment">
    <input name="in" type="float" value="0.0" />
    <input name="amount" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.5" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_color3" node="contrast" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="color3" value="1.0, 1.0, 1.0" />
    <input name="pivot" type="color3" value="0.5, 0.5, 0.5" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_color4" node="contrast" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="pivot" type="color4" value="0.5, 0.5, 0.5, 0.5" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_vector2" node="contrast" nodegroup="adjustment">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="amount" type="vector2" value="1.0, 1.0" />
    <input name="pivot" type="vector2" value="0.5, 0.5" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_vector3" node="contrast" nodegroup="adjustment">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="pivot" type="vector3" value="0.5, 0.5, 0.5" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_vector4" node="contrast" nodegroup="adjustment">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="pivot" type="vector4" value="0.5, 0.5, 0.5, 0.5" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_color3FA" node="contrast" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.5" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_color4FA" node="contrast" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.5" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_vector2FA" node="contrast" nodegroup="adjustment">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.5" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_vector3FA" node="contrast" nodegroup="adjustment">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.5" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_contrast_vector4FA" node="contrast" nodegroup="adjustment">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <input name="pivot" type="float" value="0.5" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <range> Supplemental Node
    Remap a value from one range of float/color/vector values to another, optionally
    applying a gamma correction in the middle, and optionally clamping output values.
  -->
  <nodedef name="ND_range_float" node="range" nodegroup="adjustment">
    <input name="in" type="float" value="0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="gamma" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_color3" node="range" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="inlow" type="color3" value="0.0, 0.0, 0.0" />
    <input name="inhigh" type="color3" value="1.0, 1.0, 1.0" />
    <input name="gamma" type="color3" value="1.0, 1.0, 1.0" />
    <input name="outlow" type="color3" value="0.0, 0.0, 0.0" />
    <input name="outhigh" type="color3" value="1.0, 1.0, 1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_color4" node="range" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inlow" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inhigh" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="gamma" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="outlow" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="outhigh" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_vector2" node="range" nodegroup="adjustment">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="inlow" type="vector2" value="0.0, 0.0" />
    <input name="inhigh" type="vector2" value="1.0, 1.0" />
    <input name="gamma" type="vector2" value="1.0, 1.0" />
    <input name="outlow" type="vector2" value="0.0, 0.0" />
    <input name="outhigh" type="vector2" value="1.0, 1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_vector3" node="range" nodegroup="adjustment">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="inlow" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="inhigh" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="gamma" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="outlow" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="outhigh" type="vector3" value="1.0, 1.0, 1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_vector4" node="range" nodegroup="adjustment">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inlow" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inhigh" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="gamma" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="outlow" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="outhigh" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_color3FA" node="range" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="gamma" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_color4FA" node="range" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="gamma" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_vector2FA" node="range" nodegroup="adjustment">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="gamma" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_vector3FA" node="range" nodegroup="adjustment">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="gamma" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_range_vector4FA" node="range" nodegroup="adjustment">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="inlow" type="float" value="0.0" />
    <input name="inhigh" type="float" value="1.0" />
    <input name="gamma" type="float" value="1.0" />
    <input name="outlow" type="float" value="0.0" />
    <input name="outhigh" type="float" value="1.0" />
    <input name="doclamp" type="boolean" value="false" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <hsvadjust> Supplemental Node
    Adjust the hue, saturation and value of an RGB color by converting the input color
    to HSV, adding amount.x to the hue, multiplying the saturation by amount.y,
    multiplying the value by amount.z, then converting back to RGB.
  -->
  <nodedef name="ND_hsvadjust_color3" node="hsvadjust" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="vector3" value="0.0, 1.0, 1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_hsvadjust_color4" node="hsvadjust" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="vector3" value="0.0, 1.0, 1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <saturate> Supplemental Node
    Adjust the saturation of a color using a linear interpolation between the incoming
    color and the grayscale luminance of the input computed using the provided luma
    coefficients; the alpha channel will be unchanged if present.
  -->
  <nodedef name="ND_saturate_color3" node="saturate" nodegroup="adjustment">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <input name="lumacoeffs" type="color3" value="0.2722287, 0.6740818, 0.0536895" enum="acescg, rec709, rec2020, rec2100" enumvalues="0.2722287,0.6740818,0.0536895, 0.2126,0.7152,0.0722, 0.2627,0.6780,0.0593, 0.2627,0.6780,0.0593" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_saturate_color4" node="saturate" nodegroup="adjustment">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="amount" type="float" value="1.0" />
    <input name="lumacoeffs" type="color3" value="0.2722287, 0.6740818, 0.0536895" enum="acescg, rec709, rec2020, rec2100" enumvalues="0.2722287,0.6740818,0.0536895, 0.2126,0.7152,0.0722, 0.2627,0.6780,0.0593, 0.2627,0.6780,0.0593" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <colorcorrect> Supplemental Node
    Combines various adjustment nodes into one, artist-friendly color correction node.
    The color4 signature does not touch the alpha channel.
  -->
  <nodedef name="ND_colorcorrect_color3" node="colorcorrect" nodegroup="adjustment">
    <input name="in" type="color3" uiname="Input Color" value="1, 1, 1" doc="The input color to be adjusted." />
    <input name="hue" type="float" uiname="Hue" uisoftmin="0.0" uisoftmax="1.0" value="0" doc="Rotates the color hue, with values wrapping at 0-1 boundaries." />
    <input name="saturation" type="float" uiname="Saturation" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Adjusts the input color saturation level." />
    <input name="gamma" type="float" uiname="Gamma" uisoftmin="0.0" uisoftmax="3.0" value="1" doc="Applies a gamma correction to the color." />
    <input name="lift" type="float" uiname="Lift" uisoftmin="0.0" uisoftmax="1.0" value="0" doc="Raise the dark color values, leaving the white values unchanged." />
    <input name="gain" type="float" uiname="Gain" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Multiplier increases lighter color values, leaving black values unchanged." />
    <input name="contrast" type="float" uiname="Contrast" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Linearly increase or decrease the color contrast." />
    <input name="contrastpivot" type="float" uiname="Contrast Pivot" uisoftmin="0.0" uisoftmax="1.0" value="0.5" doc="Pivot value around which contrast applies. This value will not change as contrast is adjusted." />
    <input name="exposure" type="float" uiname="Exposure" uisoftmin="-1.0" uisoftmax="1.0" value="0" doc="Multiplier which increases or decreases color brightness by 2^value." />
    <output name="out" type="color3" />
  </nodedef>
  <nodedef name="ND_colorcorrect_color4" node="colorcorrect" nodegroup="adjustment">
    <input name="in" type="color4" uiname="Input Color" value="1, 1, 1, 0" doc="The input color to be adjusted." />
    <input name="hue" type="float" uiname="Hue" uisoftmin="0.0" uisoftmax="1.0" value="0" doc="Rotates the color hue, with values wrapping at 0-1 boundaries." />
    <input name="saturation" type="float" uiname="Saturation" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Adjusts the input color saturation level." />
    <input name="gamma" type="float" uiname="Gamma" uisoftmin="0.0" uisoftmax="3.0" value="1" doc="Applies a gamma correction to the color." />
    <input name="lift" type="float" uiname="Lift" uisoftmin="0.0" uisoftmax="1.0" value="0" doc="Raise the dark color values, leaving the white values unchanged." />
    <input name="gain" type="float" uiname="Gain" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Multiplier increases lighter color values, leaving black values unchanged." />
    <input name="contrast" type="float" uiname="Contrast" uisoftmin="0.0" uisoftmax="1.0" value="1" doc="Linearly increase or decrease the color contrast." />
    <input name="contrastpivot" type="float" uiname="Contrast Pivot" uisoftmin="0.0" uisoftmax="1.0" value="0.5" doc="Pivot value around which contrast applies. This value will not change as contrast is adjusted." />
    <input name="exposure" type="float" uiname="Exposure" uisoftmin="-1.0" uisoftmax="1.0" value="0" doc="Multiplier which increases or decreases color brightness by 2^value." />
    <output name="out" type="color4" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Compositing nodes                                                        -->
  <!-- ======================================================================== -->

  <!--
    Node: <premult>
    Multiply the R or RGB channels of the input by the Alpha channel of the input.
  -->
  <nodedef name="ND_premult_color4" node="premult" nodegroup="compositing">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <unpremult>
    Divide the R or RGB channels of the input by the Alpha channel of the input.
    If the Alpha value is zero, it is passed through unchanged.
  -->
  <nodedef name="ND_unpremult_color4" node="unpremult" nodegroup="compositing">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <plus>
    Add two 1-4 channel inputs, with optional mixing between the bg input and the result.
  -->
  <nodedef name="ND_plus_float" node="plus" nodegroup="compositing">
    <input name="fg" type="float" value="0.0" />
    <input name="bg" type="float" value="0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_plus_color3" node="plus" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_plus_color4" node="plus" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <minus>
    Subtract two 1-4 channel inputs, with optional mixing between the bg input and the result.
  -->
  <nodedef name="ND_minus_float" node="minus" nodegroup="compositing">
    <input name="fg" type="float" value="0.0" />
    <input name="bg" type="float" value="0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_minus_color3" node="minus" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_minus_color4" node="minus" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <difference>
    Absolute-value difference of two 1-4 channel inputs, with optional mixing between
    the bg input and the result.
  -->
  <nodedef name="ND_difference_float" node="difference" nodegroup="compositing">
    <input name="fg" type="float" value="0.0" />
    <input name="bg" type="float" value="0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_difference_color3" node="difference" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_difference_color4" node="difference" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <burn>
    Take two 1-4 channel inputs and apply the same operator to all channels: 1-(1-B)/F
  -->
  <nodedef name="ND_burn_float" node="burn" nodegroup="compositing">
    <input name="fg" type="float" value="0.0" />
    <input name="bg" type="float" value="0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_burn_color3" node="burn" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_burn_color4" node="burn" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <dodge>
    Take two 1-4 channel inputs and apply the same operator to all channels: B/(1-F)
  -->
  <nodedef name="ND_dodge_float" node="dodge" nodegroup="compositing">
    <input name="fg" type="float" value="0.0" />
    <input name="bg" type="float" value="0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_dodge_color3" node="dodge" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_dodge_color4" node="dodge" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <screen>
    Take two 1-4 channel inputs and apply the same operator to all channels: 1-(1-F)*(1-B)
  -->
  <nodedef name="ND_screen_float" node="screen" nodegroup="compositing">
    <input name="fg" type="float" value="0.0" />
    <input name="bg" type="float" value="0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_screen_color3" node="screen" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_screen_color4" node="screen" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <overlay>
    Take two 1-4 channel inputs and apply the same operator to all channels:
      2FB if B<0.5;
      1-2(1-F)(1-B) if B>=0.5
  -->
  <nodedef name="ND_overlay_float" node="overlay" nodegroup="compositing">
    <input name="fg" type="float" value="0.0" />
    <input name="bg" type="float" value="0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_overlay_color3" node="overlay" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_overlay_color4" node="overlay" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <disjointover>
    Take two color4 inputs and use the built-in alpha
    channel(s) to control the compositing of the fg and bg inputs:
      F+B         if f+b<=1
      F+B(1-f)/b  if f+b>1
      alpha: min(f+b,1)
  -->
  <nodedef name="ND_disjointover_color4" node="disjointover" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <in>
    Take two color4 inputs and use the built-in alpha
    channel(s) to control the compositing of the fg and bg inputs: Fb  (alpha: fb)
  -->
  <nodedef name="ND_in_color4" node="in" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <mask>
    Take two color4 inputs and use the built-in alpha
    channel(s) to control the compositing of the fg and bg inputs: Bf  (alpha: bf)
  -->
  <nodedef name="ND_mask_color4" node="mask" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <matte>
    Take two color4 inputs and use the built-in alpha
    channel(s) to control the compositing of the fg and bg inputs: Ff+B(1-f)  (alpha: f+b(1-f))
  -->
  <nodedef name="ND_matte_color4" node="matte" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <out>
    Take two color4 inputs and use the built-in alpha
    channel(s) to control the compositing of the fg and bg inputs: F(1-b)  (alpha: f(1-b))
  -->
  <nodedef name="ND_out_color4" node="out" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <over>
    Take two color4 inputs and use the built-in alpha
    channel(s) to control the compositing of the fg and bg inputs: F+B(1-f)  (alpha: f+b(1-f))
  -->
  <nodedef name="ND_over_color4" node="over" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>

  <!--
    Node: <inside>
    Take one 1-4 channel input "in" plus a separate float "mask" input and apply the same
    operator to all channels: in * mask
  -->
  <nodedef name="ND_inside_float" node="inside" nodegroup="compositing">
    <input name="in" type="float" value="0.0" />
    <input name="mask" type="float" value="1.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_inside_color3" node="inside" nodegroup="compositing">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mask" type="float" value="1.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_inside_color4" node="inside" nodegroup="compositing">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mask" type="float" value="1.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <outside>
    Take one 1-4 channel input "in" plus a separate float "mask" input and apply the same
    operator to all channels: in * (1-mask)
  -->
  <nodedef name="ND_outside_float" node="outside" nodegroup="compositing">
    <input name="in" type="float" value="0.0" />
    <input name="mask" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_outside_color3" node="outside" nodegroup="compositing">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mask" type="float" value="0.0" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_outside_color4" node="outside" nodegroup="compositing">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mask" type="float" value="0.0" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <mix>
    Mix two inputs according to an input mix amount.
  -->
  <nodedef name="ND_mix_float" node="mix" nodegroup="compositing">
    <input name="fg" type="float" value="0.0" />
    <input name="bg" type="float" value="0.0" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="float" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_color3" node="mix" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_color3_color3" node="mix" nodegroup="compositing">
    <input name="fg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="color3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="color3" value="0.0, 0.0, 0.0" uisoftmin="0,0,0" uisoftmax="1,1,1" />
    <output name="out" type="color3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_color4" node="mix" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_color4_color4" node="mix" nodegroup="compositing">
    <input name="fg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="color4" value="0.0, 0.0, 0.0, 0.0" uisoftmin="0,0,0,0" uisoftmax="1,1,1,1" />
    <output name="out" type="color4" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_vector2" node="mix" nodegroup="compositing">
    <input name="fg" type="vector2" value="0.0, 0.0" />
    <input name="bg" type="vector2" value="0.0, 0.0" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="vector2" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_vector2_vector2" node="mix" nodegroup="compositing">
    <input name="fg" type="vector2" value="0.0, 0.0" />
    <input name="bg" type="vector2" value="0.0, 0.0" />
    <input name="mix" type="vector2" value="0.0, 0.0" uisoftmin="0,0" uisoftmax="1,1" />
    <output name="out" type="vector2" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_vector3" node="mix" nodegroup="compositing">
    <input name="fg" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="vector3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_vector3_vector3" node="mix" nodegroup="compositing">
    <input name="fg" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="bg" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="mix" type="vector3" value="0.0, 0.0, 0.0" uisoftmin="0,0,0" uisoftmax="1,1,1" />
    <output name="out" type="vector3" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_vector4" node="mix" nodegroup="compositing">
    <input name="fg" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="vector4" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_vector4_vector4" node="mix" nodegroup="compositing">
    <input name="fg" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="bg" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="mix" type="vector4" value="0.0, 0.0, 0.0, 0.0" uisoftmin="0,0,0,0" uisoftmax="1,1,1,1" />
    <output name="out" type="vector4" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_surfaceshader" node="mix" nodegroup="compositing">
    <input name="fg" type="surfaceshader" value="" />
    <input name="bg" type="surfaceshader" value="" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="surfaceshader" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_displacementshader" node="mix" nodegroup="compositing">
    <input name="fg" type="displacementshader" value="" />
    <input name="bg" type="displacementshader" value="" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="displacementshader" defaultinput="bg" />
  </nodedef>
  <nodedef name="ND_mix_volumeshader" node="mix" nodegroup="compositing">
    <input name="fg" type="volumeshader" value="" />
    <input name="bg" type="volumeshader" value="" />
    <input name="mix" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" />
    <output name="out" type="volumeshader" defaultinput="bg" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Conditional nodes                                                        -->
  <!-- ======================================================================== -->

  <!--
    Node: <ifgreater>
    Output the value of in1 if value1>value2, or the value of in2 if value1<=value2.
  -->
  <nodedef name="ND_ifgreater_float" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_integer" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_color3" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_color4" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_vector2" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_vector3" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_vector4" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_matrix33" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_matrix44" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_boolean" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <output name="out" type="boolean" default="false" />
  </nodedef>
  <nodedef name="ND_ifgreater_floatI" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_integerI" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_color3I" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_color4I" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_vector2I" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_vector3I" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_vector4I" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_matrix33I" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_matrix44I" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreater_booleanI" node="ifgreater" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <output name="out" type="boolean" default="false" />
  </nodedef>

  <!--
    Node: <ifgreatereq>
    Output the value of in1 if value1>=value2, or the value of in2 if value1<value2.
  -->
  <nodedef name="ND_ifgreatereq_float" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_integer" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_color3" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_color4" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_vector2" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_vector3" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_vector4" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_matrix33" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_matrix44" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_boolean" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <output name="out" type="boolean" default="false" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_floatI" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_integerI" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_color3I" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_color4I" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_vector2I" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_vector3I" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_vector4I" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_matrix33I" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_matrix44I" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifgreatereq_booleanI" node="ifgreatereq" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <output name="out" type="boolean" default="false" />
  </nodedef>

  <!--
    Node: <ifequal>
    Output the value of in1 if value1==value2, or the value of in2 if value1!=value2.
  -->
  <nodedef name="ND_ifequal_float" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_integer" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_color3" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_color4" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector2" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector3" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector4" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_matrix33" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_matrix44" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="0.0" />
    <input name="value2" type="float" value="0.0" />
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_boolean" node="ifequal" nodegroup="conditional">
    <input name="value1" type="float" value="1.0" />
    <input name="value2" type="float" value="0.0" />
    <output name="out" type="boolean" default="false" />
  </nodedef>
  <nodedef name="ND_ifequal_floatI" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_integerI" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_color3I" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_color4I" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector2I" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector3I" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector4I" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_matrix33I" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_matrix44I" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="0" />
    <input name="value2" type="integer" value="0" />
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_booleanI" node="ifequal" nodegroup="conditional">
    <input name="value1" type="integer" value="1" />
    <input name="value2" type="integer" value="0" />
    <output name="out" type="boolean" default="false" />
  </nodedef>
  <nodedef name="ND_ifequal_floatB" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_integerB" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="integer" value="0" />
    <input name="in2" type="integer" value="0" />
    <output name="out" type="integer" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_color3B" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_color4B" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector2B" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector3B" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_vector4B" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_matrix33B" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_matrix44B" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_ifequal_booleanB" node="ifequal" nodegroup="conditional">
    <input name="value1" type="boolean" value="false" />
    <input name="value2" type="boolean" value="false" />
    <output name="out" type="boolean" default="false" />
  </nodedef>

  <!--
    Node: <switch>
    Pass on the value of one of five input streams, according to the value of a selector parameter.
  -->
  <nodedef name="ND_switch_float" node="switch" nodegroup="conditional">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <input name="in3" type="float" value="0.0" />
    <input name="in4" type="float" value="0.0" />
    <input name="in5" type="float" value="0.0" />
    <input name="in6" type="float" value="0.0" />
    <input name="in7" type="float" value="0.0" />
    <input name="in8" type="float" value="0.0" />
    <input name="in9" type="float" value="0.0" />
    <input name="in10" type="float" value="0.0" />
    <input name="which" type="float" value="0.0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_color3" node="switch" nodegroup="conditional">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in3" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in4" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in5" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in6" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in7" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in8" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in9" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in10" type="color3" value="0.0, 0.0, 0.0" />
    <input name="which" type="float" value="0.0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_color4" node="switch" nodegroup="conditional">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in3" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in4" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in5" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in6" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in7" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in8" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in9" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in10" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="which" type="float" value="0.0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_vector2" node="switch" nodegroup="conditional">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <input name="in3" type="vector2" value="0.0, 0.0" />
    <input name="in4" type="vector2" value="0.0, 0.0" />
    <input name="in5" type="vector2" value="0.0, 0.0" />
    <input name="in6" type="vector2" value="0.0, 0.0" />
    <input name="in7" type="vector2" value="0.0, 0.0" />
    <input name="in8" type="vector2" value="0.0, 0.0" />
    <input name="in9" type="vector2" value="0.0, 0.0" />
    <input name="in10" type="vector2" value="0.0, 0.0" />
    <input name="which" type="float" value="0.0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_vector3" node="switch" nodegroup="conditional">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in3" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in4" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in5" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in6" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in7" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in8" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in9" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in10" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="which" type="float" value="0.0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_vector4" node="switch" nodegroup="conditional">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in3" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in4" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in5" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in6" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in7" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in8" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in9" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in10" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="which" type="float" value="0.0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_matrix33" node="switch" nodegroup="conditional">
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in3" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in4" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in5" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in6" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in7" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in8" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in9" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in10" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="which" type="float" value="0.0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_matrix44" node="switch" nodegroup="conditional">
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in3" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in4" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in5" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in6" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in7" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in8" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in9" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in10" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="which" type="float" value="0.0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_floatI" node="switch" nodegroup="conditional">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <input name="in3" type="float" value="0.0" />
    <input name="in4" type="float" value="0.0" />
    <input name="in5" type="float" value="0.0" />
    <input name="in6" type="float" value="0.0" />
    <input name="in7" type="float" value="0.0" />
    <input name="in8" type="float" value="0.0" />
    <input name="in9" type="float" value="0.0" />
    <input name="in10" type="float" value="0.0" />
    <input name="which" type="integer" value="0" />
    <output name="out" type="float" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_color3I" node="switch" nodegroup="conditional">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in3" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in4" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in5" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in6" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in7" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in8" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in9" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in10" type="color3" value="0.0, 0.0, 0.0" />
    <input name="which" type="integer" value="0" />
    <output name="out" type="color3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_color4I" node="switch" nodegroup="conditional">
    <input name="in1" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in3" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in4" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in5" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in6" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in7" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in8" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in9" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in10" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="which" type="integer" value="0" />
    <output name="out" type="color4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_vector2I" node="switch" nodegroup="conditional">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <input name="in3" type="vector2" value="0.0, 0.0" />
    <input name="in4" type="vector2" value="0.0, 0.0" />
    <input name="in5" type="vector2" value="0.0, 0.0" />
    <input name="in6" type="vector2" value="0.0, 0.0" />
    <input name="in7" type="vector2" value="0.0, 0.0" />
    <input name="in8" type="vector2" value="0.0, 0.0" />
    <input name="in9" type="vector2" value="0.0, 0.0" />
    <input name="in10" type="vector2" value="0.0, 0.0" />
    <input name="which" type="integer" value="0" />
    <output name="out" type="vector2" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_vector3I" node="switch" nodegroup="conditional">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in3" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in4" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in5" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in6" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in7" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in8" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in9" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in10" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="which" type="integer" value="0" />
    <output name="out" type="vector3" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_vector4I" node="switch" nodegroup="conditional">
    <input name="in1" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in3" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in4" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in5" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in6" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in7" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in8" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in9" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="in10" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="which" type="integer" value="0" />
    <output name="out" type="vector4" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_matrix33I" node="switch" nodegroup="conditional">
    <input name="in1" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in3" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in4" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in5" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in6" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in7" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in8" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in9" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in10" type="matrix33" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="which" type="integer" value="0" />
    <output name="out" type="matrix33" defaultinput="in1" />
  </nodedef>
  <nodedef name="ND_switch_matrix44I" node="switch" nodegroup="conditional">
    <input name="in1" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in3" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in4" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in5" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in6" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in7" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in8" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in9" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="in10" type="matrix44" value="0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0" />
    <input name="which" type="integer" value="0" />
    <output name="out" type="matrix44" defaultinput="in1" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Channel nodes                                                            -->
  <!-- ======================================================================== -->

  <!--
    Node: <convert>
    Convert a stream from one type to another; only certain unambiguous conversion
    types are supported.
  -->
  <nodedef name="ND_convert_float_color3" node="convert" nodegroup="channel">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_float_color4" node="convert" nodegroup="channel">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_float_vector2" node="convert" nodegroup="channel">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_float_vector3" node="convert" nodegroup="channel">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_float_vector4" node="convert" nodegroup="channel">
    <input name="in" type="float" value="0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <nodedef name="ND_convert_color3_color4" node="convert" nodegroup="channel">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_color3_vector2" node="convert" nodegroup="channel">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_color3_vector3" node="convert" nodegroup="channel">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_color3_vector4" node="convert" nodegroup="channel">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <nodedef name="ND_convert_color4_color3" node="convert" nodegroup="channel">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_color4_vector2" node="convert" nodegroup="channel">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_color4_vector3" node="convert" nodegroup="channel">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_color4_vector4" node="convert" nodegroup="channel">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <nodedef name="ND_convert_vector2_color3" node="convert" nodegroup="channel">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector2_color4" node="convert" nodegroup="channel">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector2_vector3" node="convert" nodegroup="channel">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector2_vector4" node="convert" nodegroup="channel">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <nodedef name="ND_convert_vector3_color3" node="convert" nodegroup="channel">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector3_color4" node="convert" nodegroup="channel">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector3_vector2" node="convert" nodegroup="channel">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector3_vector4" node="convert" nodegroup="channel">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <nodedef name="ND_convert_vector4_color3" node="convert" nodegroup="channel">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector4_color4" node="convert" nodegroup="channel">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector4_vector2" node="convert" nodegroup="channel">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_vector4_vector3" node="convert" nodegroup="channel">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>

  <nodedef name="ND_convert_boolean_float" node="convert" nodegroup="channel">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_convert_boolean_color3" node="convert" nodegroup="channel">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_boolean_color4" node="convert" nodegroup="channel">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_boolean_vector2" node="convert" nodegroup="channel">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_boolean_vector3" node="convert" nodegroup="channel">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_boolean_vector4" node="convert" nodegroup="channel">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_boolean_integer" node="convert" nodegroup="channel">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="integer" default="0" />
  </nodedef>

  <nodedef name="ND_convert_integer_float" node="convert" nodegroup="channel">
    <input name="in" type="integer" value="0" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_convert_integer_color3" node="convert" nodegroup="channel">
    <input name="in" type="integer" value="0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_integer_color4" node="convert" nodegroup="channel">
    <input name="in" type="integer" value="0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_integer_vector2" node="convert" nodegroup="channel">
    <input name="in" type="integer" value="0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_integer_vector3" node="convert" nodegroup="channel">
    <input name="in" type="integer" value="0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_integer_vector4" node="convert" nodegroup="channel">
    <input name="in" type="integer" value="0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_convert_integer_boolean" node="convert" nodegroup="channel">
    <input name="in" type="integer" value="0" />
    <output name="out" type="boolean" default="false" />
  </nodedef>

  <nodedef name="ND_convert_color3_surfaceshader" node="convert" version="1.0" isdefaultversion="true" nodegroup="shader" doc="Convert color3 to shader">
    <input name="in" type="color3" value="0, 0, 0" />
    <output name="out" type="surfaceshader" />
  </nodedef>
  <nodedef name="ND_convert_color4_surfaceshader" node="convert" version="1.0" isdefaultversion="true" nodegroup="shader" doc="Convert color4  to shader">
    <input name="in" type="color4" value="0, 0, 0, 0" />
    <output name="out" type="surfaceshader" />
  </nodedef>
  <nodedef name="ND_convert_float_surfaceshader" node="convert" version="1.0" isdefaultversion="true" nodegroup="shader" doc="Convert float to shader">
    <input name="in" type="float" value="0" />
    <output name="out" type="surfaceshader" />
  </nodedef>
  <nodedef name="ND_convert_vector2_surfaceshader" node="convert" version="1.0" isdefaultversion="true" nodegroup="shader" doc="Convert vector2 to shader">
    <input name="in" type="vector2" value="0, 0" />
    <output name="out" type="surfaceshader" />
  </nodedef>
  <nodedef name="ND_convert_vector3_surfaceshader" node="convert" version="1.0" isdefaultversion="true" nodegroup="shader" doc="Convert vector2 to shader">
    <input name="in" type="vector3" value="0, 0, 0" />
    <output name="out" type="surfaceshader" />
  </nodedef>
  <nodedef name="ND_convert_vector4_surfaceshader" node="convert" version="1.0" isdefaultversion="true" nodegroup="shader" doc="Convert vector4 to shader">
    <input name="in" type="vector4" value="0, 0, 0, 0" />
    <output name="out" type="surfaceshader" />
  </nodedef>
  <nodedef name="ND_convert_integer_surfaceshader" node="convert" version="1.0" isdefaultversion="true" nodegroup="shader" doc="Convert integer to shader">
    <input name="in" type="integer" value="0" />
    <output name="out" type="surfaceshader" />
  </nodedef>
  <nodedef name="ND_convert_boolean_surfaceshader" node="convert" version="1.0" isdefaultversion="true" nodegroup="shader" doc="Convert boolean to shader">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="surfaceshader" />
  </nodedef>

  <!--
    Node: <combine2>
    Combine the channels from two streams into the same number of channels of a
    single output stream of a specified compatible type.
  -->
  <nodedef name="ND_combine2_vector2" node="combine2" nodegroup="channel">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector2" default="0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_combine2_color4CF" node="combine2" nodegroup="channel">
    <input name="in1" type="color3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_combine2_vector4VF" node="combine2" nodegroup="channel">
    <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="in2" type="float" value="0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_combine2_vector4VV" node="combine2" nodegroup="channel">
    <input name="in1" type="vector2" value="0.0, 0.0" />
    <input name="in2" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <combine3>
    Combine the channels from three streams into the same number of channels of a
    single output stream of a specified compatible type.
  -->
  <nodedef name="ND_combine3_color3" node="combine3" nodegroup="channel">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <input name="in3" type="float" value="0.0" />
    <output name="out" type="color3" default="0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_combine3_vector3" node="combine3" nodegroup="channel">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <input name="in3" type="float" value="0.0" />
    <output name="out" type="vector3" default="0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node: <combine4>
    Combine the channels from four streams into the same number of channels of a
    single output stream of a specified compatible type.
  -->
  <nodedef name="ND_combine4_color4" node="combine4" nodegroup="channel">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <input name="in3" type="float" value="0.0" />
    <input name="in4" type="float" value="0.0" />
    <output name="out" type="color4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>
  <nodedef name="ND_combine4_vector4" node="combine4" nodegroup="channel">
    <input name="in1" type="float" value="0.0" />
    <input name="in2" type="float" value="0.0" />
    <input name="in3" type="float" value="0.0" />
    <input name="in4" type="float" value="0.0" />
    <output name="out" type="vector4" default="0.0, 0.0, 0.0, 0.0" />
  </nodedef>

  <!--
    Node <creatematrix>
    Combine the the three vectors3 from stream into a matrix 33.
  -->
  <nodedef name="ND_creatematrix_vector3_matrix33" node="creatematrix" nodegroup="math">
    <input name="in1" type="vector3" value="1.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 1.0, 0.0" />
    <input name="in3" type="vector3" value="0.0, 0.0, 1.0" />
    <output name="out" type="matrix33" default="1.0, 0.0, 0.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0" />
  </nodedef>

  <nodedef name="ND_creatematrix_vector3_matrix44" node="creatematrix" nodegroup="math">
    <input name="in1" type="vector3" value="1.0, 0.0, 0.0" />
    <input name="in2" type="vector3" value="0.0, 1.0, 0.0" />
    <input name="in3" type="vector3" value="0.0, 0.0, 1.0" />
    <input name="in4" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="matrix44" default="1.0, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0, 0.0,  0.0, 0.0, 1.0, 0.0,  0.0, 0.0, 0.0, 1.0" />
  </nodedef>

  <nodedef name="ND_creatematrix_vector4_matrix44" node="creatematrix" nodegroup="math">
    <input name="in1" type="vector4" value="1.0, 0.0, 0.0, 0.0" />
    <input name="in2" type="vector4" value="0.0, 1.0, 0.0, 0.0" />
    <input name="in3" type="vector4" value="0.0, 0.0, 1.0, 0.0" />
    <input name="in4" type="vector4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="matrix44" default="1.0, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0, 0.0,  0.0, 0.0, 1.0, 0.0,  0.0, 0.0, 0.0, 1.0" />
  </nodedef>

  <!--
    Node: <extract>
    Extract a single channel from a colorN or vectorN stream, outputting a float.
  -->
  <nodedef name="ND_extract_color3" node="extract" nodegroup="channel">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="index" type="integer" value="0" uimin="0" uimax="2" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_extract_color4" node="extract" nodegroup="channel">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="index" type="integer" value="0" uimin="0" uimax="3" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_extract_vector2" node="extract" nodegroup="channel">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="index" type="integer" value="0" uimin="0" uimax="1" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_extract_vector3" node="extract" nodegroup="channel">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="index" type="integer" value="0" uimin="0" uimax="2" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_extract_vector4" node="extract" nodegroup="channel">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="index" type="integer" value="0" uimin="0" uimax="3" uniform="true" />
    <output name="out" type="float" default="0.0" />
  </nodedef>

  <!--
    Node: <separate2>, <separate3>, <separate4> Supplemental Nodes
    Output each of the channels of a color/vector stream as a separate float output.
  -->
  <nodedef name="ND_separate2_vector2" node="separate2" nodegroup="channel">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <output name="outx" type="float" default="0.0" />
    <output name="outy" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_separate3_color3" node="separate3" nodegroup="channel">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="outr" type="float" default="0.0" />
    <output name="outg" type="float" default="0.0" />
    <output name="outb" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_separate3_vector3" node="separate3" nodegroup="channel">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="outx" type="float" default="0.0" />
    <output name="outy" type="float" default="0.0" />
    <output name="outz" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_separate4_color4" node="separate4" nodegroup="channel">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="outr" type="float" default="0.0" />
    <output name="outg" type="float" default="0.0" />
    <output name="outb" type="float" default="0.0" />
    <output name="outa" type="float" default="0.0" />
  </nodedef>
  <nodedef name="ND_separate4_vector4" node="separate4" nodegroup="channel">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <output name="outx" type="float" default="0.0" />
    <output name="outy" type="float" default="0.0" />
    <output name="outz" type="float" default="0.0" />
    <output name="outw" type="float" default="0.0" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Convolution nodes                                                        -->
  <!-- ======================================================================== -->

  <!--
    Node: <blur>
    A gaussian-falloff blur.
  -->
  <nodedef name="ND_blur_float" node="blur" nodegroup="convolution2d">
    <input name="in" type="float" value="0.0" />
    <input name="size" type="float" value="0.0" />
    <input name="filtertype" type="string" value="box" enum="box,gaussian" uniform="true" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_blur_color3" node="blur" nodegroup="convolution2d">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="size" type="float" value="0.0" />
    <input name="filtertype" type="string" value="box" enum="box,gaussian" uniform="true" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_blur_color4" node="blur" nodegroup="convolution2d">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="size" type="float" value="0.0" />
    <input name="filtertype" type="string" value="box" enum="box,gaussian" uniform="true" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_blur_vector2" node="blur" nodegroup="convolution2d">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="size" type="float" value="0.0" />
    <input name="filtertype" type="string" value="box" enum="box,gaussian" uniform="true" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_blur_vector3" node="blur" nodegroup="convolution2d">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="size" type="float" value="0.0" />
    <input name="filtertype" type="string" value="box" enum="box,gaussian" uniform="true" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_blur_vector4" node="blur" nodegroup="convolution2d">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="size" type="float" value="0.0" />
    <input name="filtertype" type="string" value="box" enum="box,gaussian" uniform="true" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>

  <!--
    Node: <heighttonormal>
    Convert a scalar height map to a normal map of type vector3.
  -->
  <nodedef name="ND_heighttonormal_vector3" node="heighttonormal" nodegroup="convolution2d">
    <input name="in" type="float" value="0.0" />
    <input name="scale" type="float" value="1.0" uimin="0.0" uisoftmax="5.0"/>
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <output name="out" type="vector3" default="0.5, 0.5, 1.0" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Logical operator nodes                                                   -->
  <!-- ======================================================================== -->

  <!--
    Node: <and>
    Logical And operation for two boolean values.
  -->
  <nodedef name="ND_logical_and" node="and" nodegroup="conditional">
    <input name="in1" type="boolean" value="false" />
    <input name="in2" type="boolean" value="false" />
    <output name="out" type="boolean" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <or>
    Logical Inclusive Or operation for two boolean values.
  -->
  <nodedef name="ND_logical_or" node="or" nodegroup="conditional">
    <input name="in1" type="boolean" value="false" />
    <input name="in2" type="boolean" value="false" />
    <output name="out" type="boolean" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <xor>
    Logical Exclusive Or operation for two boolean values.
  -->
  <nodedef name="ND_logical_xor" node="xor" nodegroup="conditional">
    <input name="in1" type="boolean" value="false" />
    <input name="in2" type="boolean" value="false" />
    <output name="out" type="boolean" defaultinput="in1" />
  </nodedef>

  <!--
    Node: <not>
    Returns logical Not of input.
  -->
  <nodedef name="ND_logical_not" node="not" nodegroup="conditional">
    <input name="in" type="boolean" value="false" />
    <output name="out" type="boolean" default="true"/>
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Organization nodes                                                       -->
  <!-- ======================================================================== -->

  <!--
    Node: <dot>
    No-op; passes its input to the output unchanged.
  -->
  <nodedef name="ND_dot_float" node="dot" nodegroup="organization">
    <input name="in" type="float" value="0.0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="float" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_color3" node="dot" nodegroup="organization">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="color3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_color4" node="dot" nodegroup="organization">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="color4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_vector2" node="dot" nodegroup="organization">
    <input name="in" type="vector2" value="0.0, 0.0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="vector2" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_vector3" node="dot" nodegroup="organization">
    <input name="in" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="vector3" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_vector4" node="dot" nodegroup="organization">
    <input name="in" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="vector4" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_boolean" node="dot" nodegroup="organization">
    <input name="in" type="boolean" value="false" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="boolean" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_integer" node="dot" nodegroup="organization">
    <input name="in" type="integer" value="0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="integer" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_matrix33" node="dot" nodegroup="organization">
    <input name="in" type="matrix33" value="1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="matrix33" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_matrix44" node="dot" nodegroup="organization">
    <input name="in" type="matrix44" value="1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="matrix44" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_string" node="dot" nodegroup="organization">
    <input name="in" type="string" value="" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="string" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_filename" node="dot" nodegroup="organization">
    <input name="in" type="filename" value="" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="filename" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_surfaceshader" node="dot" nodegroup="organization">
    <input name="in" type="surfaceshader" value="" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="surfaceshader" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_displacementshader" node="dot" nodegroup="organization">
    <input name="in" type="displacementshader" value="" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="displacementshader" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_volumeshader" node="dot" nodegroup="organization">
    <input name="in" type="volumeshader" value="" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="volumeshader" defaultinput="in" />
  </nodedef>
  <nodedef name="ND_dot_lightshader" node="dot" nodegroup="organization">
    <input name="in" type="lightshader" value="" />
    <input name="note" type="string" value="" uniform="true" />
    <output name="out" type="lightshader" defaultinput="in" />
  </nodedef>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Graph definitions of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- Texture nodes                                                            -->
  <!-- ======================================================================== -->

  <!--
    Node: <tiledimage>
  -->
  <nodegraph name="NG_tiledimage_float" nodedef="ND_tiledimage_float">
    <multiply name="N_mult_float" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="N_sub_float" type="vector2">
      <input name="in1" type="vector2" nodename="N_mult_float" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <divide name="N_divtilesize_float" type="vector2">
      <input name="in1" type="vector2" nodename="N_sub_float" />
      <input name="in2" type="vector2" interfacename="realworldimagesize" />
    </divide>
    <multiply name="N_multtilesize_float" type="vector2">
      <input name="in1" type="vector2" nodename="N_divtilesize_float" />
      <input name="in2" type="vector2" interfacename="realworldtilesize" />
    </multiply>
    <image name="N_img_float" type="float">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="float" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_multtilesize_float" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <output name="out" type="float" nodename="N_img_float" />
  </nodegraph>
  <nodegraph name="NG_tiledimage_color3" nodedef="ND_tiledimage_color3">
    <multiply name="N_mult_color3" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="N_sub_color3" type="vector2">
      <input name="in1" type="vector2" nodename="N_mult_color3" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <divide name="N_divtilesize_color3" type="vector2">
      <input name="in1" type="vector2" nodename="N_sub_color3" />
      <input name="in2" type="vector2" interfacename="realworldimagesize" />
    </divide>
    <multiply name="N_multtilesize_color3" type="vector2">
      <input name="in1" type="vector2" nodename="N_divtilesize_color3" />
      <input name="in2" type="vector2" interfacename="realworldtilesize" />
    </multiply>
    <image name="N_img_color3" type="color3">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="color3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_multtilesize_color3" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <output name="out" type="color3" nodename="N_img_color3" />
  </nodegraph>
  <nodegraph name="NG_tiledimage_color4" nodedef="ND_tiledimage_color4">
    <multiply name="N_mult_color4" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="N_sub_color4" type="vector2">
      <input name="in1" type="vector2" nodename="N_mult_color4" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <divide name="N_divtilesize_color4" type="vector2">
      <input name="in1" type="vector2" nodename="N_sub_color4" />
      <input name="in2" type="vector2" interfacename="realworldimagesize" />
    </divide>
    <multiply name="N_multtilesize_color4" type="vector2">
      <input name="in1" type="vector2" nodename="N_divtilesize_color4" />
      <input name="in2" type="vector2" interfacename="realworldtilesize" />
    </multiply>
    <image name="N_img_color4" type="color4">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="color4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_multtilesize_color4" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <output name="out" type="color4" nodename="N_img_color4" />
  </nodegraph>
  <nodegraph name="NG_tiledimage_vector2" nodedef="ND_tiledimage_vector2">
    <multiply name="N_mult_vector2" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="N_sub_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_mult_vector2" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <divide name="N_divtilesize_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_sub_vector2" />
      <input name="in2" type="vector2" interfacename="realworldimagesize" />
    </divide>
    <multiply name="N_multtilesize_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_divtilesize_vector2" />
      <input name="in2" type="vector2" interfacename="realworldtilesize" />
    </multiply>
    <image name="N_img_vector2" type="vector2">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="vector2" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_multtilesize_vector2" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <output name="out" type="vector2" nodename="N_img_vector2" />
  </nodegraph>
  <nodegraph name="NG_tiledimage_vector3" nodedef="ND_tiledimage_vector3">
    <multiply name="N_mult_vector3" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="N_sub_vector3" type="vector2">
      <input name="in1" type="vector2" nodename="N_mult_vector3" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <divide name="N_divtilesize_vector3" type="vector2">
      <input name="in1" type="vector2" nodename="N_sub_vector3" />
      <input name="in2" type="vector2" interfacename="realworldimagesize" />
    </divide>
    <multiply name="N_multtilesize_vector3" type="vector2">
      <input name="in1" type="vector2" nodename="N_divtilesize_vector3" />
      <input name="in2" type="vector2" interfacename="realworldtilesize" />
    </multiply>
    <image name="N_img_vector3" type="vector3">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="vector3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_multtilesize_vector3" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <output name="out" type="vector3" nodename="N_img_vector3" />
  </nodegraph>
  <nodegraph name="NG_tiledimage_vector4" nodedef="ND_tiledimage_vector4">
    <multiply name="N_mult_vector4" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="N_sub_vector4" type="vector2">
      <input name="in1" type="vector2" nodename="N_mult_vector4" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <divide name="N_divtilesize_vector4" type="vector2">
      <input name="in1" type="vector2" nodename="N_sub_vector4" />
      <input name="in2" type="vector2" interfacename="realworldimagesize" />
    </divide>
    <multiply name="N_multtilesize_vector4" type="vector2">
      <input name="in1" type="vector2" nodename="N_divtilesize_vector4" />
      <input name="in2" type="vector2" interfacename="realworldtilesize" />
    </multiply>
    <image name="N_img_vector4" type="vector4">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="vector4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_multtilesize_vector4" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <output name="out" type="vector4" nodename="N_img_vector4" />
  </nodegraph>

  <!--
    Node: <latlongimage>
  -->
  <nodegraph name="NG_latlongimage" nodedef="ND_latlongimage">
    <separate3 name="viewDirChannels" type="multioutput">
      <input name="in" type="vector3" interfacename="viewdir" />
    </separate3>
    <atan2 name="angleXZ" type="float">
      <input name="iny" type="float" nodename="viewDirChannels" output="outx" />
      <input name="inx" type="float" nodename="viewDirChannels" output="outz" />
    </atan2>
    <multiply name="scaleXZ" type="float">
      <input name="in1" type="float" nodename="angleXZ" />
      <input name="in2" type="float" value="-0.15915494" />
    </multiply>
    <add name="longitude" type="float">
      <input name="in1" type="float" nodename="scaleXZ" />
      <input name="in2" type="float" value="0.5" />
    </add>
    <multiply name="rotationRadians" type="float">
      <input name="in1" type="float" interfacename="rotation" />
      <input name="in2" type="float" value="0.00277778" />
    </multiply>
    <add name="offsetLongitude" type="float">
      <input name="in1" type="float" nodename="rotationRadians" />
      <input name="in2" type="float" nodename="longitude" />
    </add>
    <asin name="angleY" type="float">
      <input name="in" type="float" nodename="viewDirChannels" output="outy" />
    </asin>
    <multiply name="scaleY" type="float">
      <input name="in1" type="float" nodename="angleY" />
      <input name="in2" type="float" value="0.31830989" />
    </multiply>
    <add name="latitude" type="float">
      <input name="in1" type="float" nodename="scaleY" />
      <input name="in2" type="float" value="0.5" />
    </add>
    <combine2 name="mapUvs" type="vector2">
      <input name="in1" type="float" nodename="offsetLongitude" />
      <input name="in2" type="float" nodename="latitude" />
    </combine2>
    <image name="envImage" type="color3">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="color3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="mapUvs" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="mirror" />
      <input name="filtertype" type="string" value="linear" />
    </image>
    <output name="out" type="color3" nodename="envImage" />
  </nodegraph>

  <!--
    Node: <triplanarprojection>
    Samples data from three images, or layers within multi-layer images, and projects a tiled
    representation of the images along each of the three respective coordinate axes, computing
    a weighted blend of the three samples using the geometric normal.
  -->
  <nodegraph name="NG_triplanarprojection_float" nodedef="ND_triplanarprojection_float">
    <extract name="N_extX_float" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extY_float" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extZ_float" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="2" />
    </extract>
    <combine2 name="N_vecYZ_float" type="vector2">
      <input name="in1" type="float" nodename="N_extY_float" />
      <input name="in2" type="float" nodename="N_extZ_float" />
    </combine2>
    <combine2 name="N_vecXZ_float" type="vector2">
      <input name="in1" type="float" nodename="N_extX_float" />
      <input name="in2" type="float" nodename="N_extZ_float" />
    </combine2>
    <combine2 name="N_vecXY_float" type="vector2">
      <input name="in1" type="float" nodename="N_extX_float" />
      <input name="in2" type="float" nodename="N_extY_float" />
    </combine2>
    <multiply name="N_vecXY_invert_float" type="float">
      <input name="in1" type="float" nodename="N_extY_float" />
      <input name="in2" type="float" value="-1" />
    </multiply>
    <combine2 name="N_vecXY_xUp_float" type="vector2">
      <input name="in1" type="float" nodename="N_vecXY_invert_float" />
      <input name="in2" type="float" nodename="N_extX_float" />
    </combine2>
    <combine2 name="N_vecXZ_xUp_float" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_float" />
      <input name="in2" type="float" nodename="N_extX_float" />
    </combine2>
    <combine2 name="N_vecYZ_yUp_float" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_float" />
      <input name="in2" type="float" nodename="N_extY_float" />
    </combine2>
    <switch name="N_upDirSwitchXY_float" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXY_xUp_float" />
      <input name="in2" type="vector2" nodename="N_vecXY_float" />
      <input name="in3" type="vector2" nodename="N_vecXY_float" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchXZ_float" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXZ_xUp_float" />
      <input name="in2" type="vector2" nodename="N_vecXZ_float" />
      <input name="in3" type="vector2" nodename="N_vecXZ_float" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchYZ_float" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecYZ_yUp_float" />
      <input name="in2" type="vector2" nodename="N_vecYZ_yUp_float" />
      <input name="in3" type="vector2" nodename="N_vecYZ_float" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <image name="N_imgX_float" type="float">
      <input name="file" type="filename" interfacename="filex" />
      <input name="layer" type="string" interfacename="layerx" />
      <input name="default" type="float" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchYZ_float" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgY_float" type="float">
      <input name="file" type="filename" interfacename="filey" />
      <input name="layer" type="string" interfacename="layery" />
      <input name="default" type="float" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXZ_float" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgZ_float" type="float">
      <input name="file" type="filename" interfacename="filez" />
      <input name="layer" type="string" interfacename="layerz" />
      <input name="default" type="float" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXY_float" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <normalize name="N_norm_vector3" type="vector3">
      <input name="in" type="vector3" interfacename="normal" />
    </normalize>
    <absval name="N_absN" type="vector3">
      <input name="in" type="vector3" nodename="N_norm_vector3" />
    </absval>
    <dotproduct name="N_dotN" type="float">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="float" nodename="N_dotN" />
    </divide>
    <clamp name="N_clampForPrecision" type="float">
      <input name="in" type="float" interfacename="blend" />
      <input name="low" type="float" value="0.03" />
    </clamp>
    <divide name="N_oneOverBlend" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="N_clampForPrecision" />
    </divide>
    <power name="N_blendPower" type="vector3">
      <input name="in1" type="vector3" nodename="N_normalizeWeights" />
      <input name="in2" type="float" nodename="N_oneOverBlend" />
    </power>
    <dotproduct name="N_dotBlendedN" type="float">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeBlendedWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="float" nodename="N_dotBlendedN" />
    </divide>
    <separate3 name="N_separateWeights" type="multioutput">
      <input name="in" type="vector3" nodename="N_normalizeBlendedWeights" />
    </separate3>
    <multiply name="N_nX_float" type="float">
      <input name="in1" type="float" nodename="N_imgX_float" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outx" />
    </multiply>
    <multiply name="N_nY_float" type="float">
      <input name="in1" type="float" nodename="N_imgY_float" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outy" />
    </multiply>
    <multiply name="N_nZ_float" type="float">
      <input name="in1" type="float" nodename="N_imgZ_float" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outz" />
    </multiply>
    <add name="N_add1_float" type="float">
      <input name="in1" type="float" nodename="N_nX_float" />
      <input name="in2" type="float" nodename="N_nY_float" />
    </add>
    <add name="N_add2_float" type="float">
      <input name="in1" type="float" nodename="N_add1_float" />
      <input name="in2" type="float" nodename="N_nZ_float" />
    </add>
    <output name="out" type="float" nodename="N_add2_float" />
  </nodegraph>
  <nodegraph name="NG_triplanarprojection_color3" nodedef="ND_triplanarprojection_color3">
    <extract name="N_extX_color3" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extY_color3" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extZ_color3" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="2" />
    </extract>
    <combine2 name="N_vecYZ_color3" type="vector2">
      <input name="in1" type="float" nodename="N_extY_color3" />
      <input name="in2" type="float" nodename="N_extZ_color3" />
    </combine2>
    <combine2 name="N_vecXZ_color3" type="vector2">
      <input name="in1" type="float" nodename="N_extX_color3" />
      <input name="in2" type="float" nodename="N_extZ_color3" />
    </combine2>
    <combine2 name="N_vecXY_color3" type="vector2">
      <input name="in1" type="float" nodename="N_extX_color3" />
      <input name="in2" type="float" nodename="N_extY_color3" />
    </combine2>
    <multiply name="N_vecXY_invert_color3" type="float">
      <input name="in1" type="float" nodename="N_extY_color3" />
      <input name="in2" type="float" value="-1" />
    </multiply>
    <combine2 name="N_vecXY_xUp_color3" type="vector2">
      <input name="in1" type="float" nodename="N_vecXY_invert_color3" />
      <input name="in2" type="float" nodename="N_extX_color3" />
    </combine2>
    <combine2 name="N_vecXZ_xUp_color3" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_color3" />
      <input name="in2" type="float" nodename="N_extX_color3" />
    </combine2>
    <combine2 name="N_vecYZ_yUp_color3" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_color3" />
      <input name="in2" type="float" nodename="N_extY_color3" />
    </combine2>
    <switch name="N_upDirSwitchXY_color3" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXY_xUp_color3" />
      <input name="in2" type="vector2" nodename="N_vecXY_color3" />
      <input name="in3" type="vector2" nodename="N_vecXY_color3" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchXZ_color3" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXZ_xUp_color3" />
      <input name="in2" type="vector2" nodename="N_vecXZ_color3" />
      <input name="in3" type="vector2" nodename="N_vecXZ_color3" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchYZ_color3" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecYZ_yUp_color3" />
      <input name="in2" type="vector2" nodename="N_vecYZ_yUp_color3" />
      <input name="in3" type="vector2" nodename="N_vecYZ_color3" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <image name="N_imgX_color3" type="color3">
      <input name="file" type="filename" interfacename="filex" />
      <input name="layer" type="string" interfacename="layerx" />
      <input name="default" type="color3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchYZ_color3" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgY_color3" type="color3">
      <input name="file" type="filename" interfacename="filey" />
      <input name="layer" type="string" interfacename="layery" />
      <input name="default" type="color3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXZ_color3" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgZ_color3" type="color3">
      <input name="file" type="filename" interfacename="filez" />
      <input name="layer" type="string" interfacename="layerz" />
      <input name="default" type="color3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXY_color3" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <normalize name="N_norm_vector3" type="vector3">
      <input name="in" type="vector3" interfacename="normal" />
    </normalize>
    <absval name="N_absN" type="vector3">
      <input name="in" type="vector3" nodename="N_norm_vector3" />
    </absval>
    <dotproduct name="N_dotN" type="float">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="float" nodename="N_dotN" />
    </divide>
    <clamp name="N_clampForPrecision" type="float">
      <input name="in" type="float" interfacename="blend" />
      <input name="low" type="float" value="0.03" />
    </clamp>
    <divide name="N_oneOverBlend" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="N_clampForPrecision" />
    </divide>
    <power name="N_blendPower" type="vector3">
      <input name="in1" type="vector3" nodename="N_normalizeWeights" />
      <input name="in2" type="float" nodename="N_oneOverBlend" />
    </power>
    <dotproduct name="N_dotBlendedN" type="float">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeBlendedWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="float" nodename="N_dotBlendedN" />
    </divide>
    <separate3 name="N_separateWeights" type="multioutput">
      <input name="in" type="vector3" nodename="N_normalizeBlendedWeights" />
    </separate3>
    <multiply name="N_nX_color3" type="color3">
      <input name="in1" type="color3" nodename="N_imgX_color3" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outx" />
    </multiply>
    <multiply name="N_nY_color3" type="color3">
      <input name="in1" type="color3" nodename="N_imgY_color3" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outy" />
    </multiply>
    <multiply name="N_nZ_color3" type="color3">
      <input name="in1" type="color3" nodename="N_imgZ_color3" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outz" />
    </multiply>
    <add name="N_add1_color3" type="color3">
      <input name="in1" type="color3" nodename="N_nX_color3" />
      <input name="in2" type="color3" nodename="N_nY_color3" />
    </add>
    <add name="N_add2_color3" type="color3">
      <input name="in1" type="color3" nodename="N_add1_color3" />
      <input name="in2" type="color3" nodename="N_nZ_color3" />
    </add>
    <output name="out" type="color3" nodename="N_add2_color3" />
  </nodegraph>
  <nodegraph name="NG_triplanarprojection_color4" nodedef="ND_triplanarprojection_color4">
    <extract name="N_extX_color4" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extY_color4" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extZ_color4" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="2" />
    </extract>
    <combine2 name="N_vecYZ_color4" type="vector2">
      <input name="in1" type="float" nodename="N_extY_color4" />
      <input name="in2" type="float" nodename="N_extZ_color4" />
    </combine2>
    <combine2 name="N_vecXZ_color4" type="vector2">
      <input name="in1" type="float" nodename="N_extX_color4" />
      <input name="in2" type="float" nodename="N_extZ_color4" />
    </combine2>
    <combine2 name="N_vecXY_color4" type="vector2">
      <input name="in1" type="float" nodename="N_extX_color4" />
      <input name="in2" type="float" nodename="N_extY_color4" />
    </combine2>
    <multiply name="N_vecXY_invert_color4" type="float">
      <input name="in1" type="float" nodename="N_extY_color4" />
      <input name="in2" type="float" value="-1" />
    </multiply>
    <combine2 name="N_vecXY_xUp_color4" type="vector2">
      <input name="in1" type="float" nodename="N_vecXY_invert_color4" />
      <input name="in2" type="float" nodename="N_extX_color4" />
    </combine2>
    <combine2 name="N_vecXZ_xUp_color4" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_color4" />
      <input name="in2" type="float" nodename="N_extX_color4" />
    </combine2>
    <combine2 name="N_vecYZ_yUp_color4" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_color4" />
      <input name="in2" type="float" nodename="N_extY_color4" />
    </combine2>
    <switch name="N_upDirSwitchXY_color4" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXY_xUp_color4" />
      <input name="in2" type="vector2" nodename="N_vecXY_color4" />
      <input name="in3" type="vector2" nodename="N_vecXY_color4" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchXZ_color4" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXZ_xUp_color4" />
      <input name="in2" type="vector2" nodename="N_vecXZ_color4" />
      <input name="in3" type="vector2" nodename="N_vecXZ_color4" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchYZ_color4" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecYZ_yUp_color4" />
      <input name="in2" type="vector2" nodename="N_vecYZ_yUp_color4" />
      <input name="in3" type="vector2" nodename="N_vecYZ_color4" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <image name="N_imgX_color4" type="color4">
      <input name="file" type="filename" interfacename="filex" />
      <input name="layer" type="string" interfacename="layerx" />
      <input name="default" type="color4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchYZ_color4" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgY_color4" type="color4">
      <input name="file" type="filename" interfacename="filey" />
      <input name="layer" type="string" interfacename="layery" />
      <input name="default" type="color4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXZ_color4" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgZ_color4" type="color4">
      <input name="file" type="filename" interfacename="filez" />
      <input name="layer" type="string" interfacename="layerz" />
      <input name="default" type="color4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXY_color4" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <normalize name="N_norm_vector3" type="vector3">
      <input name="in" type="vector3" interfacename="normal" />
    </normalize>
    <absval name="N_absN" type="vector3">
      <input name="in" type="vector3" nodename="N_norm_vector3" />
    </absval>
    <dotproduct name="N_dotN" type="float">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="float" nodename="N_dotN" />
    </divide>
    <clamp name="N_clampForPrecision" type="float">
      <input name="in" type="float" interfacename="blend" />
      <input name="low" type="float" value="0.03" />
    </clamp>
    <divide name="N_oneOverBlend" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="N_clampForPrecision" />
    </divide>
    <power name="N_blendPower" type="vector3">
      <input name="in1" type="vector3" nodename="N_normalizeWeights" />
      <input name="in2" type="float" nodename="N_oneOverBlend" />
    </power>
    <dotproduct name="N_dotBlendedN" type="float">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeBlendedWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="float" nodename="N_dotBlendedN" />
    </divide>
    <separate3 name="N_separateWeights" type="multioutput">
      <input name="in" type="vector3" nodename="N_normalizeBlendedWeights" />
    </separate3>
    <multiply name="N_nX_color4" type="color4">
      <input name="in1" type="color4" nodename="N_imgX_color4" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outx" />
    </multiply>
    <multiply name="N_nY_color4" type="color4">
      <input name="in1" type="color4" nodename="N_imgY_color4" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outy" />
    </multiply>
    <multiply name="N_nZ_color4" type="color4">
      <input name="in1" type="color4" nodename="N_imgZ_color4" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outz" />
    </multiply>
    <add name="N_add1_color4" type="color4">
      <input name="in1" type="color4" nodename="N_nX_color4" />
      <input name="in2" type="color4" nodename="N_nY_color4" />
    </add>
    <add name="N_add2_color4" type="color4">
      <input name="in1" type="color4" nodename="N_add1_color4" />
      <input name="in2" type="color4" nodename="N_nZ_color4" />
    </add>
    <output name="out" type="color4" nodename="N_add2_color4" />
  </nodegraph>
  <nodegraph name="NG_triplanarprojection_vector2" nodedef="ND_triplanarprojection_vector2">
    <extract name="N_extX_vector2" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extY_vector2" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extZ_vector2" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="2" />
    </extract>
    <combine2 name="N_vecYZ_vector2" type="vector2">
      <input name="in1" type="float" nodename="N_extY_vector2" />
      <input name="in2" type="float" nodename="N_extZ_vector2" />
    </combine2>
    <combine2 name="N_vecXZ_vector2" type="vector2">
      <input name="in1" type="float" nodename="N_extX_vector2" />
      <input name="in2" type="float" nodename="N_extZ_vector2" />
    </combine2>
    <combine2 name="N_vecXY_vector2" type="vector2">
      <input name="in1" type="float" nodename="N_extX_vector2" />
      <input name="in2" type="float" nodename="N_extY_vector2" />
    </combine2>
    <multiply name="N_vecXY_invert_vector2" type="float">
      <input name="in1" type="float" nodename="N_extY_vector2" />
      <input name="in2" type="float" value="-1" />
    </multiply>
    <combine2 name="N_vecXY_xUp_vector2" type="vector2">
      <input name="in1" type="float" nodename="N_vecXY_invert_vector2" />
      <input name="in2" type="float" nodename="N_extX_vector2" />
    </combine2>
    <combine2 name="N_vecXZ_xUp_vector2" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_vector2" />
      <input name="in2" type="float" nodename="N_extX_vector2" />
    </combine2>
    <combine2 name="N_vecYZ_yUp_vector2" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_vector2" />
      <input name="in2" type="float" nodename="N_extY_vector2" />
    </combine2>
    <switch name="N_upDirSwitchXY_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXY_xUp_vector2" />
      <input name="in2" type="vector2" nodename="N_vecXY_vector2" />
      <input name="in3" type="vector2" nodename="N_vecXY_vector2" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchXZ_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXZ_xUp_vector2" />
      <input name="in2" type="vector2" nodename="N_vecXZ_vector2" />
      <input name="in3" type="vector2" nodename="N_vecXZ_vector2" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchYZ_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecYZ_yUp_vector2" />
      <input name="in2" type="vector2" nodename="N_vecYZ_yUp_vector2" />
      <input name="in3" type="vector2" nodename="N_vecYZ_vector2" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <image name="N_imgX_vector2" type="vector2">
      <input name="file" type="filename" interfacename="filex" />
      <input name="layer" type="string" interfacename="layerx" />
      <input name="default" type="vector2" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchYZ_vector2" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgY_vector2" type="vector2">
      <input name="file" type="filename" interfacename="filey" />
      <input name="layer" type="string" interfacename="layery" />
      <input name="default" type="vector2" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXZ_vector2" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgZ_vector2" type="vector2">
      <input name="file" type="filename" interfacename="filez" />
      <input name="layer" type="string" interfacename="layerz" />
      <input name="default" type="vector2" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXY_vector2" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <normalize name="N_norm_vector3" type="vector3">
      <input name="in" type="vector3" interfacename="normal" />
    </normalize>
    <absval name="N_absN" type="vector3">
      <input name="in" type="vector3" nodename="N_norm_vector3" />
    </absval>
    <dotproduct name="N_dotN" type="float">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="float" nodename="N_dotN" />
    </divide>
    <clamp name="N_clampForPrecision" type="float">
      <input name="in" type="float" interfacename="blend" />
      <input name="low" type="float" value="0.03" />
    </clamp>
    <divide name="N_oneOverBlend" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="N_clampForPrecision" />
    </divide>
    <power name="N_blendPower" type="vector3">
      <input name="in1" type="vector3" nodename="N_normalizeWeights" />
      <input name="in2" type="float" nodename="N_oneOverBlend" />
    </power>
    <dotproduct name="N_dotBlendedN" type="float">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeBlendedWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="float" nodename="N_dotBlendedN" />
    </divide>
    <separate3 name="N_separateWeights" type="multioutput">
      <input name="in" type="vector3" nodename="N_normalizeBlendedWeights" />
    </separate3>
    <multiply name="N_nX_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_imgX_vector2" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outx" />
    </multiply>
    <multiply name="N_nY_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_imgY_vector2" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outy" />
    </multiply>
    <multiply name="N_nZ_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_imgZ_vector2" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outz" />
    </multiply>
    <add name="N_add1_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_nX_vector2" />
      <input name="in2" type="vector2" nodename="N_nY_vector2" />
    </add>
    <add name="N_add2_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_add1_vector2" />
      <input name="in2" type="vector2" nodename="N_nZ_vector2" />
    </add>
    <output name="out" type="vector2" nodename="N_add2_vector2" />
  </nodegraph>
  <nodegraph name="NG_triplanarprojection_vector3" nodedef="ND_triplanarprojection_vector3">
    <extract name="N_extX_vector3" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extY_vector3" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extZ_vector3" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="2" />
    </extract>
    <combine2 name="N_vecYZ_vector3" type="vector2">
      <input name="in1" type="float" nodename="N_extY_vector3" />
      <input name="in2" type="float" nodename="N_extZ_vector3" />
    </combine2>
    <combine2 name="N_vecXZ_vector3" type="vector2">
      <input name="in1" type="float" nodename="N_extX_vector3" />
      <input name="in2" type="float" nodename="N_extZ_vector3" />
    </combine2>
    <combine2 name="N_vecXY_vector3" type="vector2">
      <input name="in1" type="float" nodename="N_extX_vector3" />
      <input name="in2" type="float" nodename="N_extY_vector3" />
    </combine2>
    <multiply name="N_vecXY_invert_vector3" type="float">
      <input name="in1" type="float" nodename="N_extY_vector3" />
      <input name="in2" type="float" value="-1" />
    </multiply>
    <combine2 name="N_vecXY_xUp_vector3" type="vector2">
      <input name="in1" type="float" nodename="N_vecXY_invert_vector3" />
      <input name="in2" type="float" nodename="N_extX_vector3" />
    </combine2>
    <combine2 name="N_vecXZ_xUp_vector3" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_vector3" />
      <input name="in2" type="float" nodename="N_extX_vector3" />
    </combine2>
    <combine2 name="N_vecYZ_yUp_vector3" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_vector3" />
      <input name="in2" type="float" nodename="N_extY_vector3" />
    </combine2>
    <switch name="N_upDirSwitchXY_vector3" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXY_xUp_vector3" />
      <input name="in2" type="vector2" nodename="N_vecXY_vector3" />
      <input name="in3" type="vector2" nodename="N_vecXY_vector3" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchXZ_vector3" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXZ_xUp_vector3" />
      <input name="in2" type="vector2" nodename="N_vecXZ_vector3" />
      <input name="in3" type="vector2" nodename="N_vecXZ_vector3" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchYZ_vector3" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecYZ_yUp_vector3" />
      <input name="in2" type="vector2" nodename="N_vecYZ_yUp_vector3" />
      <input name="in3" type="vector2" nodename="N_vecYZ_vector3" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <image name="N_imgX_vector3" type="vector3">
      <input name="file" type="filename" interfacename="filex" />
      <input name="layer" type="string" interfacename="layerx" />
      <input name="default" type="vector3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchYZ_vector3" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgY_vector3" type="vector3">
      <input name="file" type="filename" interfacename="filey" />
      <input name="layer" type="string" interfacename="layery" />
      <input name="default" type="vector3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXZ_vector3" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgZ_vector3" type="vector3">
      <input name="file" type="filename" interfacename="filez" />
      <input name="layer" type="string" interfacename="layerz" />
      <input name="default" type="vector3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXY_vector3" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <normalize name="N_norm_vector3" type="vector3">
      <input name="in" type="vector3" interfacename="normal" />
    </normalize>
    <absval name="N_absN" type="vector3">
      <input name="in" type="vector3" nodename="N_norm_vector3" />
    </absval>
    <dotproduct name="N_dotN" type="float">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="float" nodename="N_dotN" />
    </divide>
    <clamp name="N_clampForPrecision" type="float">
      <input name="in" type="float" interfacename="blend" />
      <input name="low" type="float" value="0.03" />
    </clamp>
    <divide name="N_oneOverBlend" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="N_clampForPrecision" />
    </divide>
    <power name="N_blendPower" type="vector3">
      <input name="in1" type="vector3" nodename="N_normalizeWeights" />
      <input name="in2" type="float" nodename="N_oneOverBlend" />
    </power>
    <dotproduct name="N_dotBlendedN" type="float">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeBlendedWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="float" nodename="N_dotBlendedN" />
    </divide>
    <separate3 name="N_separateWeights" type="multioutput">
      <input name="in" type="vector3" nodename="N_normalizeBlendedWeights" />
    </separate3>
    <multiply name="N_nX_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_imgX_vector3" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outx" />
    </multiply>
    <multiply name="N_nY_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_imgY_vector3" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outy" />
    </multiply>
    <multiply name="N_nZ_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_imgZ_vector3" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outz" />
    </multiply>
    <add name="N_add1_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_nX_vector3" />
      <input name="in2" type="vector3" nodename="N_nY_vector3" />
    </add>
    <add name="N_add2_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_add1_vector3" />
      <input name="in2" type="vector3" nodename="N_nZ_vector3" />
    </add>
    <output name="out" type="vector3" nodename="N_add2_vector3" />
  </nodegraph>
  <nodegraph name="NG_triplanarprojection_vector4" nodedef="ND_triplanarprojection_vector4">
    <extract name="N_extX_vector4" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extY_vector4" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extZ_vector4" type="float">
      <input name="in" type="vector3" interfacename="position" />
      <input name="index" type="integer" value="2" />
    </extract>
    <combine2 name="N_vecYZ_vector4" type="vector2">
      <input name="in1" type="float" nodename="N_extY_vector4" />
      <input name="in2" type="float" nodename="N_extZ_vector4" />
    </combine2>
    <combine2 name="N_vecXZ_vector4" type="vector2">
      <input name="in1" type="float" nodename="N_extX_vector4" />
      <input name="in2" type="float" nodename="N_extZ_vector4" />
    </combine2>
    <combine2 name="N_vecXY_vector4" type="vector2">
      <input name="in1" type="float" nodename="N_extX_vector4" />
      <input name="in2" type="float" nodename="N_extY_vector4" />
    </combine2>
    <multiply name="N_vecXY_invert_vector4" type="float">
      <input name="in1" type="float" nodename="N_extY_vector4" />
      <input name="in2" type="float" value="-1" />
    </multiply>
    <combine2 name="N_vecXY_xUp_vector4" type="vector2">
      <input name="in1" type="float" nodename="N_vecXY_invert_vector4" />
      <input name="in2" type="float" nodename="N_extX_vector4" />
    </combine2>
    <combine2 name="N_vecXZ_xUp_vector4" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_vector4" />
      <input name="in2" type="float" nodename="N_extX_vector4" />
    </combine2>
    <combine2 name="N_vecYZ_yUp_vector4" type="vector2">
      <input name="in1" type="float" nodename="N_extZ_vector4" />
      <input name="in2" type="float" nodename="N_extY_vector4" />
    </combine2>
    <switch name="N_upDirSwitchXY_vector4" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXY_xUp_vector4" />
      <input name="in2" type="vector2" nodename="N_vecXY_vector4" />
      <input name="in3" type="vector2" nodename="N_vecXY_vector4" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchXZ_vector4" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecXZ_xUp_vector4" />
      <input name="in2" type="vector2" nodename="N_vecXZ_vector4" />
      <input name="in3" type="vector2" nodename="N_vecXZ_vector4" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <switch name="N_upDirSwitchYZ_vector4" type="vector2">
      <input name="in1" type="vector2" nodename="N_vecYZ_yUp_vector4" />
      <input name="in2" type="vector2" nodename="N_vecYZ_yUp_vector4" />
      <input name="in3" type="vector2" nodename="N_vecYZ_vector4" />
      <input name="which" type="integer" interfacename="upaxis" />
    </switch>
    <image name="N_imgX_vector4" type="vector4">
      <input name="file" type="filename" interfacename="filex" />
      <input name="layer" type="string" interfacename="layerx" />
      <input name="default" type="vector4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchYZ_vector4" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgY_vector4" type="vector4">
      <input name="file" type="filename" interfacename="filey" />
      <input name="layer" type="string" interfacename="layery" />
      <input name="default" type="vector4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXZ_vector4" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <image name="N_imgZ_vector4" type="vector4">
      <input name="file" type="filename" interfacename="filez" />
      <input name="layer" type="string" interfacename="layerz" />
      <input name="default" type="vector4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="N_upDirSwitchXY_vector4" />
      <input name="uaddressmode" type="string" value="periodic" />
      <input name="vaddressmode" type="string" value="periodic" />
      <input name="filtertype" type="string" interfacename="filtertype" />
      <input name="framerange" type="string" interfacename="framerange" />
      <input name="frameoffset" type="integer" interfacename="frameoffset" />
      <input name="frameendaction" type="string" interfacename="frameendaction" />
    </image>
    <normalize name="N_norm_vector3" type="vector3">
      <input name="in" type="vector3" interfacename="normal" />
    </normalize>
    <absval name="N_absN" type="vector3">
      <input name="in" type="vector3" nodename="N_norm_vector3" />
    </absval>
    <dotproduct name="N_dotN" type="float">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_absN" />
      <input name="in2" type="float" nodename="N_dotN" />
    </divide>
    <clamp name="N_clampForPrecision" type="float">
      <input name="in" type="float" interfacename="blend" />
      <input name="low" type="float" value="0.03" />
    </clamp>
    <divide name="N_oneOverBlend" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="N_clampForPrecision" />
    </divide>
    <power name="N_blendPower" type="vector3">
      <input name="in1" type="vector3" nodename="N_normalizeWeights" />
      <input name="in2" type="float" nodename="N_oneOverBlend" />
    </power>
    <dotproduct name="N_dotBlendedN" type="float">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <divide name="N_normalizeBlendedWeights" type="vector3">
      <input name="in1" type="vector3" nodename="N_blendPower" />
      <input name="in2" type="float" nodename="N_dotBlendedN" />
    </divide>
    <separate3 name="N_separateWeights" type="multioutput">
      <input name="in" type="vector3" nodename="N_normalizeBlendedWeights" />
    </separate3>
    <multiply name="N_nX_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_imgX_vector4" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outx" />
    </multiply>
    <multiply name="N_nY_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_imgY_vector4" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outy" />
    </multiply>
    <multiply name="N_nZ_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_imgZ_vector4" />
      <input name="in2" type="float" nodename="N_separateWeights" output="outz" />
    </multiply>
    <add name="N_add1_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_nX_vector4" />
      <input name="in2" type="vector4" nodename="N_nY_vector4" />
    </add>
    <add name="N_add2_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_add1_vector4" />
      <input name="in2" type="vector4" nodename="N_nZ_vector4" />
    </add>
    <output name="out" type="vector4" nodename="N_add2_vector4" />
  </nodegraph>

  <!-- ======================================================================== -->
  <!-- Procedural nodes                                                         -->
  <!-- ======================================================================== -->

  <!--
    Node: <ramp>
    A ramp that supports up to 10 control points.
  -->
  <nodegraph name="NG_ramp" nodedef="ND_ramp">
    <separate2 name="separate1" type="multioutput" nodedef="ND_separate2_vector2">
      <input name="in" type="vector2" interfacename="texcoord" />
    </separate2>
    <ramp_gradient name="ramp_gradient1" type="color4" nodedef="ND_ramp_gradient">
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval_num" type="integer" value="1" />
      <input name="interval1" type="float" interfacename="interval1" />
      <input name="interval2" type="float" interfacename="interval2" />
      <input name="color1" type="color4" interfacename="color1" />
      <input name="prev_color" type="color4" interfacename="color1" />
      <input name="color2" type="color4" interfacename="color2" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient> 
    <ramp_gradient name="ramp_gradient2" type="color4" nodedef="ND_ramp_gradient">
      <input name="prev_color" type="color4" nodename="ramp_gradient1" />
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="interval_num" type="integer" value="2" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval1" type="float" interfacename="interval2" />
      <input name="interval2" type="float" interfacename="interval3" />
      <input name="color1" type="color4" interfacename="color2" />
      <input name="color2" type="color4" interfacename="color3" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient> 
    <ramp_gradient name="ramp_gradient3" type="color4" nodedef="ND_ramp_gradient">
      <input name="prev_color" type="color4" nodename="ramp_gradient2" />
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="interval_num" type="integer" value="3" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval1" type="float" interfacename="interval3" />
      <input name="interval2" type="float" interfacename="interval4" />
      <input name="color1" type="color4" interfacename="color3" />
      <input name="color2" type="color4" interfacename="color4" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient>
    <ramp_gradient name="ramp_gradient4" type="color4" nodedef="ND_ramp_gradient">
      <input name="prev_color" type="color4" nodename="ramp_gradient3" />
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="interval_num" type="integer" value="4" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval1" type="float" interfacename="interval4" />
      <input name="interval2" type="float" interfacename="interval5" />
      <input name="color1" type="color4" interfacename="color4" />
      <input name="color2" type="color4" interfacename="color5" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient>
    <ramp_gradient name="ramp_gradient5" type="color4" nodedef="ND_ramp_gradient">
      <input name="prev_color" type="color4" nodename="ramp_gradient4" />
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="interval_num" type="integer" value="5" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval1" type="float" interfacename="interval5" />
      <input name="interval2" type="float" interfacename="interval6" />
      <input name="color1" type="color4" interfacename="color5" />
      <input name="color2" type="color4" interfacename="color6" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient>
    <ramp_gradient name="ramp_gradient6" type="color4" nodedef="ND_ramp_gradient">
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="prev_color" type="color4" nodename="ramp_gradient5" />
      <input name="interval_num" type="integer" value="6" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval1" type="float" interfacename="interval6" />
      <input name="interval2" type="float" interfacename="interval7" />
      <input name="color1" type="color4" interfacename="color6" />
      <input name="color2" type="color4" interfacename="color7" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient>
    <ramp_gradient name="ramp_gradient7" type="color4" nodedef="ND_ramp_gradient">
      <input name="prev_color" type="color4" nodename="ramp_gradient6" />
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="interval_num" type="integer" value="7" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval1" type="float" interfacename="interval7" />
      <input name="interval2" type="float" interfacename="interval8" />
      <input name="color1" type="color4" interfacename="color7" />
      <input name="color2" type="color4" interfacename="color8" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient>
    <ramp_gradient name="ramp_gradient8" type="color4" nodedef="ND_ramp_gradient">
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="prev_color" type="color4" nodename="ramp_gradient7" />
      <input name="interval_num" type="integer" value="8" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval1" type="float" interfacename="interval8" />
      <input name="interval2" type="float" interfacename="interval9" />
      <input name="color1" type="color4" interfacename="color8" />
      <input name="color2" type="color4" interfacename="color9" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient>
    <ramp_gradient name="ramp_gradient9" type="color4" nodedef="ND_ramp_gradient">
      <input name="interpolation" type="integer" interfacename="interpolation" />
      <input name="prev_color" type="color4" nodename="ramp_gradient8" />
      <input name="interval_num" type="integer" value="9" />
      <input name="num_intervals" type="integer" interfacename="num_intervals" />
      <input name="interval1" type="float" interfacename="interval9" />
      <input name="interval2" type="float" interfacename="interval10" />
      <input name="color1" type="color4" interfacename="color9" />
      <input name="color2" type="color4" interfacename="color10" />
      <input name="x" type="float" nodename="ramp_type_selector" />
    </ramp_gradient>
    <switch name="ramp_type_selector" type="float" nodedef="ND_switch_floatI">
      <input name="which" type="integer" interfacename="type" />
      <input name="in1" type="float" nodename="separate1" output="outx" />
      <input name="in2" type="float" nodename="radial_add" />
      <input name="in3" type="float" nodename="circular_magnitude" />
      <input name="in4" type="float" nodename="box_ifgreater" />
    </switch>
    <multiply name="box_multiply" type="vector2" nodedef="ND_multiply_vector2FA">
      <input name="in1" type="vector2" nodename="box_absval" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <ifgreater name="box_ifgreater" type="float" nodedef="ND_ifgreater_float">
      <input name="value1" type="float" nodename="separate6" output="outx" />
      <input name="value2" type="float" nodename="separate6" output="outy" />
      <input name="in1" type="float" nodename="separate7" output="outx" />
      <input name="in2" type="float" nodename="separate7" output="outy" />
    </ifgreater>
    <absval name="box_absval" type="vector2" nodedef="ND_absval_vector2">
      <input name="in" type="vector2" nodename="subtract_half" />
    </absval>
    <separate2 name="separate7" type="multioutput" nodedef="ND_separate2_vector2">
      <input name="in" type="vector2" nodename="box_multiply" />
    </separate2>
    <separate2 name="separate6" type="multioutput" nodedef="ND_separate2_vector2">
      <input name="in" type="vector2" nodename="box_absval" />
    </separate2>
    <atan2 name="radial_atan2" type="float" nodedef="ND_atan2_float">
      <input name="inx" type="float" nodename="separate9" output="outy" />
      <input name="iny" type="float" nodename="separate9" output="outx" />
    </atan2>
    <divide name="radial_divide" type="float" nodedef="ND_divide_float">
      <input name="in1" type="float" nodename="radial_atan2" />
      <input name="in2" type="float" value="6.28319" />
    </divide>
    <add name="radial_add" type="float" nodedef="ND_add_float">
      <input name="in1" type="float" nodename="radial_divide" />
      <input name="in2" type="float" value="0.5" />
    </add>
    <multiply name="circular_multiply" type="vector2" nodedef="ND_multiply_vector2FA">
      <input name="in1" type="vector2" nodename="subtract_half" />
      <input name="in2" type="float" value="1.414" />
    </multiply>
    <magnitude name="circular_magnitude" type="float" nodedef="ND_magnitude_vector2">
      <input name="in" type="vector2" nodename="circular_multiply" />
    </magnitude>
    <subtract name="subtract_half" type="vector2" nodedef="ND_subtract_vector2FA">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="float" value="0.5" />
    </subtract>
    <separate2 name="separate9" type="multioutput" nodedef="ND_separate2_vector2">
      <input name="in" type="vector2" nodename="subtract_half" />
    </separate2>
    <output name="out" type="color4" nodename="ramp_gradient9" />
  </nodegraph>

  <!--
    Node: <ramp4>
    A 4-corner bilinear value ramp.
  -->
  <nodegraph name="NG_ramp4_float" nodedef="ND_ramp4_float">
    <clamp name="N_txclamp_float" type="vector2">
      <input name="in" type="vector2" interfacename="texcoord" />
    </clamp>
    <extract name="N_s_float" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_float" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_t_float" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_float" />
      <input name="index" type="integer" value="1" />
    </extract>
    <mix name="N_mixtop_float" type="float">
      <input name="bg" type="float" interfacename="valuetl" />
      <input name="fg" type="float" interfacename="valuetr" />
      <input name="mix" type="float" nodename="N_s_float" />
    </mix>
    <mix name="N_mixbot_float" type="float">
      <input name="bg" type="float" interfacename="valuebl" />
      <input name="fg" type="float" interfacename="valuebr" />
      <input name="mix" type="float" nodename="N_s_float" />
    </mix>
    <mix name="N_mix_float" type="float">
      <input name="bg" type="float" nodename="N_mixtop_float" />
      <input name="fg" type="float" nodename="N_mixbot_float" />
      <input name="mix" type="float" nodename="N_t_float" />
    </mix>
    <output name="out" type="float" nodename="N_mix_float" />
  </nodegraph>
  <nodegraph name="NG_ramp4_color3" nodedef="ND_ramp4_color3">
    <clamp name="N_txclamp_color3" type="vector2">
      <input name="in" type="vector2" interfacename="texcoord" />
    </clamp>
    <extract name="N_s_color3" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_color3" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_t_color3" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_color3" />
      <input name="index" type="integer" value="1" />
    </extract>
    <mix name="N_mixtop_color3" type="color3">
      <input name="bg" type="color3" interfacename="valuetl" />
      <input name="fg" type="color3" interfacename="valuetr" />
      <input name="mix" type="float" nodename="N_s_color3" />
    </mix>
    <mix name="N_mixbot_color3" type="color3">
      <input name="bg" type="color3" interfacename="valuebl" />
      <input name="fg" type="color3" interfacename="valuebr" />
      <input name="mix" type="float" nodename="N_s_color3" />
    </mix>
    <mix name="N_mix_color3" type="color3">
      <input name="bg" type="color3" nodename="N_mixtop_color3" />
      <input name="fg" type="color3" nodename="N_mixbot_color3" />
      <input name="mix" type="float" nodename="N_t_color3" />
    </mix>
    <output name="out" type="color3" nodename="N_mix_color3" />
  </nodegraph>
  <nodegraph name="NG_ramp4_color4" nodedef="ND_ramp4_color4">
    <clamp name="N_txclamp_color4" type="vector2">
      <input name="in" type="vector2" interfacename="texcoord" />
    </clamp>
    <extract name="N_s_color4" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_color4" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_t_color4" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_color4" />
      <input name="index" type="integer" value="1" />
    </extract>
    <mix name="N_mixtop_color4" type="color4">
      <input name="bg" type="color4" interfacename="valuetl" />
      <input name="fg" type="color4" interfacename="valuetr" />
      <input name="mix" type="float" nodename="N_s_color4" />
    </mix>
    <mix name="N_mixbot_color4" type="color4">
      <input name="bg" type="color4" interfacename="valuebl" />
      <input name="fg" type="color4" interfacename="valuebr" />
      <input name="mix" type="float" nodename="N_s_color4" />
    </mix>
    <mix name="N_mix_color4" type="color4">
      <input name="bg" type="color4" nodename="N_mixtop_color4" />
      <input name="fg" type="color4" nodename="N_mixbot_color4" />
      <input name="mix" type="float" nodename="N_t_color4" />
    </mix>
    <output name="out" type="color4" nodename="N_mix_color4" />
  </nodegraph>
  <nodegraph name="NG_ramp4_vector2" nodedef="ND_ramp4_vector2">
    <clamp name="N_txclamp_vector2" type="vector2">
      <input name="in" type="vector2" interfacename="texcoord" />
    </clamp>
    <extract name="N_s_vector2" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_vector2" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_t_vector2" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_vector2" />
      <input name="index" type="integer" value="1" />
    </extract>
    <mix name="N_mixtop_vector2" type="vector2">
      <input name="bg" type="vector2" interfacename="valuetl" />
      <input name="fg" type="vector2" interfacename="valuetr" />
      <input name="mix" type="float" nodename="N_s_vector2" />
    </mix>
    <mix name="N_mixbot_vector2" type="vector2">
      <input name="bg" type="vector2" interfacename="valuebl" />
      <input name="fg" type="vector2" interfacename="valuebr" />
      <input name="mix" type="float" nodename="N_s_vector2" />
    </mix>
    <mix name="N_mix_vector2" type="vector2">
      <input name="bg" type="vector2" nodename="N_mixtop_vector2" />
      <input name="fg" type="vector2" nodename="N_mixbot_vector2" />
      <input name="mix" type="float" nodename="N_t_vector2" />
    </mix>
    <output name="out" type="vector2" nodename="N_mix_vector2" />
  </nodegraph>
  <nodegraph name="NG_ramp4_vector3" nodedef="ND_ramp4_vector3">
    <clamp name="N_txclamp_vector3" type="vector2">
      <input name="in" type="vector2" interfacename="texcoord" />
    </clamp>
    <extract name="N_s_vector3" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_vector3" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_t_vector3" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_vector3" />
      <input name="index" type="integer" value="1" />
    </extract>
    <mix name="N_mixtop_vector3" type="vector3">
      <input name="bg" type="vector3" interfacename="valuetl" />
      <input name="fg" type="vector3" interfacename="valuetr" />
      <input name="mix" type="float" nodename="N_s_vector3" />
    </mix>
    <mix name="N_mixbot_vector3" type="vector3">
      <input name="bg" type="vector3" interfacename="valuebl" />
      <input name="fg" type="vector3" interfacename="valuebr" />
      <input name="mix" type="float" nodename="N_s_vector3" />
    </mix>
    <mix name="N_mix_vector3" type="vector3">
      <input name="bg" type="vector3" nodename="N_mixtop_vector3" />
      <input name="fg" type="vector3" nodename="N_mixbot_vector3" />
      <input name="mix" type="float" nodename="N_t_vector3" />
    </mix>
    <output name="out" type="vector3" nodename="N_mix_vector3" />
  </nodegraph>
  <nodegraph name="NG_ramp4_vector4" nodedef="ND_ramp4_vector4">
    <clamp name="N_txclamp_vector4" type="vector2">
      <input name="in" type="vector2" interfacename="texcoord" />
    </clamp>
    <extract name="N_s_vector4" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_vector4" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_t_vector4" type="float">
      <input name="in" type="vector2" nodename="N_txclamp_vector4" />
      <input name="index" type="integer" value="1" />
    </extract>
    <mix name="N_mixtop_vector4" type="vector4">
      <input name="bg" type="vector4" interfacename="valuetl" />
      <input name="fg" type="vector4" interfacename="valuetr" />
      <input name="mix" type="float" nodename="N_s_vector4" />
    </mix>
    <mix name="N_mixbot_vector4" type="vector4">
      <input name="bg" type="vector4" interfacename="valuebl" />
      <input name="fg" type="vector4" interfacename="valuebr" />
      <input name="mix" type="float" nodename="N_s_vector4" />
    </mix>
    <mix name="N_mix_vector4" type="vector4">
      <input name="bg" type="vector4" nodename="N_mixtop_vector4" />
      <input name="fg" type="vector4" nodename="N_mixbot_vector4" />
      <input name="mix" type="float" nodename="N_t_vector4" />
    </mix>
    <output name="out" type="vector4" nodename="N_mix_vector4" />
  </nodegraph>

  <!--
    Node <ramp_gradient>
    A helper node that handles a single control point within a <ramp>.
  -->
  <nodegraph name="NG_ramp_gradient" nodedef="ND_ramp_gradient">
    <clamp name="linear_clamp" type="float" nodedef="ND_clamp_float">
      <input name="in" type="float" interfacename="x" />
      <input name="low" type="float" interfacename="interval1" />
      <input name="high" type="float" interfacename="interval2" />
    </clamp>
    <remap name="linear_remap" type="float" nodedef="ND_remap_float">
      <input name="in" type="float" nodename="linear_clamp" />
      <input name="inlow" type="float" interfacename="interval1" />
      <input name="inhigh" type="float" interfacename="interval2" />
      <input name="outlow" type="float" value="0" />
      <input name="outhigh" type="float" value="1" />
    </remap>
    <smoothstep name="smoothstep" type="float" nodedef="ND_smoothstep_float">
      <input name="in" type="float" interfacename="x" />
      <input name="low" type="float" interfacename="interval1" />
      <input name="high" type="float" interfacename="interval2" />
    </smoothstep>
    <switch name="interpolation_selector" type="float" nodedef="ND_switch_floatI">
      <input name="which" type="integer" interfacename="interpolation" />
      <input name="in1" type="float" nodename="linear_remap" />
      <input name="in2" type="float" nodename="smoothstep" />
    </switch>
    <mix name="mix3" type="color4" nodedef="ND_mix_color4">
      <input name="fg" type="color4" interfacename="color2" />
      <input name="bg" type="color4" interfacename="color1" />
      <input name="mix" type="float" nodename="interpolation_selector" />
    </mix>
    <ifgreater name="step_ifgreater" type="color4" nodedef="ND_ifgreater_color4">
      <input name="value2" type="float" interfacename="x" />
      <input name="in1" type="color4" interfacename="color1" />
      <input name="in2" type="color4" interfacename="color2" />
      <input name="value1" type="float" interfacename="interval2" />
    </ifgreater>
    <switch name="interpolation_selector2" type="color4" nodedef="ND_switch_color4I">
      <input name="in1" type="color4" nodename="mix3" />
      <input name="in2" type="color4" nodename="mix3" />
      <input name="which" type="integer" interfacename="interpolation" />
      <input name="in3" type="color4" nodename="step_ifgreater" />
    </switch>
    <ifgreater name="ifgreater3" type="color4" nodedef="ND_ifgreater_color4">
      <input name="value1" type="float" interfacename="x" />
      <input name="value2" type="float" interfacename="interval1" />
      <input name="in1" type="color4" nodename="interpolation_selector2" />
      <input name="in2" type="color4" interfacename="prev_color" />
    </ifgreater>
    <ifgreater name="ifgreatereq1" type="color4" nodedef="ND_ifgreatereq_color4I">
      <input name="value1" type="integer" interfacename="interval_num" />
      <input name="value2" type="integer" interfacename="num_intervals" />
      <input name="in1" type="color4" interfacename="prev_color" />
      <input name="in2" type="color4" nodename="ifgreater3" />
    </ifgreater>
    <output name="out" type="color4" nodename="ifgreatereq1" />
  </nodegraph>

  <!--
    Node: <noise2d>
  -->
  <nodegraph name="NG_noise2d_color3" nodedef="ND_noise2d_color3">
    <noise2d name="N_noise2d" type="vector3">
      <input name="amplitude" type="vector3" interfacename="amplitude" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </noise2d>
    <convert name="N_convert" type="color3">
      <input name="in" type="vector3" nodename="N_noise2d" />
    </convert>
    <output name="out" type="color3" nodename="N_convert" />
  </nodegraph>
  <nodegraph name="NG_noise2d_color4" nodedef="ND_noise2d_color4">
    <noise2d name="N_noise2d" type="vector4">
      <input name="amplitude" type="vector4" interfacename="amplitude" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </noise2d>
    <convert name="N_convert" type="color4">
      <input name="in" type="vector4" nodename="N_noise2d" />
    </convert>
    <output name="out" type="color4" nodename="N_convert" />
  </nodegraph>
  <nodegraph name="NG_noise2d_color3FA" nodedef="ND_noise2d_color3FA">
    <convert name="N_convert" type="vector3">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise2d name="N_noise2d" type="color3">
      <input name="amplitude" type="vector3" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </noise2d>
    <output name="out" type="color3" nodename="N_noise2d" />
  </nodegraph>
  <nodegraph name="NG_noise2d_color4FA" nodedef="ND_noise2d_color4FA">
    <convert name="N_convert" type="vector4">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise2d name="N_noise2d" type="color4">
      <input name="amplitude" type="vector4" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </noise2d>
    <output name="out" type="color4" nodename="N_noise2d" />
  </nodegraph>
  <nodegraph name="NG_noise2d_vector2FA" nodedef="ND_noise2d_vector2FA">
    <convert name="N_convert" type="vector2">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise2d name="N_noise2d" type="vector2">
      <input name="amplitude" type="vector2" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </noise2d>
    <output name="out" type="vector2" nodename="N_noise2d" />
  </nodegraph>
  <nodegraph name="NG_noise2d_vector3FA" nodedef="ND_noise2d_vector3FA">
    <convert name="N_convert" type="vector3">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise2d name="N_noise2d" type="vector3">
      <input name="amplitude" type="vector3" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </noise2d>
    <output name="out" type="vector3" nodename="N_noise2d" />
  </nodegraph>
  <nodegraph name="NG_noise2d_vector4FA" nodedef="ND_noise2d_vector4FA">
    <convert name="N_convert" type="vector4">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise2d name="N_noise2d" type="vector4">
      <input name="amplitude" type="vector4" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </noise2d>
    <output name="out" type="vector4" nodename="N_noise2d" />
  </nodegraph>

  <!--
    Node: <noise3d>
  -->
  <nodegraph name="NG_noise3d_color3" nodedef="ND_noise3d_color3">
    <noise3d name="N_noise3d" type="vector3">
      <input name="amplitude" type="vector3" interfacename="amplitude" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="position" type="vector3" interfacename="position" />
    </noise3d>
    <convert name="N_convert" type="color3">
      <input name="in" type="vector3" nodename="N_noise3d" />
    </convert>
    <output name="out" type="color3" nodename="N_convert" />
  </nodegraph>
  <nodegraph name="NG_noise3d_color4" nodedef="ND_noise3d_color4">
    <noise3d name="N_noise3d" type="vector4">
      <input name="amplitude" type="vector4" interfacename="amplitude" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="position" type="vector3" interfacename="position" />
    </noise3d>
    <convert name="N_convert" type="color4">
      <input name="in" type="vector4" nodename="N_noise3d" />
    </convert>
    <output name="out" type="color4" nodename="N_convert" />
  </nodegraph>
  <nodegraph name="NG_noise3d_color3FA" nodedef="ND_noise3d_color3FA">
    <convert name="N_convert" type="vector3">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise3d name="N_noise3d" type="color3">
      <input name="amplitude" type="vector3" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="position" type="vector3" interfacename="position" />
    </noise3d>
    <output name="out" type="color3" nodename="N_noise3d" />
  </nodegraph>
  <nodegraph name="NG_noise3d_color4FA" nodedef="ND_noise3d_color4FA">
    <convert name="N_convert" type="vector4">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise3d name="N_noise3d" type="color4">
      <input name="amplitude" type="vector4" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="position" type="vector3" interfacename="position" />
    </noise3d>
    <output name="out" type="color4" nodename="N_noise3d" />
  </nodegraph>
  <nodegraph name="NG_noise3d_vector2FA" nodedef="ND_noise3d_vector2FA">
    <convert name="N_convert" type="vector2">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise3d name="N_noise3d" type="vector2">
      <input name="amplitude" type="vector2" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="position" type="vector3" interfacename="position" />
    </noise3d>
    <output name="out" type="vector2" nodename="N_noise3d" />
  </nodegraph>
  <nodegraph name="NG_noise3d_vector3FA" nodedef="ND_noise3d_vector3FA">
    <convert name="N_convert" type="vector3">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise3d name="N_noise3d" type="vector3">
      <input name="amplitude" type="vector3" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="position" type="vector3" interfacename="position" />
    </noise3d>
    <output name="out" type="vector3" nodename="N_noise3d" />
  </nodegraph>
  <nodegraph name="NG_noise3d_vector4FA" nodedef="ND_noise3d_vector4FA">
    <convert name="N_convert" type="vector4">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <noise3d name="N_noise3d" type="vector4">
      <input name="amplitude" type="vector4" nodename="N_convert" />
      <input name="pivot" type="float" interfacename="pivot" />
      <input name="position" type="vector3" interfacename="position" />
    </noise3d>
    <output name="out" type="vector4" nodename="N_noise3d" />
  </nodegraph>

  <!--
    Node: <fractal2d>
  -->
  <nodegraph name="NG_fractal2d_color3" nodedef="ND_fractal2d_color3">
    <fractal2d name="N_fractal2d" type="vector3">
      <input name="amplitude" type="vector3" interfacename="amplitude" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </fractal2d>
    <convert name="N_convert" type="color3">
      <input name="in" type="vector3" nodename="N_fractal2d" />
    </convert>
    <output name="out" type="color3" nodename="N_convert" />
  </nodegraph>
  <nodegraph name="NG_fractal2d_color4" nodedef="ND_fractal2d_color4">
    <fractal2d name="N_fractal2d" type="vector4">
      <input name="amplitude" type="vector4" interfacename="amplitude" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </fractal2d>
    <convert name="N_convert" type="color4">
      <input name="in" type="vector4" nodename="N_fractal2d" />
    </convert>
    <output name="out" type="color4" nodename="N_convert" />
  </nodegraph>
  <nodegraph name="NG_fractal2d_color3FA" nodedef="ND_fractal2d_color3FA">
    <convert name="N_convert" type="vector3">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal2d name="N_fractal2d" type="color3">
      <input name="amplitude" type="vector3" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </fractal2d>
    <output name="out" type="color3" nodename="N_fractal2d" />
  </nodegraph>
  <nodegraph name="NG_fractal2d_color4FA" nodedef="ND_fractal2d_color4FA">
    <convert name="N_convert" type="vector4">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal2d name="N_fractal2d" type="color4">
      <input name="amplitude" type="vector4" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </fractal2d>
    <output name="out" type="color4" nodename="N_fractal2d" />
  </nodegraph>
  <nodegraph name="NG_fractal2d_vector2FA" nodedef="ND_fractal2d_vector2FA">
    <convert name="N_convert" type="vector2">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal2d name="N_fractal2d" type="vector2">
      <input name="amplitude" type="vector2" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </fractal2d>
    <output name="out" type="vector2" nodename="N_fractal2d" />
  </nodegraph>
  <nodegraph name="NG_fractal2d_vector3FA" nodedef="ND_fractal2d_vector3FA">
    <convert name="N_convert" type="vector3">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal2d name="N_fractal2d" type="vector3">
      <input name="amplitude" type="vector3" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </fractal2d>
    <output name="out" type="vector3" nodename="N_fractal2d" />
  </nodegraph>
  <nodegraph name="NG_fractal2d_vector4FA" nodedef="ND_fractal2d_vector4FA">
    <convert name="N_convert" type="vector4">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal2d name="N_fractal2d" type="vector4">
      <input name="amplitude" type="vector4" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
    </fractal2d>
    <output name="out" type="vector4" nodename="N_fractal2d" />
  </nodegraph>

  <!--
    Node: <fractal3d>
  -->
  <nodegraph name="NG_fractal3d_color3" nodedef="ND_fractal3d_color3">
    <fractal3d name="N_fractal3d" type="vector3">
      <input name="amplitude" type="vector3" interfacename="amplitude" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" interfacename="position" />
    </fractal3d>
    <convert name="N_convert" type="color3">
      <input name="in" type="vector3" nodename="N_fractal3d" />
    </convert>
    <output name="out" type="color3" nodename="N_convert" />
  </nodegraph>
  <nodegraph name="NG_fractal3d_color4" nodedef="ND_fractal3d_color4">
    <fractal3d name="N_fractal3d" type="vector4">
      <input name="amplitude" type="vector4" interfacename="amplitude" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" interfacename="position" />
    </fractal3d>
    <convert name="N_convert" type="color4">
      <input name="in" type="vector4" nodename="N_fractal3d" />
    </convert>
    <output name="out" type="color4" nodename="N_convert" />
  </nodegraph>
  <nodegraph name="NG_fractal3d_color3FA" nodedef="ND_fractal3d_color3FA">
    <convert name="N_convert" type="vector3">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal3d name="N_fractal3d" type="color3">
      <input name="amplitude" type="vector3" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" interfacename="position" />
    </fractal3d>
    <output name="out" type="color3" nodename="N_fractal3d" />
  </nodegraph>
  <nodegraph name="NG_fractal3d_color4FA" nodedef="ND_fractal3d_color4FA">
    <convert name="N_convert" type="vector4">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal3d name="N_fractal3d" type="color4">
      <input name="amplitude" type="vector4" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" interfacename="position" />
    </fractal3d>
    <output name="out" type="color4" nodename="N_fractal3d" />
  </nodegraph>
  <nodegraph name="NG_fractal3d_vector2FA" nodedef="ND_fractal3d_vector2FA">
    <convert name="N_convert" type="vector2">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal3d name="N_fractal3d" type="vector2">
      <input name="amplitude" type="vector2" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" interfacename="position" />
    </fractal3d>
    <output name="out" type="vector2" nodename="N_fractal3d" />
  </nodegraph>
  <nodegraph name="NG_fractal3d_vector3FA" nodedef="ND_fractal3d_vector3FA">
    <convert name="N_convert" type="vector3">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal3d name="N_fractal3d" type="vector3">
      <input name="amplitude" type="vector3" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" interfacename="position" />
    </fractal3d>
    <output name="out" type="vector3" nodename="N_fractal3d" />
  </nodegraph>
  <nodegraph name="NG_fractal3d_vector4FA" nodedef="ND_fractal3d_vector4FA">
    <convert name="N_convert" type="vector4">
      <input name="in" type="float" interfacename="amplitude" />
    </convert>
    <fractal3d name="N_fractal3d" type="vector4">
      <input name="amplitude" type="vector4" nodename="N_convert" />
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" interfacename="position" />
    </fractal3d>
    <output name="out" type="vector4" nodename="N_fractal3d" />
  </nodegraph>

  <!--
    <unifiednoise2d>
    Combined 2d noises for artists.
  -->
  <nodegraph name="NG_unifiednoise2d_float" nodedef="ND_unifiednoise2d_float">
    <range name="N_range" type="float">
      <input name="in" type="float" nodename="N_switch_type" />
      <input name="outlow" type="float" interfacename="outmin" />
      <input name="outhigh" type="float" interfacename="outmax" />
      <input name="doclamp" type="boolean" interfacename="clampoutput" />
      <input name="inlow" type="float" value="0" />
      <input name="inhigh" type="float" value="1" />
    </range>
    <switch name="N_switch_type" type="float">
      <input name="in1" type="float" nodename="N_perlin_noise2d" />
      <input name="in2" type="float" nodename="N_cellnoise2d" />
      <input name="in3" type="float" nodename="N_worleynoise2d" />
      <input name="in4" type="float" nodename="N_fractal3d" />
      <input name="which" type="integer" interfacename="type" />
    </switch>
    <noise2d name="N_perlin_noise2d" type="float">
      <input name="texcoord" type="vector2" nodename="N_apply_cell_jitter" />
      <input name="amplitude" type="float" value="0.5" />
      <input name="pivot" type="float" value="0.5" />
    </noise2d>
    <cellnoise2d name="N_cellnoise2d" type="float">
      <input name="texcoord" type="vector2" nodename="N_apply_cell_jitter" />
    </cellnoise2d>
    <worleynoise2d name="N_worleynoise2d" type="float">
      <input name="texcoord" type="vector2" nodename="N_apply_offset" />
      <input name="jitter" type="float" interfacename="jitter" />
      <input name="style" type="integer" interfacename="style" />
    </worleynoise2d>
    <fractal3d name="N_fractal3d" type="float">
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" nodename="N_combine_with_jitter" />
      <input name="amplitude" type="float" value="1" />
    </fractal3d>
    <rotate2d name="N_apply_cell_jitter" type="vector2">
      <input name="in" type="vector2" nodename="N_apply_offset" />
      <input name="amount" type="float" nodename="N_cell_jitter_mult" />
    </rotate2d>
    <add name="N_apply_offset" type="vector2">
      <input name="in1" type="vector2" nodename="N_apply_freq" />
      <input name="in2" type="vector2" interfacename="offset" />
    </add>
    <combine3 name="N_combine_with_jitter" type="vector3">
      <input name="in1" type="float" nodename="N_separate" output="outx" />
      <input name="in2" type="float" nodename="N_separate" output="outy" />
      <input name="in3" type="float" nodename="N_cell_jitter_mult" />
    </combine3>
    <multiply name="N_cell_jitter_mult" type="float">
      <input name="in1" type="float" nodename="N_jitter_minus_1" />
      <input name="in2" type="float" value="90000" />
    </multiply>
    <multiply name="N_apply_freq" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="freq" />
    </multiply>
    <separate2 name="N_separate" type="multioutput">
      <input name="in" type="vector2" nodename="N_apply_offset" />
    </separate2>
    <subtract name="N_jitter_minus_1" type="float">
      <input name="in1" type="float" interfacename="jitter" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <output name="out" type="float" nodename="N_range" />
  </nodegraph>

  <!--
    Node: <unifiednoise3d>
    Combined 3d noises for artists.
  -->
  <nodegraph name="NG_unifiednoise3d_float" nodedef="ND_unifiednoise3d_float">
    <range name="N_range" type="float">
      <input name="in" type="float" nodename="N_switch_type" />
      <input name="outlow" type="float" interfacename="outmin" />
      <input name="outhigh" type="float" interfacename="outmax" />
      <input name="doclamp" type="boolean" interfacename="clampoutput" />
      <input name="inlow" type="float" value="0" />
      <input name="inhigh" type="float" value="1" />
    </range>
    <switch name="N_switch_type" type="float">
      <input name="in1" type="float" nodename="N_perlin_noise3d" />
      <input name="in2" type="float" nodename="N_cellnoise3d" />
      <input name="in3" type="float" nodename="N_worleynoise3d" />
      <input name="in4" type="float" nodename="N_fractal3d" />
      <input name="which" type="integer" interfacename="type" />
    </switch>
    <noise3d name="N_perlin_noise3d" type="float">
      <input name="position" type="vector3" nodename="N_apply_cell_jitter" />
      <input name="amplitude" type="float" value="0.5" />
      <input name="pivot" type="float" value="0.5" />
    </noise3d>
    <cellnoise3d name="N_cellnoise3d" type="float">
      <input name="position" type="vector3" nodename="N_apply_cell_jitter" />
    </cellnoise3d>
    <worleynoise3d name="N_worleynoise3d" type="float">
      <input name="position" type="vector3" nodename="N_apply_offset" />
      <input name="jitter" type="float" interfacename="jitter" />
      <input name="style" type="integer" interfacename="style" />
    </worleynoise3d>
    <fractal3d name="N_fractal3d" type="float">
      <input name="octaves" type="integer" interfacename="octaves" />
      <input name="lacunarity" type="float" interfacename="lacunarity" />
      <input name="diminish" type="float" interfacename="diminish" />
      <input name="position" type="vector3" nodename="N_apply_cell_jitter" />
      <input name="amplitude" type="float" value="1" />
    </fractal3d>
    <rotate3d name="N_apply_cell_jitter" type="vector3">
      <input name="in" type="vector3" nodename="N_apply_offset" />
      <input name="amount" type="float" nodename="N_cell_jitter_mult" />
      <input name="axis" type="vector3" value="0.1, 1, 0" />
    </rotate3d>
    <add name="N_apply_offset" type="vector3">
      <input name="in1" type="vector3" nodename="N_apply_freq" />
      <input name="in2" type="vector3" interfacename="offset" />
    </add>
    <multiply name="N_cell_jitter_mult" type="float">
      <input name="in1" type="float" nodename="N_jitter_minus_one" />
      <input name="in2" type="float" value="90000" />
    </multiply>
    <multiply name="N_apply_freq" type="vector3">
      <input name="in1" type="vector3" interfacename="position" />
      <input name="in2" type="vector3" interfacename="freq" />
    </multiply>
    <subtract name="N_jitter_minus_one" type="float">
      <input name="in1" type="float" interfacename="jitter" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <output name="out" type="float" nodename="N_range" />
  </nodegraph>

  <!--
    Node: <randomfloat>
    Produces a randomized float, based on an 'input' signal and 'seed' value.
  -->
  <nodegraph name="NG_randomfloat_float" nodedef="ND_randomfloat_float">
    <convert name="N_convertSeed1" type="float">
      <input name="in" type="integer" interfacename="seed" />
    </convert>
    <multiply name="N_scaleInput" type="float">
      <input name="in1" type="float" interfacename="in" />
      <input name="in2" type="float" value="4096" />
    </multiply>
    <combine2 name="N_combine2" type="vector2">
      <input name="in1" type="float" nodename="N_scaleInput" />
      <input name="in2" type="float" nodename="N_convertSeed1" />
    </combine2>
    <cellnoise2d name="N_cellnoise1" type="float">
      <input name="texcoord" type="vector2" nodename="N_combine2" />
    </cellnoise2d>
    <range name="N_remapRange" type="float">
      <input name="in" type="float" nodename="N_cellnoise1" />
      <input name="outlow" type="float" interfacename="min" />
      <input name="outhigh" type="float" interfacename="max" />
      <input name="doclamp" type="boolean" value="true" />
    </range>
    <output name="out" type="float" nodename="N_remapRange" />
  </nodegraph>
  <nodegraph name="NG_randomfloat_integer" nodedef="ND_randomfloat_integer">
    <convert name="N_convertInput1" type="float">
      <input name="in" type="integer" interfacename="in" />
    </convert>
    <convert name="N_convertSeed1" type="float">
      <input name="in" type="integer" interfacename="seed" />
    </convert>
    <combine2 name="N_combine2" type="vector2">
      <input name="in1" type="float" nodename="N_convertInput1" />
      <input name="in2" type="float" nodename="N_convertSeed1" />
    </combine2>
    <cellnoise2d name="N_cellnoise1" type="float">
      <input name="texcoord" type="vector2" nodename="N_combine2" />
    </cellnoise2d>
    <range name="N_remapRange" type="float">
      <input name="in" type="float" nodename="N_cellnoise1" />
      <input name="outlow" type="float" interfacename="min" />
      <input name="outhigh" type="float" interfacename="max" />
      <input name="doclamp" type="boolean" value="true" />
    </range>
    <output name="out" type="float" nodename="N_remapRange" />
  </nodegraph>

  <!--
    Node: <randomcolor>
    Produces a randomized color, based on an input signal and seed value.
  -->
  <nodegraph name="NG_randomcolor_float" nodedef="ND_randomcolor_float">
    <convert name="N_convertSeed1" type="float">
      <input name="in" type="integer" interfacename="seed" />
    </convert>
    <add name="N_offset_hue" type="float">
      <input name="in1" type="float" nodename="N_convertSeed1" />
      <input name="in2" type="float" value="413.3" />
    </add>
    <add name="N_offset_saturation" type="float">
      <input name="in1" type="float" nodename="N_convertSeed1" />
      <input name="in2" type="float" value="1522.4" />
    </add>
    <add name="N_offset_brightness" type="float">
      <input name="in1" type="float" nodename="N_convertSeed1" />
      <input name="in2" type="float" value="1813.8" />
    </add>
    <ceil name="N_seed_hue" type="integer">
      <input name="in" type="float" nodename="N_offset_hue" />
    </ceil>
    <ceil name="N_seed_saturation" type="integer">
      <input name="in" type="float" nodename="N_offset_saturation" />
    </ceil>
    <ceil name="N_seed_brightness" type="integer">
      <input name="in" type="float" nodename="N_offset_brightness" />
    </ceil>
    <randomfloat name="N_rand_hue" type="float">
      <input name="in" type="float" interfacename="in" />
      <input name="seed" type="integer" nodename="N_seed_hue" />
    </randomfloat>
    <randomfloat name="N_rand_saturation" type="float">
      <input name="in" type="float" interfacename="in" />
      <input name="seed" type="integer" nodename="N_seed_saturation" />
    </randomfloat>
    <randomfloat name="N_rand_brightness" type="float">
      <input name="in" type="float" interfacename="in" />
      <input name="seed" type="integer" nodename="N_seed_brightness" />
    </randomfloat>
    <range name="N_range_hue" type="float">
      <input name="in" type="float" nodename="N_rand_hue" />
      <input name="outlow" type="float" interfacename="huelow" />
      <input name="outhigh" type="float" interfacename="huehigh" />
    </range>
    <range name="N_range_saturation" type="float">
      <input name="in" type="float" nodename="N_rand_saturation" />
      <input name="outlow" type="float" interfacename="saturationlow" />
      <input name="outhigh" type="float" interfacename="saturationhigh" />
    </range>
    <range name="N_range_brightness" type="float">
      <input name="in" type="float" nodename="N_rand_brightness" />
      <input name="outlow" type="float" interfacename="brightnesslow" />
      <input name="outhigh" type="float" interfacename="brightnesshigh" />
    </range>
    <combine3 name="N_combine_HSV" type="color3">
      <input name="in1" type="float" nodename="N_range_hue" />
      <input name="in2" type="float" nodename="N_range_saturation" />
      <input name="in3" type="float" nodename="N_range_brightness" />
    </combine3>
    <hsvtorgb name="N_HSV_to_RGB" type="color3">
      <input name="in" type="color3" nodename="N_combine_HSV" />
    </hsvtorgb>
    <output name="out" type="color3" nodename="N_HSV_to_RGB" />
  </nodegraph>
  <nodegraph name="NG_randomcolor_integer" nodedef="ND_randomcolor_integer">
    <convert name="N_convert1" type="float">
      <input name="in" type="integer" interfacename="in" />
    </convert>
    <randomcolor name="N_randomcolor1" type="color3">
      <input name="in" type="float" nodename="N_convert1" />
      <input name="huelow" type="float" interfacename="huelow" />
      <input name="huehigh" type="float" interfacename="huehigh" />
      <input name="saturationlow" type="float" interfacename="saturationlow" />
      <input name="saturationhigh" type="float" interfacename="saturationhigh" />
      <input name="brightnesslow" type="float" interfacename="brightnesslow" />
      <input name="brightnesshigh" type="float" interfacename="brightnesshigh" />
      <input name="seed" type="integer" interfacename="seed" />
    </randomcolor>
    <output name="out" type="color3" nodename="N_randomcolor1" />
  </nodegraph>

  <!--
    Node: <checkerboard>
    A 2D checkerboard pattern.
  -->
  <nodegraph name="NG_checkerboard_color3" nodedef="ND_checkerboard_color3">
    <multiply name="N_mtlxmult" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="N_mtlxsubtract" type="vector2">
      <input name="in1" type="vector2" nodename="N_mtlxmult" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <floor name="N_mtlxfloor" type="vector2">
      <input name="in" type="vector2" nodename="N_mtlxsubtract" />
    </floor>
    <dotproduct name="N_mtlxdotproduct" type="float">
      <input name="in1" type="vector2" nodename="N_mtlxfloor" />
      <input name="in2" type="vector2" value="1, 1" />
    </dotproduct>
    <modulo name="N_modulo" type="float">
      <input name="in1" type="float" nodename="N_mtlxdotproduct" />
      <input name="in2" type="float" value="2" />
    </modulo>
    <mix name="N_mtlxmix" type="color3">
      <input name="bg" type="color3" interfacename="color2" />
      <input name="fg" type="color3" interfacename="color1" />
      <input name="mix" type="float" nodename="N_modulo" />
    </mix>
    <output name="out" type="color3" nodename="N_mtlxmix" />
  </nodegraph>

  <!--
    Node: <line>
    Returns 1 if texcoord is at less than radius distance from a line segment defined by point1 and point2; otherwise returns 0.
    Segment ends will be rounded.
    Uses formulas from Inigo Quilez SDF samples (iquilezles.org)
  -->
  <nodegraph name="NG_line_float" nodedef="ND_line_float">
    <subtract name="delta" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="center" />
    </subtract>
    <subtract name="p_a" type="vector2">
      <input name="in1" type="vector2" nodename="delta" />
      <input name="in2" type="vector2" interfacename="point1" />
    </subtract>
    <subtract name="b_a" type="vector2">
      <input name="in1" type="vector2" interfacename="point2" />
      <input name="in2" type="vector2" interfacename="point1" />
    </subtract>
    <dotproduct name="dot_pa_ba" type="float">
      <input name="in1" type="vector2" nodename="p_a" />
      <input name="in2" type="vector2" nodename="b_a" />
    </dotproduct>
    <dotproduct name="dot_ba_ba" type="float">
      <input name="in1" type="vector2" nodename="b_a" />
      <input name="in2" type="vector2" nodename="b_a" />
    </dotproduct>
    <divide name="divide_dots" type="float">
      <input name="in1" type="float" nodename="dot_pa_ba" />
      <input name="in2" type="float" nodename="dot_ba_ba" />
    </divide>
    <clamp name="clamp" type="float">
      <input name="in" type="float" nodename="divide_dots" />
    </clamp>
    <multiply name="multiply_clamp_ba" type="vector2">
      <input name="in1" type="vector2" nodename="b_a" />
      <input name="in2" type="float" nodename="clamp" />
    </multiply>
    <distance name="distance" type="float">
      <input name="in1" type="vector2" nodename="p_a" />
      <input name="in2" type="vector2" nodename="multiply_clamp_ba" />
    </distance>
    <ifgreater name="dist_comp" type="float">
      <input name="value1" type="float" nodename="distance" />
      <input name="value2" type="float" interfacename="radius" />
      <input name="in1" type="float" value="0" />
      <input name="in2" type="float" value="1" />
    </ifgreater>
    <output name="out" type="float" nodename="dist_comp" />
  </nodegraph>

  <!--
    Node: <circle>
    Returns 1 if texcoord is inside a circle defined by center and radius; otherwise returns 0.
  -->
  <nodegraph name="NG_circle_float" nodedef="ND_circle_float">
    <subtract name="delta" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="center" />
    </subtract>
    <dotproduct name="dist_square" type="float">
      <input name="in1" type="vector2" nodename="delta" />
      <input name="in2" type="vector2" nodename="delta" />
    </dotproduct>
    <multiply name="rad_square" type="float">
      <input name="in1" type="float" interfacename="radius" />
      <input name="in2" type="float" interfacename="radius" />
    </multiply>
    <ifgreater name="dist_comp" type="float">
      <input name="value1" type="float" nodename="dist_square" />
      <input name="value2" type="float" nodename="rad_square" />
      <input name="in1" type="float" value="0" />
      <input name="in2" type="float" value="1" />
    </ifgreater>
    <output name="out" type="float" nodename="dist_comp" />
  </nodegraph>

  <!--
    Node: <cloverleaf>
    Returns 1 if texcoord is inside a cloverleaf shape inscribed by a circle defined by center and radius; otherwise returns 0.
  -->
  <nodegraph name="NG_cloverleaf_float" nodedef="ND_cloverleaf_float">
    <add name="sample_double" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="texcoord" />
    </add>
    <add name="center_double" type="vector2">
      <input name="in1" type="vector2" interfacename="center" />
      <input name="in2" type="vector2" interfacename="center" />
    </add>
    <add name="sample_add" type="vector2">
      <input name="in1" type="vector2" nodename="sample_double" />
      <input name="in2" type="float" interfacename="radius" />
    </add>
    <subtract name="sample_subtract" type="vector2">
      <input name="in1" type="vector2" nodename="sample_double" />
      <input name="in2" type="float" interfacename="radius" />
    </subtract>
    <separate2 name="sample_double_separate" type="multioutput">
      <input name="in" type="vector2" nodename="sample_double" />
    </separate2>
    <separate2 name="sample_add_separate" type="multioutput">
      <input name="in" type="vector2" nodename="sample_add" />
    </separate2>
    <separate2 name="sample_subtract_separate" type="multioutput">
      <input name="in" type="vector2" nodename="sample_subtract" />
    </separate2>
    <combine2 name="coord1" type="vector2">
      <input name="in1" type="float" nodename="sample_add_separate" output="outx" />
      <input name="in2" type="float" nodename="sample_double_separate" output="outy" />
    </combine2>
    <combine2 name="coord2" type="vector2">
      <input name="in1" type="float" nodename="sample_subtract_separate" output="outx" />
      <input name="in2" type="float" nodename="sample_double_separate" output="outy" />
    </combine2>
    <combine2 name="coord3" type="vector2">
      <input name="in1" type="float" nodename="sample_double_separate" output="outx" />
      <input name="in2" type="float" nodename="sample_subtract_separate" output="outy" />
    </combine2>
    <combine2 name="coord4" type="vector2">
      <input name="in1" type="float" nodename="sample_double_separate" output="outx" />
      <input name="in2" type="float" nodename="sample_add_separate" output="outy" />
    </combine2>
    <circle name="circle1" type="float">
      <input name="texcoord" type="vector2" nodename="coord1" />
      <input name="center" type="vector2" nodename="center_double" />
      <input name="radius" type="float" interfacename="radius" />
    </circle>
    <circle name="circle2" type="float">
      <input name="texcoord" type="vector2" nodename="coord2" />
      <input name="center" type="vector2" nodename="center_double" />
      <input name="radius" type="float" interfacename="radius" />
    </circle>
    <circle name="circle3" type="float">
      <input name="texcoord" type="vector2" nodename="coord3" />
      <input name="center" type="vector2" nodename="center_double" />
      <input name="radius" type="float" interfacename="radius" />
    </circle>
    <circle name="circle4" type="float">
      <input name="texcoord" type="vector2" nodename="coord4" />
      <input name="center" type="vector2" nodename="center_double" />
      <input name="radius" type="float" interfacename="radius" />
    </circle>
    <max name="max1" type="float">
      <input name="in1" type="float" nodename="circle1" />
      <input name="in2" type="float" nodename="circle2" />
    </max>
    <max name="max2" type="float">
      <input name="in1" type="float" nodename="circle3" />
      <input name="in2" type="float" nodename="circle4" />
    </max>
    <max name="max" type="float">
      <input name="in1" type="float" nodename="max1" />
      <input name="in2" type="float" nodename="max2" />
    </max>
    <output name="out" type="float" nodename="max" />
  </nodegraph>

  <!--
    Node: <hexagon>
    Returns 1 if texcoord is inside a hexagon shape inscribed by a circle defined by center and radius; otherwise returns 0.
    Uses formulas from Inigo Quilez SDF samples (iquilezles.org)
  -->
  <nodegraph name="NG_hexagon_float" nodedef="ND_hexagon_float">
    <constant name="k" type="vector3">
      <input name="value" type="vector3" value="-0.866025, 0.5, 0.57735" />
    </constant>
    <multiply name="minus_k" type="vector3">
      <input name="in1" type="vector3" nodename="k" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <separate3 name="k_separate" type="multioutput">
      <input name="in" type="vector3" nodename="k" />
    </separate3>
    <separate3 name="minus_k_separate" type="multioutput">
      <input name="in" type="vector3" nodename="minus_k" />
    </separate3>
    <subtract name="delta" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="center" />
    </subtract>
    <absval name="delta_abs" type="vector2">
      <input name="in" type="vector2" nodename="delta" />
    </absval>
    <separate2 name="delta_abs_separate" type="multioutput">
      <input name="in" type="vector2" nodename="delta_abs" />
    </separate2>
    <combine2 name="p" type="vector2">
      <input name="in1" type="float" nodename="delta_abs_separate" output="outy" />
      <input name="in2" type="float" nodename="delta_abs_separate" output="outx" />
    </combine2>
    <multiply name="kz_r1" type="float">
      <input name="in1" type="float" nodename="k_separate" output="outz" />
      <input name="in2" type="float" interfacename="radius" />
    </multiply>
    <multiply name="minus_kz_r" type="float">
      <input name="in1" type="float" nodename="minus_k_separate" output="outz" />
      <input name="in2" type="float" interfacename="radius" />
    </multiply>
    <combine2 name="combine_mkx_ky" type="vector2">
      <input name="in1" type="float" nodename="minus_k_separate" output="outx" />
      <input name="in2" type="float" nodename="k_separate" output="outy" />
    </combine2>
    <combine2 name="kxy" type="vector2">
      <input name="in1" type="float" nodename="k_separate" output="outx" />
      <input name="in2" type="float" nodename="k_separate" output="outy" />
    </combine2>
    <dotproduct name="dot_kxy_p" type="float">
      <input name="in1" type="vector2" nodename="kxy" />
      <input name="in2" type="vector2" nodename="p" />
    </dotproduct>
    <dotproduct name="dot_kxy_p1" type="float">
      <input name="in1" type="vector2" nodename="combine_mkx_ky" />
      <input name="in2" type="vector2" nodename="new_p1" />
    </dotproduct>
    <min name="min_dotkxyp_p" type="float">
      <input name="in1" type="float" nodename="dot_kxy_p" />
    </min>
    <min name="min_0" type="float">
      <input name="in1" type="float" nodename="dot_kxy_p1" />
    </min>
    <multiply name="multiply_kxy_min" type="vector2">
      <input name="in1" type="vector2" nodename="kxy" />
      <input name="in2" type="float" nodename="min_dotkxyp_p" />
    </multiply>
    <multiply name="multiply2_1" type="vector2">
      <input name="in1" type="vector2" nodename="multiply_kxy_min" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <multiply name="multiply_min_comb" type="vector2">
      <input name="in1" type="vector2" nodename="combine_mkx_ky" />
      <input name="in2" type="float" nodename="min_0" />
    </multiply>
    <multiply name="multiply2_2" type="vector2">
      <input name="in1" type="vector2" nodename="multiply_min_comb" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <extract name="new_p2_x" type="float">
      <input name="in" type="vector2" nodename="new_p2" />
      <input name="index" type="integer" value="0" />
    </extract>
    <clamp name="clamp" type="float">
      <input name="in" type="float" nodename="new_p2_x" />
      <input name="low" type="float" nodename="minus_kz_r" />
      <input name="high" type="float" nodename="kz_r1" />
    </clamp>
    <combine2 name="combine_clamp_rad" type="vector2">
      <input name="in1" type="float" nodename="clamp" />
      <input name="in2" type="float" interfacename="radius" />
    </combine2>
    <subtract name="new_p1" type="vector2">
      <input name="in1" type="vector2" nodename="p" />
      <input name="in2" type="vector2" nodename="multiply2_1" />
    </subtract>
    <subtract name="new_p2" type="vector2">
      <input name="in1" type="vector2" nodename="new_p1" />
      <input name="in2" type="vector2" nodename="multiply2_2" />
    </subtract>
    <subtract name="new_p3" type="vector2">
      <input name="in1" type="vector2" nodename="new_p2" />
      <input name="in2" type="vector2" nodename="combine_clamp_rad" />
    </subtract>
    <dotproduct name="p3_sum" type="float">
      <input name="in1" type="vector2" nodename="new_p3" />
      <input name="in2" type="vector2" value="1, 1" />
    </dotproduct>
    <sqrt name="p3_sqrt" type="float">
      <input name="in" type="float" nodename="p3_sum" />
    </sqrt>
    <ifgreater name="ifgreater_p3" type="float">
      <input name="value1" type="float" nodename="p3_sqrt" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="float" value="0" />
      <input name="in2" type="float" value="1" />
    </ifgreater>
    <output name="out" type="float" nodename="ifgreater_p3" />
  </nodegraph>

  <!--
    Node: <grid>
    Creates a grid pattern with the given tiling, offset, and line thickness.
    Pattern can be regular or staggered.
  -->
  <nodegraph name="NG_grid_color3" nodedef="ND_grid_color3">
    <multiply name="texcoord_scale" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="texcoord_bias" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord_scale" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <separate2 name="texcoord_bias_separate" type="multioutput">
      <input name="in" type="vector2" nodename="texcoord_bias" />
    </separate2>
    <subtract name="thick_to_size" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="thickness" />
    </subtract>
    <modulo name="mod_Y" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
    </modulo>
    <modulo name="mod_Y_row" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
      <input name="in2" type="float" value="2" />
    </modulo>
    <multiply name="mody_2" type="float">
      <input name="in1" type="float" nodename="mod_Y" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <ifgreater name="alt_rows_shift" type="float">
      <input name="value1" type="float" nodename="mod_Y_row" />
      <input name="value2" type="float" value="1" />
      <input name="in1" type="float" value="0.5" />
    </ifgreater>
    <add name="shift_X" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outx" />
      <input name="in2" type="float" nodename="alt_rows_shift" />
    </add>
    <ifequal name="stagger_selection" type="float">
      <input name="value1" type="boolean" interfacename="staggered" />
      <input name="value2" type="boolean" value="true" />
      <input name="in1" type="float" nodename="shift_X" />
      <input name="in2" type="float" nodename="texcoord_bias_separate" output="outx" />
    </ifequal>
    <modulo name="mod_X" type="float">
      <input name="in1" type="float" nodename="stagger_selection" />
    </modulo>
    <multiply name="modx_2" type="float">
      <input name="in1" type="float" nodename="mod_X" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <subtract name="subX_1" type="float">
      <input name="in1" type="float" nodename="modx_2" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <subtract name="subY_1" type="float">
      <input name="in1" type="float" nodename="mody_2" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <absval name="abs_X" type="float">
      <input name="in" type="float" nodename="subX_1" />
    </absval>
    <absval name="abs_Y" type="float">
      <input name="in" type="float" nodename="subY_1" />
    </absval>
    <ifgreater name="X_detect" type="float">
      <input name="value1" type="float" nodename="abs_X" />
      <input name="value2" type="float" nodename="thick_to_size" />
      <input name="in1" type="float" value="0" />
      <input name="in2" type="float" value="1" />
    </ifgreater>
    <ifgreater name="Y_detect" type="float">
      <input name="value1" type="float" nodename="abs_Y" />
      <input name="value2" type="float" nodename="thick_to_size" />
      <input name="in1" type="float" value="0" />
      <input name="in2" type="float" value="1" />
    </ifgreater>
    <min name="min" type="float">
      <input name="in1" type="float" nodename="X_detect" />
      <input name="in2" type="float" nodename="Y_detect" />
    </min>
    <subtract name="inv_result" type="float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" nodename="min" />
    </subtract>
    <convert name="to_rgb" type="color3">
      <input name="in" type="float" nodename="inv_result" />
    </convert>
    <output name="out" type="color3" nodename="to_rgb" />
  </nodegraph>

  <!--
    Node: <crosshatch>
    Creates a crosshatch pattern with the given tiling, offset, and line thickness.
    Pattern can be regular or staggered.
  -->
  <nodegraph name="NG_crosshatch_color3" nodedef="ND_crosshatch_color3">
    <multiply name="texcoord_scale" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="texcoord_bias" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord_scale" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <separate2 name="texcoord_bias_separate" type="multioutput">
      <input name="in" type="vector2" nodename="texcoord_bias" />
    </separate2>
    <modulo name="mod_Y" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
    </modulo>
    <modulo name="mod_Y_row" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
      <input name="in2" type="float" value="2" />
    </modulo>
    <multiply name="mody_2" type="float">
      <input name="in1" type="float" nodename="mod_Y" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <ifgreater name="alt_rows_shift" type="float">
      <input name="value1" type="float" nodename="mod_Y_row" />
      <input name="value2" type="float" value="1" />
      <input name="in1" type="float" value="0.5" />
    </ifgreater>
    <add name="shift_X" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outx" />
      <input name="in2" type="float" nodename="alt_rows_shift" />
    </add>
    <ifequal name="stagger_selection" type="float">
      <input name="value1" type="boolean" interfacename="staggered" />
      <input name="value2" type="boolean" value="true" />
      <input name="in1" type="float" nodename="shift_X" />
      <input name="in2" type="float" nodename="texcoord_bias_separate" output="outx" />
    </ifequal>
    <modulo name="mod_X" type="float">
      <input name="in1" type="float" nodename="stagger_selection" />
    </modulo>
    <multiply name="modx_2" type="float">
      <input name="in1" type="float" nodename="mod_X" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <subtract name="subX_1" type="float">
      <input name="in1" type="float" nodename="modx_2" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <subtract name="subY_1" type="float">
      <input name="in1" type="float" nodename="mody_2" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <combine2 name="sample_vec" type="vector2">
      <input name="in1" type="float" nodename="subX_1" />
      <input name="in2" type="float" nodename="subY_1" />
    </combine2>
    <line name="line_diag1" type="float">
      <input name="texcoord" type="vector2" nodename="sample_vec" />
      <input name="radius" type="float" interfacename="thickness" />
      <input name="point1" type="vector2" value="1, 1" />
      <input name="point2" type="vector2" value="-1, -1" />
    </line>
    <line name="line_diag2" type="float">
      <input name="texcoord" type="vector2" nodename="sample_vec" />
      <input name="radius" type="float" interfacename="thickness" />
      <input name="point1" type="vector2" value="-1, 1" />
      <input name="point2" type="vector2" value="1, -1" />
    </line>
    <max name="composite_diags" type="float">
      <input name="in1" type="float" nodename="line_diag1" />
      <input name="in2" type="float" nodename="line_diag2" />
    </max>
    <max name="max" type="float">
      <input name="in1" type="float" nodename="composite_diags" />
      <input name="in2" type="float" nodename="composite_diags" />
    </max>
    <convert name="to_rgb" type="color3">
      <input name="in" type="float" nodename="max" />
    </convert>
    <output name="out" type="color3" nodename="to_rgb" />
  </nodegraph>

  <!--
    Node: <tiledcircles>
    Creates a black and white pattern of circles with a defined spacing and size (diameter).
    Pattern can be regular or staggered.
  -->
  <nodegraph name="NG_tiledcircles_color3" nodedef="ND_tiledcircles_color3">
    <multiply name="texcoord_scale" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="texcoord_bias" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord_scale" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <separate2 name="texcoord_bias_separate" type="multioutput">
      <input name="in" type="vector2" nodename="texcoord_bias" />
    </separate2>
    <modulo name="mod_texcoord" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord_bias" />
    </modulo>
    <multiply name="mod_texcoord_2" type="vector2">
      <input name="in1" type="vector2" nodename="mod_texcoord" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <subtract name="recenter" type="vector2">
      <input name="in1" type="vector2" nodename="mod_texcoord_2" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <modulo name="stagg_Y" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
      <input name="in2" type="float" value="1.73205" />
    </modulo>
    <ifgreater name="delta_X" type="float">
      <input name="value1" type="float" nodename="stagg_Y" />
      <input name="value2" type="float" value="0.866025" />
      <input name="in1" type="float" value="0.5" />
    </ifgreater>
    <add name="shift_X" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outx" />
      <input name="in2" type="float" nodename="delta_X" />
    </add>
    <modulo name="mod_X_1" type="float">
      <input name="in1" type="float" nodename="shift_X" />
    </modulo>
    <modulo name="mod_Y_1" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
      <input name="in2" type="float" value="0.866025" />
    </modulo>
    <subtract name="coord_adj_1" type="float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" nodename="mod_X_1" />
    </subtract>
    <subtract name="coord_adj_2" type="float">
      <input name="in1" type="float" nodename="mod_X_1" />
      <input name="in2" type="float" value="0.5" />
    </subtract>
    <subtract name="coord_adj_3" type="float">
      <input name="in1" type="float" value="0.866025" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </subtract>
    <combine2 name="coord_circ1" type="vector2">
      <input name="in1" type="float" nodename="mod_X_1" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </combine2>
    <combine2 name="coord_circ2" type="vector2">
      <input name="in1" type="float" nodename="coord_adj_1" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </combine2>
    <combine2 name="coord_circ3" type="vector2">
      <input name="in1" type="float" nodename="coord_adj_2" />
      <input name="in2" type="float" nodename="coord_adj_3" />
    </combine2>
    <divide name="scale_half" type="float">
      <input name="in1" type="float" interfacename="size" />
      <input name="in2" type="float" value="2" />
    </divide>
    <circle name="circle_stagg1" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ1" />
      <input name="radius" type="float" nodename="scale_half" />
    </circle>
    <circle name="circle_stagg2" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ2" />
      <input name="radius" type="float" nodename="scale_half" />
    </circle>
    <circle name="circle_stagg3" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ3" />
      <input name="radius" type="float" nodename="scale_half" />
    </circle>
    <max name="max1" type="float">
      <input name="in1" type="float" nodename="circle_stagg1" />
      <input name="in2" type="float" nodename="circle_stagg2" />
    </max>
    <max name="max" type="float">
      <input name="in1" type="float" nodename="max1" />
      <input name="in2" type="float" nodename="circle_stagg3" />
    </max>
    <circle name="circle_regular" type="float">
      <input name="texcoord" type="vector2" nodename="recenter" />
      <input name="radius" type="float" interfacename="size" />
    </circle>
    <ifequal name="pattern_selection" type="float">
      <input name="value1" type="boolean" interfacename="staggered" />
      <input name="value2" type="boolean" value="true" />
      <input name="in1" type="float" nodename="max" />
      <input name="in2" type="float" nodename="circle_regular" />
    </ifequal>
    <convert name="to_rgb" type="color3">
      <input name="in" type="float" nodename="pattern_selection" />
    </convert>
    <output name="out" type="color3" nodename="to_rgb" />
  </nodegraph>

  <!--
    Node: <tiledcloverleafs>
    Creates a black and white pattern of cloverleafs with a defined spacing and size (diameter of the circles circumscribing the shape).
    Pattern can be regular or staggered.
  -->
  <nodegraph name="NG_tiledcloverleafs_color3" nodedef="ND_tiledcloverleafs_color3">
    <multiply name="texcoord_scale" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="texcoord_bias" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord_scale" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <separate2 name="texcoord_bias_separate" type="multioutput">
      <input name="in" type="vector2" nodename="texcoord_bias" />
    </separate2>
    <modulo name="mod_texcoord" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord_bias" />
    </modulo>
    <multiply name="mod_texcoord_2" type="vector2">
      <input name="in1" type="vector2" nodename="mod_texcoord" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <subtract name="recenter" type="vector2">
      <input name="in1" type="vector2" nodename="mod_texcoord_2" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <modulo name="stagg_Y" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
      <input name="in2" type="float" value="1" />
    </modulo>
    <ifgreater name="delta_X" type="float">
      <input name="value1" type="float" nodename="stagg_Y" />
      <input name="value2" type="float" value="0.5" />
      <input name="in1" type="float" value="0.5" />
    </ifgreater>
    <add name="shift_X" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outx" />
      <input name="in2" type="float" nodename="delta_X" />
    </add>
    <modulo name="mod_X_1" type="float">
      <input name="in1" type="float" nodename="shift_X" />
    </modulo>
    <modulo name="mod_Y_1" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
      <input name="in2" type="float" value="0.5" />
    </modulo>
    <subtract name="coord_adj_1" type="float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" nodename="mod_X_1" />
    </subtract>
    <subtract name="coord_adj_2" type="float">
      <input name="in1" type="float" nodename="mod_X_1" />
      <input name="in2" type="float" value="0.5" />
    </subtract>
    <subtract name="coord_adj_3" type="float">
      <input name="in1" type="float" value="0.5" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </subtract>
    <combine2 name="coord_circ1" type="vector2">
      <input name="in1" type="float" nodename="mod_X_1" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </combine2>
    <combine2 name="coord_circ2" type="vector2">
      <input name="in1" type="float" nodename="coord_adj_1" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </combine2>
    <combine2 name="coord_circ3" type="vector2">
      <input name="in1" type="float" nodename="coord_adj_2" />
      <input name="in2" type="float" nodename="coord_adj_3" />
    </combine2>
    <divide name="scale_half" type="float">
      <input name="in1" type="float" interfacename="size" />
      <input name="in2" type="float" value="2" />
    </divide>
    <cloverleaf name="cloverleaf_stagg1" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ1" />
      <input name="radius" type="float" nodename="scale_half" />
    </cloverleaf>
    <cloverleaf name="cloverleaf_stagg2" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ2" />
      <input name="radius" type="float" nodename="scale_half" />
    </cloverleaf>
    <cloverleaf name="cloverleaf_stagg3" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ3" />
      <input name="radius" type="float" nodename="scale_half" />
    </cloverleaf>
    <max name="max1" type="float">
      <input name="in1" type="float" nodename="cloverleaf_stagg1" />
      <input name="in2" type="float" nodename="cloverleaf_stagg2" />
    </max>
    <max name="max" type="float">
      <input name="in1" type="float" nodename="max1" />
      <input name="in2" type="float" nodename="cloverleaf_stagg3" />
    </max>
    <cloverleaf name="cloverleaf_regular" type="float">
      <input name="texcoord" type="vector2" nodename="recenter" />
      <input name="radius" type="float" interfacename="size" />
    </cloverleaf>
    <ifequal name="pattern_selection" type="float">
      <input name="value1" type="boolean" interfacename="staggered" />
      <input name="value2" type="boolean" value="true" />
      <input name="in1" type="float" nodename="max" />
      <input name="in2" type="float" nodename="cloverleaf_regular" />
    </ifequal>
    <convert name="to_rgb" type="color3">
      <input name="in" type="float" nodename="pattern_selection" />
    </convert>
    <output name="out" type="color3" nodename="to_rgb" />
  </nodegraph>

  <!--
    Node: <tiledhexagons>
    Creates a black and white pattern of hexagons with a defined spacing and size (diameter of the circles circumscribing the shape).
    Pattern can be regular or staggered.
  -->
  <nodegraph name="NG_tiledhexagons_color3" nodedef="ND_tiledhexagons_color3">
    <multiply name="texcoord_scale" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="uvtiling" />
    </multiply>
    <subtract name="texcoord_bias" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord_scale" />
      <input name="in2" type="vector2" interfacename="uvoffset" />
    </subtract>
    <separate2 name="texcoord_bias_separate" type="multioutput">
      <input name="in" type="vector2" nodename="texcoord_bias" />
    </separate2>
    <modulo name="mod_texcoord" type="vector2">
      <input name="in1" type="vector2" nodename="texcoord_bias" />
    </modulo>
    <multiply name="mod_texcoord_2" type="vector2">
      <input name="in1" type="vector2" nodename="mod_texcoord" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <subtract name="recenter" type="vector2">
      <input name="in1" type="vector2" nodename="mod_texcoord_2" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <modulo name="stagg_Y" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
      <input name="in2" type="float" value="1.73205" />
    </modulo>
    <ifgreater name="delta_X" type="float">
      <input name="value1" type="float" nodename="stagg_Y" />
      <input name="value2" type="float" value="0.866025" />
      <input name="in1" type="float" value="0.5" />
    </ifgreater>
    <add name="shift_X" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outx" />
      <input name="in2" type="float" nodename="delta_X" />
    </add>
    <modulo name="mod_X_1" type="float">
      <input name="in1" type="float" nodename="shift_X" />
    </modulo>
    <modulo name="mod_Y_1" type="float">
      <input name="in1" type="float" nodename="texcoord_bias_separate" output="outy" />
      <input name="in2" type="float" value="0.866025" />
    </modulo>
    <subtract name="coord_adj_1" type="float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" nodename="mod_X_1" />
    </subtract>
    <subtract name="coord_adj_2" type="float">
      <input name="in1" type="float" nodename="mod_X_1" />
      <input name="in2" type="float" value="0.5" />
    </subtract>
    <subtract name="coord_adj_3" type="float">
      <input name="in1" type="float" value="0.866025" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </subtract>
    <combine2 name="coord_circ1" type="vector2">
      <input name="in1" type="float" nodename="mod_X_1" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </combine2>
    <combine2 name="coord_circ2" type="vector2">
      <input name="in1" type="float" nodename="coord_adj_1" />
      <input name="in2" type="float" nodename="mod_Y_1" />
    </combine2>
    <combine2 name="coord_circ3" type="vector2">
      <input name="in1" type="float" nodename="coord_adj_2" />
      <input name="in2" type="float" nodename="coord_adj_3" />
    </combine2>
    <divide name="scale_half" type="float">
      <input name="in1" type="float" interfacename="size" />
      <input name="in2" type="float" value="2" />
    </divide>
    <hexagon name="hexagon_stagg1" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ1" />
      <input name="radius" type="float" nodename="scale_half" />
    </hexagon>
    <hexagon name="hexagon_stagg2" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ2" />
      <input name="radius" type="float" nodename="scale_half" />
    </hexagon>
    <hexagon name="hexagon_stagg3" type="float">
      <input name="texcoord" type="vector2" nodename="coord_circ3" />
      <input name="radius" type="float" nodename="scale_half" />
    </hexagon>
    <max name="max1" type="float">
      <input name="in1" type="float" nodename="hexagon_stagg1" />
      <input name="in2" type="float" nodename="hexagon_stagg2" />
    </max>
    <max name="max" type="float">
      <input name="in1" type="float" nodename="max1" />
      <input name="in2" type="float" nodename="hexagon_stagg3" />
    </max>
    <hexagon name="hexagon_regular" type="float">
      <input name="texcoord" type="vector2" nodename="recenter" />
      <input name="radius" type="float" interfacename="size" />
    </hexagon>
    <ifequal name="pattern_selection" type="float">
      <input name="value1" type="boolean" interfacename="staggered" />
      <input name="value2" type="boolean" value="true" />
      <input name="in1" type="float" nodename="max" />
      <input name="in2" type="float" nodename="hexagon_regular" />
    </ifequal>
    <convert name="to_rgb" type="color3">
      <input name="in" type="float" nodename="pattern_selection" />
    </convert>
    <output name="out" type="color3" nodename="to_rgb" />
  </nodegraph>

  <!-- ======================================================================== -->
  <!-- Geometric nodes                                                          -->
  <!-- ======================================================================== -->

  <!--
    Node: <bump>
  -->
  <nodegraph name="NG_bump_vector3" nodedef="ND_bump_vector3">
    <heighttonormal name="N_heighttonormal" type="vector3">
      <input name="in" type="float" interfacename="height" />
    </heighttonormal>
    <normalmap name="N_normalmap" type="vector3">
      <input name="in" type="vector3" nodename="N_heighttonormal" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="scale" type="float" interfacename="scale" />
      <input name="tangent" type="vector3" interfacename="tangent" />
      <input name="bitangent" type="vector3" interfacename="bitangent" />
    </normalmap>
    <output name="out" type="vector3" nodename="N_normalmap" />
  </nodegraph>

  <!-- ======================================================================== -->
  <!-- Global nodes                                                             -->
  <!-- ======================================================================== -->

  <!-- ======================================================================== -->
  <!-- Application nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- ======================================================================== -->
  <!-- Math nodes                                                               -->
  <!-- ======================================================================== -->

  <!--
    Node: <place2d>
    Transform incoming UV texture coordinates from one 2D frame of reference to another.
    operationorder (integer enum): the order in which to perform the transform operations.
    "0" or "SRT" performs -pivot, scale, rotate, translate, +pivot as per the original
    implementation matching the behavior of certain DCC packages, and "1" or "TRS" performs
    -pivot, translate, rotate, scale, +pivot which does not introduce texture shear.
    Default is 0 "SRT" for backward compatibility.
  -->
  <nodegraph name="NG_place2d_vector2" nodedef="ND_place2d_vector2">
    <subtract name="N_subpivot" type="vector2">
      <input name="in1" type="vector2" interfacename="texcoord" />
      <input name="in2" type="vector2" interfacename="pivot" />
    </subtract>
    <divide name="N_applyscale" type="vector2">
      <input name="in1" type="vector2" nodename="N_subpivot" />
      <input name="in2" type="vector2" interfacename="scale" />
    </divide>
    <rotate2d name="N_applyrot" type="vector2">
      <input name="in" type="vector2" nodename="N_applyscale" />
      <input name="amount" type="float" interfacename="rotate" />
    </rotate2d>
    <subtract name="N_applyoffset" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyrot" />
      <input name="in2" type="vector2" interfacename="offset" />
    </subtract>
    <add name="N_addpivot" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyoffset" />
      <input name="in2" type="vector2" interfacename="pivot" />
    </add>
    <subtract name="N_applyoffset2" type="vector2">
      <input name="in1" type="vector2" nodename="N_subpivot" />
      <input name="in2" type="vector2" interfacename="offset" />
    </subtract>
    <rotate2d name="N_applyrot2" type="vector2">
      <input name="in" type="vector2" nodename="N_applyoffset2" />
      <input name="amount" type="float" interfacename="rotate" />
    </rotate2d>
    <divide name="N_applyscale2" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyrot2" />
      <input name="in2" type="vector2" interfacename="scale" />
    </divide>
    <add name="N_addpivot2" type="vector2">
      <input name="in1" type="vector2" nodename="N_applyscale2" />
      <input name="in2" type="vector2" interfacename="pivot" />
    </add>
    <switch name="N_switch_operationorder" type="vector2">
      <input name="in1" type="vector2" nodename="N_addpivot" />
      <input name="in2" type="vector2" nodename="N_addpivot2" />
      <input name="which" type="integer" interfacename="operationorder" />
    </switch>
    <output name="out" type="vector2" nodename="N_switch_operationorder" />
  </nodegraph>

  <!--
    Node: <distance>
    Measures the distance between two points in 2D, 3D, or 4D.
  -->
  <nodegraph name="NG_distance_vector2" nodedef="ND_distance_vector2">
    <subtract name="N_mtlxsubtract" type="vector2">
      <input name="in1" type="vector2" interfacename="in1" />
      <input name="in2" type="vector2" interfacename="in2" />
    </subtract>
    <magnitude name="N_mtlxmagnitude" type="float">
      <input name="in" type="vector2" nodename="N_mtlxsubtract" />
    </magnitude>
    <output name="out" type="float" nodename="N_mtlxmagnitude" />
  </nodegraph>
  <nodegraph name="NG_distance_vector3" nodedef="ND_distance_vector3">
    <subtract name="N_mtlxsubtract" type="vector3">
      <input name="in1" type="vector3" interfacename="in1" />
      <input name="in2" type="vector3" interfacename="in2" />
    </subtract>
    <magnitude name="N_mtlxmagnitude" type="float">
      <input name="in" type="vector3" nodename="N_mtlxsubtract" />
    </magnitude>
    <output name="out" type="float" nodename="N_mtlxmagnitude" />
  </nodegraph>
  <nodegraph name="NG_distance_vector4" nodedef="ND_distance_vector4">
    <subtract name="N_mtlxsubtract" type="vector4">
      <input name="in1" type="vector4" interfacename="in1" />
      <input name="in2" type="vector4" interfacename="in2" />
    </subtract>
    <magnitude name="N_mtlxmagnitude" type="float">
      <input name="in" type="vector4" nodename="N_mtlxsubtract" />
    </magnitude>
    <output name="out" type="float" nodename="N_mtlxmagnitude" />
  </nodegraph>

  <!--
    Node: <trianglewave>
    Generate a triangle wave from the given scalar input.
    The generated wave ranges from zero to one and repeats on integer boundaries.
  -->
  <nodegraph name="NG_trianglewave_float" nodedef="ND_trianglewave_float">
    <absval name="absval1" type="float">
      <input name="in" type="float" interfacename="in" />
    </absval>
    <modulo name="modulo1" type="float">
      <input name="in1" type="float" nodename="absval1" />
    </modulo>
    <subtract name="subtract1" type="float">
      <input name="in1" type="float" nodename="modulo1" />
      <input name="in2" type="float" value="0.5" />
    </subtract>
    <absval name="absval2" type="float">
      <input name="in" type="float" nodename="subtract1" />
    </absval>
    <subtract name="subtract2" type="float">
      <input name="in1" type="float" value="0.5" />
      <input name="in2" type="float" nodename="absval2" />
    </subtract>
    <output name="out" type="float" nodename="subtract2" />
  </nodegraph>

  <!--
    Node: <reflect>
    Compute the reflection vector given an incident vector and unit surface normal.
  -->
  <nodegraph name="NG_reflect_vector3" type="vector3" nodedef="ND_reflect_vector3">
    <dotproduct name="NdotI" type="float">
      <input name="in1" type="vector3" interfacename="normal" />
      <input name="in2" type="vector3" interfacename="in" />
    </dotproduct>
    <multiply name="NdotI_2" type="float">
      <input name="in1" type="float" nodename="NdotI" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <multiply name="NdotI_N_2" type="vector3">
      <input name="in1" type="vector3" interfacename="normal" />
      <input name="in2" type="float" nodename="NdotI_2" />
    </multiply>
    <subtract name="reflection_vector" type="vector3">
      <input name="in1" type="vector3" interfacename="in" />
      <input name="in2" type="vector3" nodename="NdotI_N_2" />
    </subtract>
    <output name="out" type="vector3" nodename="reflection_vector" />
  </nodegraph>

  <!--
    Node: <refract>
    Compute the refraction vector given an incident vector, unit surface normal,
    and index of refraction.
  -->
  <nodegraph name="NG_refract_vector3" nodedef="ND_refract_vector3">
    <dotproduct name="IdotN" type="float">
      <input name="in1" type="vector3" interfacename="in" />
      <input name="in2" type="vector3" interfacename="normal" />
    </dotproduct>
    <multiply name="IdotNsq" type="float">
      <input name="in1" type="float" nodename="IdotN" />
      <input name="in2" type="float" nodename="IdotN" />
    </multiply>
    <multiply name="iorsq" type="float">
      <input name="in1" type="float" interfacename="ior" />
      <input name="in2" type="float" interfacename="ior" />
    </multiply>
    <subtract name="one_IdotNsq" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="IdotNsq" />
    </subtract>
    <multiply name="iorsq_one_IdotNsq" type="float">
      <input name="in1" type="float" nodename="iorsq" />
      <input name="in2" type="float" nodename="one_IdotNsq" />
    </multiply>
    <subtract name="k" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="iorsq_one_IdotNsq" />
    </subtract>
    <multiply name="I_scaled" type="vector3">
      <input name="in1" type="vector3" interfacename="in" />
      <input name="in2" type="float" interfacename="ior" />
    </multiply>
    <sqrt name="sqrt_k" type="float">
      <input name="in" type="float" nodename="k" />
    </sqrt>
    <multiply name="ior_NdotI" type="float">
      <input name="in1" type="float" interfacename="ior" />
      <input name="in2" type="float" nodename="IdotN" />
    </multiply>
    <add name="ior_NdotI_sqrt_k" type="float">
      <input name="in1" type="float" nodename="ior_NdotI" />
      <input name="in2" type="float" nodename="sqrt_k" />
    </add>
    <multiply name="N_scaled" type="vector3">
      <input name="in1" type="vector3" interfacename="normal" />
      <input name="in2" type="float" nodename="ior_NdotI_sqrt_k" />
    </multiply>
    <subtract name="refract_dir" type="vector3">
      <input name="in1" type="vector3" nodename="I_scaled" />
      <input name="in2" type="vector3" nodename="N_scaled" />
    </subtract>
    <ifgreater name="result" type="vector3">
      <input name="value1" type="float" value="0.0" />
      <input name="value2" type="float" nodename="k" />
      <input name="in1" type="vector3" value="0.0, 0.0, 0.0" />
      <input name="in2" type="vector3" nodename="refract_dir" />
    </ifgreater>
    <output name="out" type="vector3" nodename="result" />
  </nodegraph>

  <!-- ======================================================================== -->
  <!-- Adjustment nodes                                                         -->
  <!-- ======================================================================== -->

  <!--
    Node: <smoothstep>
    Outputs a smooth (hermite-interpolated) remapping of input values from low-high
    to output 0-1.
  -->
  <nodegraph name="NG_smoothstep_color3" nodedef="ND_smoothstep_color3">
    <separate3 name="separate_in" type="multioutput">
      <input name="in" type="color3" interfacename="in" />
    </separate3>
    <separate3 name="separate_low" type="multioutput">
      <input name="in" type="color3" interfacename="low" />
    </separate3>
    <separate3 name="separate_high" type="multioutput">
      <input name="in" type="color3" interfacename="high" />
    </separate3>
    <smoothstep name="smoothstep_r" type="float">
      <input name="in" type="float" nodename="separate_in" output="outr"/>
      <input name="low" type="float" nodename="separate_low" output="outr"/>
      <input name="high" type="float" nodename="separate_high" output="outr"/>
    </smoothstep>
    <smoothstep name="smoothstep_g" type="float">
      <input name="in" type="float" nodename="separate_in" output="outg"/>
      <input name="low" type="float" nodename="separate_low" output="outg"/>
      <input name="high" type="float" nodename="separate_high" output="outg"/>
    </smoothstep>
    <smoothstep name="smoothstep_b" type="float">
      <input name="in" type="float" nodename="separate_in" output="outb"/>
      <input name="low" type="float" nodename="separate_low" output="outb"/>
      <input name="high" type="float" nodename="separate_high" output="outb"/>
    </smoothstep>
    <combine3 name="combine" type="color3">
      <input name="in1" type="float" nodename="smoothstep_r"/>
      <input name="in2" type="float" nodename="smoothstep_g"/>
      <input name="in3" type="float" nodename="smoothstep_b"/>
    </combine3>
    <output name="out" type="color3" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_color4" nodedef="ND_smoothstep_color4">
    <separate4 name="separate_in" type="multioutput">
      <input name="in" type="color4" interfacename="in" />
    </separate4>
    <separate4 name="separate_low" type="multioutput">
      <input name="in" type="color4" interfacename="low" />
    </separate4>
    <separate4 name="separate_high" type="multioutput">
      <input name="in" type="color4" interfacename="high" />
    </separate4>
    <smoothstep name="smoothstep_r" type="float">
      <input name="in" type="float" nodename="separate_in" output="outr"/>
      <input name="low" type="float" nodename="separate_low" output="outr"/>
      <input name="high" type="float" nodename="separate_high" output="outr"/>
    </smoothstep>
    <smoothstep name="smoothstep_g" type="float">
      <input name="in" type="float" nodename="separate_in" output="outg"/>
      <input name="low" type="float" nodename="separate_low" output="outg"/>
      <input name="high" type="float" nodename="separate_high" output="outg"/>
    </smoothstep>
    <smoothstep name="smoothstep_b" type="float">
      <input name="in" type="float" nodename="separate_in" output="outb"/>
      <input name="low" type="float" nodename="separate_low" output="outb"/>
      <input name="high" type="float" nodename="separate_high" output="outb"/>
    </smoothstep>
    <smoothstep name="smoothstep_a" type="float">
      <input name="in" type="float" nodename="separate_in" output="outa"/>
      <input name="low" type="float" nodename="separate_low" output="outa"/>
      <input name="high" type="float" nodename="separate_high" output="outa"/>
    </smoothstep>
    <combine4 name="combine" type="color4">
      <input name="in1" type="float" nodename="smoothstep_r"/>
      <input name="in2" type="float" nodename="smoothstep_g"/>
      <input name="in3" type="float" nodename="smoothstep_b"/>
      <input name="in4" type="float" nodename="smoothstep_a"/>
    </combine4>
    <output name="out" type="color4" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_color3FA" nodedef="ND_smoothstep_color3FA">
    <separate3 name="separate_in" type="multioutput">
      <input name="in" type="color3" interfacename="in" />
    </separate3>
    <smoothstep name="smoothstep_r" type="float">
      <input name="in" type="float" nodename="separate_in" output="outr"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_g" type="float">
      <input name="in" type="float" nodename="separate_in" output="outg"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_b" type="float">
      <input name="in" type="float" nodename="separate_in" output="outb"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <combine3 name="combine" type="color3">
      <input name="in1" type="float" nodename="smoothstep_r"/>
      <input name="in2" type="float" nodename="smoothstep_g"/>
      <input name="in3" type="float" nodename="smoothstep_b"/>
    </combine3>
    <output name="out" type="color3" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_color4FA" nodedef="ND_smoothstep_color4FA">
    <separate4 name="separate_in" type="multioutput">
      <input name="in" type="color4" interfacename="in" />
    </separate4>
    <smoothstep name="smoothstep_r" type="float">
      <input name="in" type="float" nodename="separate_in" output="outr"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_g" type="float">
      <input name="in" type="float" nodename="separate_in" output="outg"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_b" type="float">
      <input name="in" type="float" nodename="separate_in" output="outb"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_a" type="float">
      <input name="in" type="float" nodename="separate_in" output="outa"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <combine4 name="combine" type="color4">
      <input name="in1" type="float" nodename="smoothstep_r"/>
      <input name="in2" type="float" nodename="smoothstep_g"/>
      <input name="in3" type="float" nodename="smoothstep_b"/>
      <input name="in4" type="float" nodename="smoothstep_a"/>
    </combine4>
    <output name="out" type="color4" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_vector2" nodedef="ND_smoothstep_vector2">
    <separate2 name="separate_in" type="multioutput">
      <input name="in" type="vector2" interfacename="in"/>
    </separate2>
    <separate2 name="separate_low" type="multioutput">
      <input name="in" type="vector2" interfacename="low"/>
    </separate2>
    <separate2 name="separate_high" type="multioutput">
      <input name="in" type="vector2" interfacename="high"/>
    </separate2>
    <smoothstep name="smoothstep_x" type="float">
      <input name="in" type="float" nodename="separate_in" output="outx"/>
      <input name="low" type="float" nodename="separate_low" output="outx"/>
      <input name="high" type="float" nodename="separate_high" output="outx"/>
    </smoothstep>
    <smoothstep name="smoothstep_y" type="float">
      <input name="in" type="float" nodename="separate_in" output="outy"/>
      <input name="low" type="float" nodename="separate_low" output="outy"/>
      <input name="high" type="float" nodename="separate_high" output="outy"/>
    </smoothstep>
    <combine2 name="combine" type="vector2">
      <input name="in1" type="float" nodename="smoothstep_x"/>
      <input name="in2" type="float" nodename="smoothstep_y"/>
    </combine2>
    <output name="out" type="vector2" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_vector3" nodedef="ND_smoothstep_vector3">
    <separate3 name="separate_in" type="multioutput">
      <input name="in" type="vector3" interfacename="in"/>
    </separate3>
    <separate3 name="separate_low" type="multioutput">
      <input name="in" type="vector3" interfacename="low"/>
    </separate3>
    <separate3 name="separate_high" type="multioutput">
      <input name="in" type="vector3" interfacename="high"/>
    </separate3>
    <smoothstep name="smoothstep_x" type="float">
      <input name="in" type="float" nodename="separate_in" output="outx"/>
      <input name="low" type="float" nodename="separate_low" output="outx"/>
      <input name="high" type="float" nodename="separate_high" output="outx"/>
    </smoothstep>
    <smoothstep name="smoothstep_y" type="float">
      <input name="in" type="float" nodename="separate_in" output="outy"/>
      <input name="low" type="float" nodename="separate_low" output="outy"/>
      <input name="high" type="float" nodename="separate_high" output="outy"/>
    </smoothstep>
    <smoothstep name="smoothstep_z" type="float">
      <input name="in" type="float" nodename="separate_in" output="outz"/>
      <input name="low" type="float" nodename="separate_low" output="outz"/>
      <input name="high" type="float" nodename="separate_high" output="outz"/>
    </smoothstep>
    <combine3 name="combine" type="vector3">
      <input name="in1" type="float" nodename="smoothstep_x"/>
      <input name="in2" type="float" nodename="smoothstep_y"/>
      <input name="in3" type="float" nodename="smoothstep_z"/>
    </combine3>
    <output name="out" type="vector3" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_vector4" nodedef="ND_smoothstep_vector4">
    <separate4 name="separate_in" type="multioutput">
      <input name="in" type="vector4" interfacename="in"/>
    </separate4>
    <separate4 name="separate_low" type="multioutput">
      <input name="in" type="vector4" interfacename="low"/>
    </separate4>
    <separate4 name="separate_high" type="multioutput">
      <input name="in" type="vector4" interfacename="high"/>
    </separate4>
    <smoothstep name="smoothstep_x" type="float">
      <input name="in" type="float" nodename="separate_in" output="outx"/>
      <input name="low" type="float" nodename="separate_low" output="outx"/>
      <input name="high" type="float" nodename="separate_high" output="outx"/>
    </smoothstep>
    <smoothstep name="smoothstep_y" type="float">
      <input name="in" type="float" nodename="separate_in" output="outy"/>
      <input name="low" type="float" nodename="separate_low" output="outy"/>
      <input name="high" type="float" nodename="separate_high" output="outy"/>
    </smoothstep>
    <smoothstep name="smoothstep_z" type="float">
      <input name="in" type="float" nodename="separate_in" output="outz"/>
      <input name="low" type="float" nodename="separate_low" output="outz"/>
      <input name="high" type="float" nodename="separate_high" output="outz"/>
    </smoothstep>
    <smoothstep name="smoothstep_w" type="float">
      <input name="in" type="float" nodename="separate_in" output="outw"/>
      <input name="low" type="float" nodename="separate_low" output="outw"/>
      <input name="high" type="float" nodename="separate_high" output="outw"/>
    </smoothstep>
    <combine4 name="combine" type="vector4">
      <input name="in1" type="float" nodename="smoothstep_x"/>
      <input name="in2" type="float" nodename="smoothstep_y"/>
      <input name="in3" type="float" nodename="smoothstep_z"/>
      <input name="in4" type="float" nodename="smoothstep_w"/>
    </combine4>
    <output name="out" type="vector4" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_vector2FA" nodedef="ND_smoothstep_vector2FA">
    <separate2 name="separate_in" type="multioutput">
      <input name="in" type="vector2" interfacename="in" />
    </separate2>
    <smoothstep name="smoothstep_x" type="float">
      <input name="in" type="float" nodename="separate_in" output="outx"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_y" type="float">
      <input name="in" type="float" nodename="separate_in" output="outy"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <combine2 name="combine" type="vector2">
      <input name="in1" type="float" nodename="smoothstep_x"/>
      <input name="in2" type="float" nodename="smoothstep_y"/>
    </combine2>
    <output name="out" type="vector2" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_vector3FA" nodedef="ND_smoothstep_vector3FA">
    <separate3 name="separate_in" type="multioutput">
      <input name="in" type="vector3" interfacename="in" />
    </separate3>
    <smoothstep name="smoothstep_x" type="float">
      <input name="in" type="float" nodename="separate_in" output="outx"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_y" type="float">
      <input name="in" type="float" nodename="separate_in" output="outy"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_z" type="float">
      <input name="in" type="float" nodename="separate_in" output="outz"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <combine3 name="combine" type="vector3">
      <input name="in1" type="float" nodename="smoothstep_x"/>
      <input name="in2" type="float" nodename="smoothstep_y"/>
      <input name="in3" type="float" nodename="smoothstep_z"/>
    </combine3>
    <output name="out" type="vector3" nodename="combine"/>
  </nodegraph>
  <nodegraph name="NG_smoothstep_vector4FA" nodedef="ND_smoothstep_vector4FA">
    <separate4 name="separate_in" type="multioutput">
      <input name="in" type="vector4" interfacename="in" />
    </separate4>
    <smoothstep name="smoothstep_x" type="float">
      <input name="in" type="float" nodename="separate_in" output="outx"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_y" type="float">
      <input name="in" type="float" nodename="separate_in" output="outy"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_z" type="float">
      <input name="in" type="float" nodename="separate_in" output="outz"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <smoothstep name="smoothstep_w" type="float">
      <input name="in" type="float" nodename="separate_in" output="outw"/>
      <input name="low" type="float" interfacename="low"/>
      <input name="high" type="float" interfacename="high"/>
    </smoothstep>
    <combine4 name="combine" type="vector4">
      <input name="in1" type="float" nodename="smoothstep_x"/>
      <input name="in2" type="float" nodename="smoothstep_y"/>
      <input name="in3" type="float" nodename="smoothstep_z"/>
      <input name="in4" type="float" nodename="smoothstep_w"/>
    </combine4>
    <output name="out" type="vector4" nodename="combine"/>
  </nodegraph>

  <!--
    Node: <safepower>
    Raise incoming half/float/color/vector values to the "in2" power.
    Negative "in1" values will result in negative output values. ie. out = sign(in1)*pow(abs(in1),in2)
  -->
  <nodegraph name="NG_safepower_float" nodedef="ND_safepower_float">
    <sign name="sign_in1" type="float">
      <input name="in" type="float" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="float">
      <input name="in" type="float" interfacename="in1" />
    </absval>
    <power name="power" type="float">
      <input name="in1" type="float" nodename="abs_in1" />
      <input name="in2" type="float" interfacename="in2" />
    </power>
    <multiply name="safepower" type="float">
      <input name="in1" type="float" nodename="sign_in1" />
      <input name="in2" type="float" nodename="power" />
    </multiply>
    <output name="out" type="float" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_color3" nodedef="ND_safepower_color3">
    <sign name="sign_in1" type="color3">
      <input name="in" type="color3" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="color3">
      <input name="in" type="color3" interfacename="in1" />
    </absval>
    <power name="power" type="color3">
      <input name="in1" type="color3" nodename="abs_in1" />
      <input name="in2" type="color3" interfacename="in2" />
    </power>
    <multiply name="safepower" type="color3">
      <input name="in1" type="color3" nodename="sign_in1" />
      <input name="in2" type="color3" nodename="power" />
    </multiply>
    <output name="out" type="color3" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_color4" nodedef="ND_safepower_color4">
    <sign name="sign_in1" type="color4">
      <input name="in" type="color4" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="color4">
      <input name="in" type="color4" interfacename="in1" />
    </absval>
    <power name="power" type="color4">
      <input name="in1" type="color4" nodename="abs_in1" />
      <input name="in2" type="color4" interfacename="in2" />
    </power>
    <multiply name="safepower" type="color4">
      <input name="in1" type="color4" nodename="sign_in1" />
      <input name="in2" type="color4" nodename="power" />
    </multiply>
    <output name="out" type="color4" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_vector2" nodedef="ND_safepower_vector2">
    <sign name="sign_in1" type="vector2">
      <input name="in" type="vector2" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="vector2">
      <input name="in" type="vector2" interfacename="in1" />
    </absval>
    <power name="power" type="vector2">
      <input name="in1" type="vector2" nodename="abs_in1" />
      <input name="in2" type="vector2" interfacename="in2" />
    </power>
    <multiply name="safepower" type="vector2">
      <input name="in1" type="vector2" nodename="sign_in1" />
      <input name="in2" type="vector2" nodename="power" />
    </multiply>
    <output name="out" type="vector2" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_vector3" nodedef="ND_safepower_vector3">
    <sign name="sign_in1" type="vector3">
      <input name="in" type="vector3" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="vector3">
      <input name="in" type="vector3" interfacename="in1" />
    </absval>
    <power name="power" type="vector3">
      <input name="in1" type="vector3" nodename="abs_in1" />
      <input name="in2" type="vector3" interfacename="in2" />
    </power>
    <multiply name="safepower" type="vector3">
      <input name="in1" type="vector3" nodename="sign_in1" />
      <input name="in2" type="vector3" nodename="power" />
    </multiply>
    <output name="out" type="vector3" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_vector4" nodedef="ND_safepower_vector4">
    <sign name="sign_in1" type="vector4">
      <input name="in" type="vector4" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="vector4">
      <input name="in" type="vector4" interfacename="in1" />
    </absval>
    <power name="power" type="vector4">
      <input name="in1" type="vector4" nodename="abs_in1" />
      <input name="in2" type="vector4" interfacename="in2" />
    </power>
    <multiply name="safepower" type="vector4">
      <input name="in1" type="vector4" nodename="sign_in1" />
      <input name="in2" type="vector4" nodename="power" />
    </multiply>
    <output name="out" type="vector4" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_color3FA" nodedef="ND_safepower_color3FA">
    <sign name="sign_in1" type="color3">
      <input name="in" type="color3" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="color3">
      <input name="in" type="color3" interfacename="in1" />
    </absval>
    <power name="power" type="color3">
      <input name="in1" type="color3" nodename="abs_in1" />
      <input name="in2" type="float" interfacename="in2" />
    </power>
    <multiply name="safepower" type="color3">
      <input name="in1" type="color3" nodename="sign_in1" />
      <input name="in2" type="color3" nodename="power" />
    </multiply>
    <output name="out" type="color3" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_color4FA" nodedef="ND_safepower_color4FA">
    <sign name="sign_in1" type="color4">
      <input name="in" type="color4" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="color4">
      <input name="in" type="color4" interfacename="in1" />
    </absval>
    <power name="power" type="color4">
      <input name="in1" type="color4" nodename="abs_in1" />
      <input name="in2" type="float" interfacename="in2" />
    </power>
    <multiply name="safepower" type="color4">
      <input name="in1" type="color4" nodename="sign_in1" />
      <input name="in2" type="color4" nodename="power" />
    </multiply>
    <output name="out" type="color4" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_vector2FA" nodedef="ND_safepower_vector2FA">
    <sign name="sign_in1" type="vector2">
      <input name="in" type="vector2" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="vector2">
      <input name="in" type="vector2" interfacename="in1" />
    </absval>
    <power name="power" type="vector2">
      <input name="in1" type="vector2" nodename="abs_in1" />
      <input name="in2" type="float" interfacename="in2" />
    </power>
    <multiply name="safepower" type="vector2">
      <input name="in1" type="vector2" nodename="sign_in1" />
      <input name="in2" type="vector2" nodename="power" />
    </multiply>
    <output name="out" type="vector2" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_vector3FA" nodedef="ND_safepower_vector3FA">
    <sign name="sign_in1" type="vector3">
      <input name="in" type="vector3" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="vector3">
      <input name="in" type="vector3" interfacename="in1" />
    </absval>
    <power name="power" type="vector3">
      <input name="in1" type="vector3" nodename="abs_in1" />
      <input name="in2" type="float" interfacename="in2" />
    </power>
    <multiply name="safepower" type="vector3">
      <input name="in1" type="vector3" nodename="sign_in1" />
      <input name="in2" type="vector3" nodename="power" />
    </multiply>
    <output name="out" type="vector3" nodename="safepower" />
  </nodegraph>
  <nodegraph name="NG_safepower_vector4FA" nodedef="ND_safepower_vector4FA">
    <sign name="sign_in1" type="vector4">
      <input name="in" type="vector4" interfacename="in1" />
    </sign>
    <absval name="abs_in1" type="vector4">
      <input name="in" type="vector4" interfacename="in1" />
    </absval>
    <power name="power" type="vector4">
      <input name="in1" type="vector4" nodename="abs_in1" />
      <input name="in2" type="float" interfacename="in2" />
    </power>
    <multiply name="safepower" type="vector4">
      <input name="in1" type="vector4" nodename="sign_in1" />
      <input name="in2" type="vector4" nodename="power" />
    </multiply>
    <output name="out" type="vector4" nodename="safepower" />
  </nodegraph>

  <!--
    Node: <contrast>
    Increase or decrease contrast of a float/color value using a linear slope multiplier.
  -->
  <nodegraph name="NG_contrast_float" nodedef="ND_contrast_float">
    <subtract name="N_sub_float" type="float">
      <input name="in1" type="float" interfacename="in" />
      <input name="in2" type="float" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_float" type="float">
      <input name="in1" type="float" nodename="N_sub_float" />
      <input name="in2" type="float" interfacename="amount" />
    </multiply>
    <add name="N_add_float" type="float">
      <input name="in1" type="float" nodename="N_mul_float" />
      <input name="in2" type="float" interfacename="pivot" />
    </add>
    <output name="out" type="float" nodename="N_add_float" />
  </nodegraph>
  <nodegraph name="NG_contrast_color3" nodedef="ND_contrast_color3">
    <subtract name="N_sub_color3" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="color3" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_color3" type="color3">
      <input name="in1" type="color3" nodename="N_sub_color3" />
      <input name="in2" type="color3" interfacename="amount" />
    </multiply>
    <add name="N_add_color3" type="color3">
      <input name="in1" type="color3" nodename="N_mul_color3" />
      <input name="in2" type="color3" interfacename="pivot" />
    </add>
    <output name="out" type="color3" nodename="N_add_color3" />
  </nodegraph>
  <nodegraph name="NG_contrast_color4" nodedef="ND_contrast_color4">
    <subtract name="N_sub_color4" type="color4">
      <input name="in1" type="color4" interfacename="in" />
      <input name="in2" type="color4" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_color4" type="color4">
      <input name="in1" type="color4" nodename="N_sub_color4" />
      <input name="in2" type="color4" interfacename="amount" />
    </multiply>
    <add name="N_add_color4" type="color4">
      <input name="in1" type="color4" nodename="N_mul_color4" />
      <input name="in2" type="color4" interfacename="pivot" />
    </add>
    <output name="out" type="color4" nodename="N_add_color4" />
  </nodegraph>
  <nodegraph name="NG_contrast_vector2" nodedef="ND_contrast_vector2">
    <subtract name="N_sub_vector2" type="vector2">
      <input name="in1" type="vector2" interfacename="in" />
      <input name="in2" type="vector2" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_sub_vector2" />
      <input name="in2" type="vector2" interfacename="amount" />
    </multiply>
    <add name="N_add_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_mul_vector2" />
      <input name="in2" type="vector2" interfacename="pivot" />
    </add>
    <output name="out" type="vector2" nodename="N_add_vector2" />
  </nodegraph>
  <nodegraph name="NG_contrast_vector3" nodedef="ND_contrast_vector3">
    <subtract name="N_sub_vector3" type="vector3">
      <input name="in1" type="vector3" interfacename="in" />
      <input name="in2" type="vector3" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_sub_vector3" />
      <input name="in2" type="vector3" interfacename="amount" />
    </multiply>
    <add name="N_add_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_mul_vector3" />
      <input name="in2" type="vector3" interfacename="pivot" />
    </add>
    <output name="out" type="vector3" nodename="N_add_vector3" />
  </nodegraph>
  <nodegraph name="NG_contrast_vector4" nodedef="ND_contrast_vector4">
    <subtract name="N_sub_vector4" type="vector4">
      <input name="in1" type="vector4" interfacename="in" />
      <input name="in2" type="vector4" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_sub_vector4" />
      <input name="in2" type="vector4" interfacename="amount" />
    </multiply>
    <add name="N_add_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_mul_vector4" />
      <input name="in2" type="vector4" interfacename="pivot" />
    </add>
    <output name="out" type="vector4" nodename="N_add_vector4" />
  </nodegraph>
  <nodegraph name="NG_contrast_color3FA" nodedef="ND_contrast_color3FA">
    <subtract name="N_sub_color3FA" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="float" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_color3FA" type="color3">
      <input name="in1" type="color3" nodename="N_sub_color3FA" />
      <input name="in2" type="float" interfacename="amount" />
    </multiply>
    <add name="N_add_color3FA" type="color3">
      <input name="in1" type="color3" nodename="N_mul_color3FA" />
      <input name="in2" type="float" interfacename="pivot" />
    </add>
    <output name="out" type="color3" nodename="N_add_color3FA" />
  </nodegraph>
  <nodegraph name="NG_contrast_color4FA" nodedef="ND_contrast_color4FA">
    <subtract name="N_sub_color4FA" type="color4">
      <input name="in1" type="color4" interfacename="in" />
      <input name="in2" type="float" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_color4FA" type="color4">
      <input name="in1" type="color4" nodename="N_sub_color4FA" />
      <input name="in2" type="float" interfacename="amount" />
    </multiply>
    <add name="N_add_color4FA" type="color4">
      <input name="in1" type="color4" nodename="N_mul_color4FA" />
      <input name="in2" type="float" interfacename="pivot" />
    </add>
    <output name="out" type="color4" nodename="N_add_color4FA" />
  </nodegraph>
  <nodegraph name="NG_contrast_vector2FA" nodedef="ND_contrast_vector2FA">
    <subtract name="N_sub_vector2FA" type="vector2">
      <input name="in1" type="vector2" interfacename="in" />
      <input name="in2" type="float" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_vector2FA" type="vector2">
      <input name="in1" type="vector2" nodename="N_sub_vector2FA" />
      <input name="in2" type="float" interfacename="amount" />
    </multiply>
    <add name="N_add_vector2FA" type="vector2">
      <input name="in1" type="vector2" nodename="N_mul_vector2FA" />
      <input name="in2" type="float" interfacename="pivot" />
    </add>
    <output name="out" type="vector2" nodename="N_add_vector2FA" />
  </nodegraph>
  <nodegraph name="NG_contrast_vector3FA" nodedef="ND_contrast_vector3FA">
    <subtract name="N_sub_vector3FA" type="vector3">
      <input name="in1" type="vector3" interfacename="in" />
      <input name="in2" type="float" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_vector3FA" type="vector3">
      <input name="in1" type="vector3" nodename="N_sub_vector3FA" />
      <input name="in2" type="float" interfacename="amount" />
    </multiply>
    <add name="N_add_vector3FA" type="vector3">
      <input name="in1" type="vector3" nodename="N_mul_vector3FA" />
      <input name="in2" type="float" interfacename="pivot" />
    </add>
    <output name="out" type="vector3" nodename="N_add_vector3FA" />
  </nodegraph>
  <nodegraph name="NG_contrast_vector4FA" nodedef="ND_contrast_vector4FA">
    <subtract name="N_sub_vector4FA" type="vector4">
      <input name="in1" type="vector4" interfacename="in" />
      <input name="in2" type="float" interfacename="pivot" />
    </subtract>
    <multiply name="N_mul_vector4FA" type="vector4">
      <input name="in1" type="vector4" nodename="N_sub_vector4FA" />
      <input name="in2" type="float" interfacename="amount" />
    </multiply>
    <add name="N_add_vector4FA" type="vector4">
      <input name="in1" type="vector4" nodename="N_mul_vector4FA" />
      <input name="in2" type="float" interfacename="pivot" />
    </add>
    <output name="out" type="vector4" nodename="N_add_vector4FA" />
  </nodegraph>

  <!--
    Node: <range>
    Remap a value from one range of float/color/vector values to another, optionally
    applying a gamma correction in the middle, and optionally clamping output values.
  -->
  <nodegraph name="NG_range_float" nodedef="ND_range_float">
    <remap name="N_remap1_float" type="float">
      <input name="in" type="float" interfacename="in" />
      <input name="inlow" type="float" interfacename="inlow" />
      <input name="inhigh" type="float" interfacename="inhigh" />
      <input name="outlow" type="float" value="0.0" />
      <input name="outhigh" type="float" value="1.0" />
    </remap>
    <divide name="N_recip_float" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="gamma" />
    </divide>
    <absval name="N_abs_float" type="float">
      <input name="in" type="float" nodename="N_remap1_float" />
    </absval>
    <power name="N_pow_float" type="float">
      <input name="in1" type="float" nodename="N_abs_float" />
      <input name="in2" type="float" nodename="N_recip_float" />
    </power>
    <sign name="N_sign_float" type="float">
      <input name="in" type="float" nodename="N_remap1_float" />
    </sign>
    <multiply name="N_gamma_float" type="float">
      <input name="in1" type="float" nodename="N_pow_float" />
      <input name="in2" type="float" nodename="N_sign_float" />
    </multiply>
    <remap name="N_remap2_float" type="float">
      <input name="in" type="float" nodename="N_gamma_float" />
      <input name="inlow" type="float" value="0.0" />
      <input name="inhigh" type="float" value="1.0" />
      <input name="outlow" type="float" interfacename="outlow" />
      <input name="outhigh" type="float" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_float" type="float">
      <input name="in" type="float" nodename="N_remap2_float" />
      <input name="low" type="float" interfacename="outlow" />
      <input name="high" type="float" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_float" type="float">
      <input name="in1" type="float" nodename="N_clamp_float" />
      <input name="in2" type="float" nodename="N_remap2_float" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="float" nodename="N_switch_float" />
  </nodegraph>
  <nodegraph name="NG_range_color3" nodedef="ND_range_color3">
    <remap name="N_remap1_color3" type="color3">
      <input name="in" type="color3" interfacename="in" />
      <input name="inlow" type="color3" interfacename="inlow" />
      <input name="inhigh" type="color3" interfacename="inhigh" />
      <input name="outlow" type="color3" value="0.0, 0.0, 0.0" />
      <input name="outhigh" type="color3" value="1.0, 1.0, 1.0" />
    </remap>
    <divide name="N_recip_color3" type="color3">
      <input name="in1" type="color3" value="1.0, 1.0, 1.0" />
      <input name="in2" type="color3" interfacename="gamma" />
    </divide>
    <absval name="N_abs_color3" type="color3">
      <input name="in" type="color3" nodename="N_remap1_color3" />
    </absval>
    <power name="N_pow_color3" type="color3">
      <input name="in1" type="color3" nodename="N_abs_color3" />
      <input name="in2" type="color3" nodename="N_recip_color3" />
    </power>
    <sign name="N_sign_color3" type="color3">
      <input name="in" type="color3" nodename="N_remap1_color3" />
    </sign>
    <multiply name="N_gamma_color3" type="color3">
      <input name="in1" type="color3" nodename="N_pow_color3" />
      <input name="in2" type="color3" nodename="N_sign_color3" />
    </multiply>
    <remap name="N_remap2_color3" type="color3">
      <input name="in" type="color3" nodename="N_gamma_color3" />
      <input name="inlow" type="color3" value="0.0, 0.0, 0.0" />
      <input name="inhigh" type="color3" value="1.0, 1.0, 1.0" />
      <input name="outlow" type="color3" interfacename="outlow" />
      <input name="outhigh" type="color3" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_color3" type="color3">
      <input name="in" type="color3" nodename="N_remap2_color3" />
      <input name="low" type="color3" interfacename="outlow" />
      <input name="high" type="color3" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_color3" type="color3">
      <input name="in1" type="color3" nodename="N_clamp_color3" />
      <input name="in2" type="color3" nodename="N_remap2_color3" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="color3" nodename="N_switch_color3" />
  </nodegraph>
  <nodegraph name="NG_range_color4" nodedef="ND_range_color4">
    <remap name="N_remap1_color4" type="color4">
      <input name="in" type="color4" interfacename="in" />
      <input name="inlow" type="color4" interfacename="inlow" />
      <input name="inhigh" type="color4" interfacename="inhigh" />
      <input name="outlow" type="color4" value="0.0, 0.0, 0.0, 0.0" />
      <input name="outhigh" type="color4" value="1.0, 1.0, 1.0, 1.0" />
    </remap>
    <divide name="N_recip_color4" type="color4">
      <input name="in1" type="color4" value="1.0, 1.0, 1.0, 1.0" />
      <input name="in2" type="color4" interfacename="gamma" />
    </divide>
    <absval name="N_abs_color4" type="color4">
      <input name="in" type="color4" nodename="N_remap1_color4" />
    </absval>
    <power name="N_pow_color4" type="color4">
      <input name="in1" type="color4" nodename="N_abs_color4" />
      <input name="in2" type="color4" nodename="N_recip_color4" />
    </power>
    <sign name="N_sign_color4" type="color4">
      <input name="in" type="color4" nodename="N_remap1_color4" />
    </sign>
    <multiply name="N_gamma_color4" type="color4">
      <input name="in1" type="color4" nodename="N_pow_color4" />
      <input name="in2" type="color4" nodename="N_sign_color4" />
    </multiply>
    <remap name="N_remap2_color4" type="color4">
      <input name="in" type="color4" nodename="N_gamma_color4" />
      <input name="inlow" type="color4" value="0.0, 0.0, 0.0, 0.0" />
      <input name="inhigh" type="color4" value="1.0, 1.0, 1.0, 1.0" />
      <input name="outlow" type="color4" interfacename="outlow" />
      <input name="outhigh" type="color4" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_color4" type="color4">
      <input name="in" type="color4" nodename="N_remap2_color4" />
      <input name="low" type="color4" interfacename="outlow" />
      <input name="high" type="color4" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_color4" type="color4">
      <input name="in1" type="color4" nodename="N_clamp_color4" />
      <input name="in2" type="color4" nodename="N_remap2_color4" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="color4" nodename="N_switch_color4" />
  </nodegraph>
  <nodegraph name="NG_range_vector2" nodedef="ND_range_vector2">
    <remap name="N_remap1_vector2" type="vector2">
      <input name="in" type="vector2" interfacename="in" />
      <input name="inlow" type="vector2" interfacename="inlow" />
      <input name="inhigh" type="vector2" interfacename="inhigh" />
      <input name="outlow" type="vector2" value="0.0, 0.0" />
      <input name="outhigh" type="vector2" value="1.0, 1.0" />
    </remap>
    <divide name="N_recip_vector2" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" interfacename="gamma" />
    </divide>
    <absval name="N_abs_vector2" type="vector2">
      <input name="in" type="vector2" nodename="N_remap1_vector2" />
    </absval>
    <power name="N_pow_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_abs_vector2" />
      <input name="in2" type="vector2" nodename="N_recip_vector2" />
    </power>
    <sign name="N_sign_vector2" type="vector2">
      <input name="in" type="vector2" nodename="N_remap1_vector2" />
    </sign>
    <multiply name="N_gamma_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_pow_vector2" />
      <input name="in2" type="vector2" nodename="N_sign_vector2" />
    </multiply>
    <remap name="N_remap2_vector2" type="vector2">
      <input name="in" type="vector2" nodename="N_gamma_vector2" />
      <input name="inlow" type="vector2" value="0.0, 0.0" />
      <input name="inhigh" type="vector2" value="1.0, 1.0" />
      <input name="outlow" type="vector2" interfacename="outlow" />
      <input name="outhigh" type="vector2" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_vector2" type="vector2">
      <input name="in" type="vector2" nodename="N_remap2_vector2" />
      <input name="low" type="vector2" interfacename="outlow" />
      <input name="high" type="vector2" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_vector2" type="vector2">
      <input name="in1" type="vector2" nodename="N_clamp_vector2" />
      <input name="in2" type="vector2" nodename="N_remap2_vector2" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="vector2" nodename="N_switch_vector2" />
  </nodegraph>
  <nodegraph name="NG_range_vector3" nodedef="ND_range_vector3">
    <remap name="N_remap1_vector3" type="vector3">
      <input name="in" type="vector3" interfacename="in" />
      <input name="inlow" type="vector3" interfacename="inlow" />
      <input name="inhigh" type="vector3" interfacename="inhigh" />
      <input name="outlow" type="vector3" value="0.0, 0.0, 0.0" />
      <input name="outhigh" type="vector3" value="1.0, 1.0, 1.0" />
    </remap>
    <divide name="N_recip_vector3" type="vector3">
      <input name="in1" type="vector3" value="1.0, 1.0, 1.0" />
      <input name="in2" type="vector3" interfacename="gamma" />
    </divide>
    <absval name="N_abs_vector3" type="vector3">
      <input name="in" type="vector3" nodename="N_remap1_vector3" />
    </absval>
    <power name="N_pow_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_abs_vector3" />
      <input name="in2" type="vector3" nodename="N_recip_vector3" />
    </power>
    <sign name="N_sign_vector3" type="vector3">
      <input name="in" type="vector3" nodename="N_remap1_vector3" />
    </sign>
    <multiply name="N_gamma_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_pow_vector3" />
      <input name="in2" type="vector3" nodename="N_sign_vector3" />
    </multiply>
    <remap name="N_remap2_vector3" type="vector3">
      <input name="in" type="vector3" nodename="N_gamma_vector3" />
      <input name="inlow" type="vector3" value="0.0, 0.0, 0.0" />
      <input name="inhigh" type="vector3" value="1.0, 1.0, 1.0" />
      <input name="outlow" type="vector3" interfacename="outlow" />
      <input name="outhigh" type="vector3" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_vector3" type="vector3">
      <input name="in" type="vector3" nodename="N_remap2_vector3" />
      <input name="low" type="vector3" interfacename="outlow" />
      <input name="high" type="vector3" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_vector3" type="vector3">
      <input name="in1" type="vector3" nodename="N_clamp_vector3" />
      <input name="in2" type="vector3" nodename="N_remap2_vector3" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="vector3" nodename="N_switch_vector3" />
  </nodegraph>
  <nodegraph name="NG_range_vector4" nodedef="ND_range_vector4">
    <remap name="N_remap1_vector4" type="vector4">
      <input name="in" type="vector4" interfacename="in" />
      <input name="inlow" type="vector4" interfacename="inlow" />
      <input name="inhigh" type="vector4" interfacename="inhigh" />
      <input name="outlow" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
      <input name="outhigh" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
    </remap>
    <divide name="N_recip_vector4" type="vector4">
      <input name="in1" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
      <input name="in2" type="vector4" interfacename="gamma" />
    </divide>
    <absval name="N_abs_vector4" type="vector4">
      <input name="in" type="vector4" nodename="N_remap1_vector4" />
    </absval>
    <power name="N_pow_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_abs_vector4" />
      <input name="in2" type="vector4" nodename="N_recip_vector4" />
    </power>
    <sign name="N_sign_vector4" type="vector4">
      <input name="in" type="vector4" nodename="N_remap1_vector4" />
    </sign>
    <multiply name="N_gamma_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_pow_vector4" />
      <input name="in2" type="vector4" nodename="N_sign_vector4" />
    </multiply>
    <remap name="N_remap2_vector4" type="vector4">
      <input name="in" type="vector4" nodename="N_gamma_vector4" />
      <input name="inlow" type="vector4" value="0.0, 0.0, 0.0, 0.0" />
      <input name="inhigh" type="vector4" value="1.0, 1.0, 1.0, 1.0" />
      <input name="outlow" type="vector4" interfacename="outlow" />
      <input name="outhigh" type="vector4" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_vector4" type="vector4">
      <input name="in" type="vector4" nodename="N_remap2_vector4" />
      <input name="low" type="vector4" interfacename="outlow" />
      <input name="high" type="vector4" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_vector4" type="vector4">
      <input name="in1" type="vector4" nodename="N_clamp_vector4" />
      <input name="in2" type="vector4" nodename="N_remap2_vector4" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="vector4" nodename="N_switch_vector4" />
  </nodegraph>
  <nodegraph name="NG_range_color3FA" nodedef="ND_range_color3FA">
    <remap name="N_remap1_color3FA" type="color3">
      <input name="in" type="color3" interfacename="in" />
      <input name="inlow" type="float" interfacename="inlow" />
      <input name="inhigh" type="float" interfacename="inhigh" />
      <input name="outlow" type="float" value="0.0" />
      <input name="outhigh" type="float" value="1.0" />
    </remap>
    <divide name="N_recip_color3FA" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="gamma" />
    </divide>
    <absval name="N_abs_color3FA" type="color3">
      <input name="in" type="color3" nodename="N_remap1_color3FA" />
    </absval>
    <power name="N_pow_color3FA" type="color3">
      <input name="in1" type="color3" nodename="N_abs_color3FA" />
      <input name="in2" type="float" nodename="N_recip_color3FA" />
    </power>
    <sign name="N_sign_color3FA" type="color3">
      <input name="in" type="color3" nodename="N_remap1_color3FA" />
    </sign>
    <multiply name="N_gamma_color3FA" type="color3">
      <input name="in1" type="color3" nodename="N_pow_color3FA" />
      <input name="in2" type="color3" nodename="N_sign_color3FA" />
    </multiply>
    <remap name="N_remap2_color3FA" type="color3">
      <input name="in" type="color3" nodename="N_gamma_color3FA" />
      <input name="inlow" type="float" value="0.0" />
      <input name="inhigh" type="float" value="1.0" />
      <input name="outlow" type="float" interfacename="outlow" />
      <input name="outhigh" type="float" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_color3FA" type="color3">
      <input name="in" type="color3" nodename="N_remap2_color3FA" />
      <input name="low" type="float" interfacename="outlow" />
      <input name="high" type="float" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_color3FA" type="color3">
      <input name="in1" type="color3" nodename="N_clamp_color3FA" />
      <input name="in2" type="color3" nodename="N_remap2_color3FA" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="color3" nodename="N_switch_color3FA" />
  </nodegraph>
  <nodegraph name="NG_range_color4FA" nodedef="ND_range_color4FA">
    <remap name="N_remap1_color4FA" type="color4">
      <input name="in" type="color4" interfacename="in" />
      <input name="inlow" type="float" interfacename="inlow" />
      <input name="inhigh" type="float" interfacename="inhigh" />
      <input name="outlow" type="float" value="0.0" />
      <input name="outhigh" type="float" value="1.0" />
    </remap>
    <divide name="N_recip_color4FA" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="gamma" />
    </divide>
    <absval name="N_abs_color4FA" type="color4">
      <input name="in" type="color4" nodename="N_remap1_color4FA" />
    </absval>
    <power name="N_pow_color4FA" type="color4">
      <input name="in1" type="color4" nodename="N_abs_color4FA" />
      <input name="in2" type="float" nodename="N_recip_color4FA" />
    </power>
    <sign name="N_sign_color4FA" type="color4">
      <input name="in" type="color4" nodename="N_remap1_color4FA" />
    </sign>
    <multiply name="N_gamma_color4FA" type="color4">
      <input name="in1" type="color4" nodename="N_pow_color4FA" />
      <input name="in2" type="color4" nodename="N_sign_color4FA" />
    </multiply>
    <remap name="N_remap2_color4FA" type="color4">
      <input name="in" type="color4" nodename="N_gamma_color4FA" />
      <input name="inlow" type="float" value="0.0" />
      <input name="inhigh" type="float" value="1.0" />
      <input name="outlow" type="float" interfacename="outlow" />
      <input name="outhigh" type="float" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_color4FA" type="color4">
      <input name="in" type="color4" nodename="N_remap2_color4FA" />
      <input name="low" type="float" interfacename="outlow" />
      <input name="high" type="float" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_color4FA" type="color4">
      <input name="in1" type="color4" nodename="N_clamp_color4FA" />
      <input name="in2" type="color4" nodename="N_remap2_color4FA" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="color4" nodename="N_switch_color4FA" />
  </nodegraph>
  <nodegraph name="NG_range_vector2FA" nodedef="ND_range_vector2FA">
    <remap name="N_remap1_vector2FA" type="vector2">
      <input name="in" type="vector2" interfacename="in" />
      <input name="inlow" type="float" interfacename="inlow" />
      <input name="inhigh" type="float" interfacename="inhigh" />
      <input name="outlow" type="float" value="0.0" />
      <input name="outhigh" type="float" value="1.0" />
    </remap>
    <divide name="N_recip_vector2FA" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="gamma" />
    </divide>
    <absval name="N_abs_vector2FA" type="vector2">
      <input name="in" type="vector2" nodename="N_remap1_vector2FA" />
    </absval>
    <power name="N_pow_vector2FA" type="vector2">
      <input name="in1" type="vector2" nodename="N_abs_vector2FA" />
      <input name="in2" type="float" nodename="N_recip_vector2FA" />
    </power>
    <sign name="N_sign_vector2FA" type="vector2">
      <input name="in" type="vector2" nodename="N_remap1_vector2FA" />
    </sign>
    <multiply name="N_gamma_vector2FA" type="vector2">
      <input name="in1" type="vector2" nodename="N_pow_vector2FA" />
      <input name="in2" type="vector2" nodename="N_sign_vector2FA" />
    </multiply>
    <remap name="N_remap2_vector2FA" type="vector2">
      <input name="in" type="vector2" nodename="N_gamma_vector2FA" />
      <input name="inlow" type="float" value="0.0" />
      <input name="inhigh" type="float" value="1.0" />
      <input name="outlow" type="float" interfacename="outlow" />
      <input name="outhigh" type="float" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_vector2FA" type="vector2">
      <input name="in" type="vector2" nodename="N_remap2_vector2FA" />
      <input name="low" type="float" interfacename="outlow" />
      <input name="high" type="float" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_vector2FA" type="vector2">
      <input name="in1" type="vector2" nodename="N_clamp_vector2FA" />
      <input name="in2" type="vector2" nodename="N_remap2_vector2FA" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="vector2" nodename="N_switch_vector2FA" />
  </nodegraph>
  <nodegraph name="NG_range_vector3FA" nodedef="ND_range_vector3FA">
    <remap name="N_remap1_vector3FA" type="vector3">
      <input name="in" type="vector3" interfacename="in" />
      <input name="inlow" type="float" interfacename="inlow" />
      <input name="inhigh" type="float" interfacename="inhigh" />
      <input name="outlow" type="float" value="0.0" />
      <input name="outhigh" type="float" value="1.0" />
    </remap>
    <divide name="N_recip_vector3FA" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="gamma" />
    </divide>
    <absval name="N_abs_vector3FA" type="vector3">
      <input name="in" type="vector3" nodename="N_remap1_vector3FA" />
    </absval>
    <power name="N_pow_vector3FA" type="vector3">
      <input name="in1" type="vector3" nodename="N_abs_vector3FA" />
      <input name="in2" type="float" nodename="N_recip_vector3FA" />
    </power>
    <sign name="N_sign_vector3FA" type="vector3">
      <input name="in" type="vector3" nodename="N_remap1_vector3FA" />
    </sign>
    <multiply name="N_gamma_vector3FA" type="vector3">
      <input name="in1" type="vector3" nodename="N_pow_vector3FA" />
      <input name="in2" type="vector3" nodename="N_sign_vector3FA" />
    </multiply>
    <remap name="N_remap2_vector3FA" type="vector3">
      <input name="in" type="vector3" nodename="N_gamma_vector3FA" />
      <input name="inlow" type="float" value="0.0" />
      <input name="inhigh" type="float" value="1.0" />
      <input name="outlow" type="float" interfacename="outlow" />
      <input name="outhigh" type="float" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_vector3FA" type="vector3">
      <input name="in" type="vector3" nodename="N_remap2_vector3FA" />
      <input name="low" type="float" interfacename="outlow" />
      <input name="high" type="float" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_vector3FA" type="vector3">
      <input name="in1" type="vector3" nodename="N_clamp_vector3FA" />
      <input name="in2" type="vector3" nodename="N_remap2_vector3FA" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="vector3" nodename="N_switch_vector3FA" />
  </nodegraph>
  <nodegraph name="NG_range_vector4FA" nodedef="ND_range_vector4FA">
    <remap name="N_remap1_vector4FA" type="vector4">
      <input name="in" type="vector4" interfacename="in" />
      <input name="inlow" type="float" interfacename="inlow" />
      <input name="inhigh" type="float" interfacename="inhigh" />
      <input name="outlow" type="float" value="0.0" />
      <input name="outhigh" type="float" value="1.0" />
    </remap>
    <divide name="N_recip_vector4FA" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="gamma" />
    </divide>
    <absval name="N_abs_vector4FA" type="vector4">
      <input name="in" type="vector4" nodename="N_remap1_vector4FA" />
    </absval>
    <power name="N_pow_vector4FA" type="vector4">
      <input name="in1" type="vector4" nodename="N_abs_vector4FA" />
      <input name="in2" type="float" nodename="N_recip_vector4FA" />
    </power>
    <sign name="N_sign_vector4FA" type="vector4">
      <input name="in" type="vector4" nodename="N_remap1_vector4FA" />
    </sign>
    <multiply name="N_gamma_vector4FA" type="vector4">
      <input name="in1" type="vector4" nodename="N_pow_vector4FA" />
      <input name="in2" type="vector4" nodename="N_sign_vector4FA" />
    </multiply>
    <remap name="N_remap2_vector4FA" type="vector4">
      <input name="in" type="vector4" nodename="N_gamma_vector4FA" />
      <input name="inlow" type="float" value="0.0" />
      <input name="inhigh" type="float" value="1.0" />
      <input name="outlow" type="float" interfacename="outlow" />
      <input name="outhigh" type="float" interfacename="outhigh" />
    </remap>
    <clamp name="N_clamp_vector4FA" type="vector4">
      <input name="in" type="vector4" nodename="N_remap2_vector4FA" />
      <input name="low" type="float" interfacename="outlow" />
      <input name="high" type="float" interfacename="outhigh" />
    </clamp>
    <ifequal name="N_switch_vector4FA" type="vector4">
      <input name="in1" type="vector4" nodename="N_clamp_vector4FA" />
      <input name="in2" type="vector4" nodename="N_remap2_vector4FA" />
      <input name="value1" type="boolean" interfacename="doclamp" />
      <input name="value2" type="boolean" value="true" />
    </ifequal>
    <output name="out" type="vector4" nodename="N_switch_vector4FA" />
  </nodegraph>

  <!--
    Node: <hsvadjust>
    Adjust the hue, saturation and value of an RGB color by converting the input color
    to HSV, adding amount.x to the hue, multiplying the saturation by amount.y,
    multiplying the value by amount.z, then converting back to RGB.
  -->
  <nodegraph name="NG_hsvadjust_color3" nodedef="ND_hsvadjust_color3">
    <rgbtohsv name="N_inhsv_color3" type="color3">
      <input name="in" type="color3" interfacename="in" />
    </rgbtohsv>
    <convert name="N_camount_color3" type="color3">
      <input name="in" type="vector3" interfacename="amount" />
    </convert>
    <multiply name="N_hchans_color3" type="color3">
      <input name="in1" type="color3" nodename="N_camount_color3" />
      <input name="in2" type="color3" value="1.0, 0.0, 0.0" />
    </multiply>
    <multiply name="N_tmp1_color3" type="color3">
      <input name="in1" type="color3" nodename="N_camount_color3" />
      <input name="in2" type="color3" value="0.0, 1.0, 1.0" />
    </multiply>
    <add name="N_svchans_color3" type="color3">
      <input name="in1" type="color3" nodename="N_tmp1_color3" />
      <input name="in2" type="color3" value="1.0, 0.0, 0.0" />
    </add>
    <add name="N_tmp2_color3" type="color3">
      <input name="in1" type="color3" nodename="N_inhsv_color3" />
      <input name="in2" type="color3" nodename="N_hchans_color3" />
    </add>
    <multiply name="N_tmp3_color3" type="color3">
      <input name="in1" type="color3" nodename="N_tmp2_color3" />
      <input name="in2" type="color3" nodename="N_svchans_color3" />
    </multiply>
    <hsvtorgb name="N_torgb_color3" type="color3">
      <input name="in" type="color3" nodename="N_tmp3_color3" />
    </hsvtorgb>
    <output name="out" type="color3" nodename="N_torgb_color3" />
  </nodegraph>
  <nodegraph name="NG_hsvadjust_color4" nodedef="ND_hsvadjust_color4">
    <rgbtohsv name="N_inhsv_color4" type="color4">
      <input name="in" type="color4" interfacename="in" />
    </rgbtohsv>
    <convert name="N_camt_color3" type="color3">
      <input name="in" type="vector3" interfacename="amount" />
    </convert>
    <convert name="N_camount_color4" type="color4">
      <input name="in" type="color3" nodename="N_camt_color3" />
    </convert>
    <multiply name="N_hchans_color4" type="color4">
      <input name="in1" type="color4" nodename="N_camount_color4" />
      <input name="in2" type="color4" value="1.0, 0.0, 0.0, 0.0" />
    </multiply>
    <multiply name="N_tmp1_color4" type="color4">
      <input name="in1" type="color4" nodename="N_camount_color4" />
      <input name="in2" type="color4" value="0.0, 1.0, 1.0, 0.0" />
    </multiply>
    <add name="N_svchans_color4" type="color4">
      <input name="in1" type="color4" nodename="N_tmp1_color4" />
      <input name="in2" type="color4" value="1.0, 0.0, 0.0, 1.0" />
    </add>
    <add name="N_tmp2_color4" type="color4">
      <input name="in1" type="color4" nodename="N_inhsv_color4" />
      <input name="in2" type="color4" nodename="N_hchans_color4" />
    </add>
    <multiply name="N_tmp3_color4" type="color4">
      <input name="in1" type="color4" nodename="N_tmp2_color4" />
      <input name="in2" type="color4" nodename="N_svchans_color4" />
    </multiply>
    <hsvtorgb name="N_torgb_color4" type="color4">
      <input name="in" type="color4" nodename="N_tmp3_color4" />
    </hsvtorgb>
    <output name="out" type="color4" nodename="N_torgb_color4" />
  </nodegraph>

  <!--
    Node: <saturate>
    Adjust the saturation of a color using a linear interpolation between the incoming
    color and the grayscale luminance of the input computed using the provided luma
    coefficients; the alpha channel will be unchanged if present.
  -->
  <nodegraph name="NG_saturate_color3" nodedef="ND_saturate_color3">
    <luminance name="N_gray_color3" type="color3">
      <input name="in" type="color3" interfacename="in" />
      <input name="lumacoeffs" type="color3" interfacename="lumacoeffs" />
    </luminance>
    <mix name="N_mix_color3" type="color3">
      <input name="bg" type="color3" nodename="N_gray_color3" />
      <input name="fg" type="color3" interfacename="in" />
      <input name="mix" type="float" interfacename="amount" />
    </mix>
    <output name="out" type="color3" nodename="N_mix_color3" />
  </nodegraph>
  <nodegraph name="NG_saturate_color4" nodedef="ND_saturate_color4">
    <luminance name="N_gray_color4" type="color4">
      <input name="in" type="color4" interfacename="in" />
      <input name="lumacoeffs" type="color3" interfacename="lumacoeffs" />
    </luminance>
    <mix name="N_mix_color4" type="color4">
      <input name="bg" type="color4" nodename="N_gray_color4" />
      <input name="fg" type="color4" interfacename="in" />
      <input name="mix" type="float" interfacename="amount" />
    </mix>
    <output name="out" type="color4" nodename="N_mix_color4" />
  </nodegraph>

  <!--
    Node: <colorcorrect>
    Combines various adjustment nodes into one, artist-friendly color correction node.
  -->
  <nodegraph name="NG_colorcorrect_color3" nodedef="ND_colorcorrect_color3">
    <multiply name="N_exposure" type="color3">
      <input name="in1" type="color3" nodename="N_contrast" />
      <input name="in2" type="float" nodename="N_exposurepwr" />
    </multiply>
    <contrast name="N_contrast" type="color3">
      <input name="in" type="color3" nodename="N_gain" />
      <input name="amount" type="float" interfacename="contrast" />
      <input name="pivot" type="float" interfacename="contrastpivot" />
    </contrast>
    <power name="N_exposurepwr" type="float">
      <input name="in2" type="float" interfacename="exposure" />
      <input name="in1" type="float" value="2" />
    </power>
    <multiply name="N_gain" type="color3">
      <input name="in1" type="color3" nodename="N_liftadd" />
      <input name="in2" type="float" interfacename="gain" />
    </multiply>
    <add name="N_liftadd" type="color3">
      <input name="in1" type="color3" nodename="N_liftmult" />
      <input name="in2" type="float" interfacename="lift" />
    </add>
    <multiply name="N_liftmult" type="color3">
      <input name="in1" type="color3" nodename="N_gamma" />
      <input name="in2" type="float" nodename="N_liftsubtract" />
    </multiply>
    <range name="N_gamma" type="color3">
      <input name="in" type="color3" nodename="N_saturation" />
      <input name="gamma" type="float" interfacename="gamma" />
      <input name="inlow" type="float" value="0" />
      <input name="inhigh" type="float" value="1" />
      <input name="outlow" type="float" value="0" />
      <input name="outhigh" type="float" value="1" />
      <input name="doclamp" type="boolean" value="false" />
    </range>
    <subtract name="N_liftsubtract" type="float">
      <input name="in2" type="float" interfacename="lift" />
      <input name="in1" type="float" value="1" />
    </subtract>
    <saturate name="N_saturation" type="color3">
      <input name="in" type="color3" nodename="N_hsvadjust" />
      <input name="amount" type="float" interfacename="saturation" />
    </saturate>
    <hsvadjust name="N_hsvadjust" type="color3">
      <input name="in" type="color3" interfacename="in" />
      <input name="amount" type="vector3" nodename="N_parm2hue" />
    </hsvadjust>
    <combine3 name="N_parm2hue" type="vector3">
      <input name="in1" type="float" interfacename="hue" />
      <input name="in2" type="float" value="1" />
      <input name="in3" type="float" value="1" />
    </combine3>
    <output name="out" type="color3" nodename="N_exposure" />
  </nodegraph>
  <nodegraph name="NG_colorcorrect_color4" nodedef="ND_colorcorrect_color4">
    <separate4 name="N_split_color4" type="multioutput">
      <input name="in" type="color4" interfacename="in" />
    </separate4>
    <combine3 name="N_combine_color" type="color3">
      <input name="in1" type="float" nodename="N_split_color4" output="outr" />
      <input name="in2" type="float" nodename="N_split_color4" output="outg" />
      <input name="in3" type="float" nodename="N_split_color4" output="outb" />
    </combine3>
    <colorcorrect name="N_colorcorrect" type="color3">
      <input name="in" type="color3" nodename="N_combine_color" />
      <input name="hue" type="float" interfacename="hue" />
      <input name="saturation" type="float" interfacename="saturation" />
      <input name="gamma" type="float" interfacename="gamma" />
      <input name="lift" type="float" interfacename="lift" />
      <input name="gain" type="float" interfacename="gain" />
      <input name="contrast" type="float" interfacename="contrast" />
      <input name="contrastpivot" type="float" interfacename="contrastpivot" />
      <input name="exposure" type="float" interfacename="exposure" />
    </colorcorrect>
    <separate3 name="N_split_color" type="multioutput">
      <input name="in" type="color3" nodename="N_colorcorrect" />
    </separate3>
    <combine4 name="N_combine_with_alpha" type="color4">
      <input name="in1" type="float" nodename="N_split_color" output="outr" />
      <input name="in2" type="float" nodename="N_split_color" output="outg" />
      <input name="in3" type="float" nodename="N_split_color" output="outb" />
      <input name="in4" type="float" nodename="N_split_color4" output="outa" />
    </combine4>
    <output name="out" type="color4" nodename="N_combine_with_alpha" />
  </nodegraph>

  <!-- ======================================================================== -->
  <!-- Compositing nodes                                                        -->
  <!-- ======================================================================== -->

  <!--
    Node: <overlay>
    Overlay is a compositing node which is a combination of multiply and screen.
  -->
  <nodegraph name="NG_overlay_float" nodedef="ND_overlay_float">
    <output name="out" type="float" nodename="N_mix" />
    <ifgreatereq name="N_ifgreatereq0_overlay_r" type="float" nodedef="ND_ifgreatereq_float">
      <input name="value1" type="float" interfacename="bg" />
      <input name="value2" type="float" value="0.5" />
      <input name="in1" type="float" nodename="N_subtract_lower_one" />
      <input name="in2" type="float" nodename="N_multiply_upper_two" />
    </ifgreatereq>
    <multiply name="N_multiply_upper_fg_bg" type="float" nodedef="ND_multiply_float">
      <input name="in1" type="float" interfacename="fg" />
      <input name="in2" type="float" interfacename="bg" />
    </multiply>
    <multiply name="N_multiply_upper_two" type="float" nodedef="ND_multiply_float">
      <input name="in1" type="float" nodename="N_multiply_upper_fg_bg" />
      <input name="in2" type="float" value="2" />
    </multiply>
    <subtract name="N_subtract_lower_one_bg" type="float" nodedef="ND_subtract_float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" interfacename="bg" />
    </subtract>
    <subtract name="N_subtract_lower_one_fg" type="float" nodedef="ND_subtract_float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" interfacename="fg" />
    </subtract>
    <multiply name="N_multiply_lower_fg_bg" type="float" nodedef="ND_multiply_float">
      <input name="in1" type="float" nodename="N_subtract_lower_one_bg" />
      <input name="in2" type="float" nodename="N_subtract_lower_one_fg" />
    </multiply>
    <subtract name="N_subtract_lower_one" type="float" nodedef="ND_subtract_float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" nodename="N_multiply_lower_two" />
    </subtract>
    <mix name="N_mix" type="float" nodedef="ND_mix_float">
      <input name="fg" type="float" nodename="N_ifgreatereq0_overlay_r" />
      <input name="bg" type="float" interfacename="bg" />
      <input name="mix" type="float" interfacename="mix" />
    </mix>
    <multiply name="N_multiply_lower_two" type="float" nodedef="ND_multiply_float">
      <input name="in1" type="float" nodename="N_multiply_lower_fg_bg" />
      <input name="in2" type="float" value="2" />
    </multiply>
  </nodegraph>
  <nodegraph name="NG_overlay_color3" nodedef="ND_overlay_color3">
    <output name="out" type="color3" nodename="N_combine" />
    <separate3 name="N_split_color3_fg" type="multioutput">
      <input name="in" type="color3" interfacename="fg" />
    </separate3>
    <separate3 name="N_split_color3_bg" type="multioutput">
      <input name="in" type="color3" interfacename="bg" />
    </separate3>
    <combine3 name="N_combine" type="color3" nodedef="ND_combine3_color3">
      <input name="in1" type="float" nodename="N_overlay_r" />
      <input name="in2" type="float" nodename="N_overlay_g" />
      <input name="in3" type="float" nodename="N_overlay_b" />
    </combine3>
    <overlay name="N_overlay_r" type="float" nodedef="ND_overlay_float">
      <input name="fg" type="float" nodename="N_split_color3_fg" output="outr" />
      <input name="bg" type="float" nodename="N_split_color3_bg" output="outr" />
      <input name="mix" type="float" interfacename="mix" />
    </overlay>
    <overlay name="N_overlay_g" type="float" nodedef="ND_overlay_float">
      <input name="fg" type="float" nodename="N_split_color3_fg" output="outg" />
      <input name="bg" type="float" nodename="N_split_color3_bg" output="outg" />
      <input name="mix" type="float" interfacename="mix" />
    </overlay>
    <overlay name="N_overlay_b" type="float" nodedef="ND_overlay_float">
      <input name="fg" type="float" nodename="N_split_color3_fg" output="outb" />
      <input name="bg" type="float" nodename="N_split_color3_bg" output="outb" />
      <input name="mix" type="float" interfacename="mix" />
    </overlay>
  </nodegraph>
  <nodegraph name="NG_overlay_color4" nodedef="ND_overlay_color4">
    <output name="out" type="color4" nodename="N_combine" />
    <separate4 name="N_split_fg" type="multioutput">
      <input name="in" type="color4" interfacename="fg" />
    </separate4>
    <separate4 name="N_split_bg" type="multioutput">
      <input name="in" type="color4" interfacename="bg" />
    </separate4>
    <overlay name="N_overlay_r" type="float" nodedef="ND_overlay_float">
      <input name="fg" type="float" nodename="N_split_fg" output="outr" />
      <input name="bg" type="float" nodename="N_split_bg" output="outr" />
      <input name="mix" type="float" interfacename="mix" />
    </overlay>
    <overlay name="N_overlay_g" type="float" nodedef="ND_overlay_float">
      <input name="fg" type="float" nodename="N_split_fg" output="outg" />
      <input name="bg" type="float" nodename="N_split_bg" output="outg" />
      <input name="mix" type="float" interfacename="mix" />
    </overlay>
    <overlay name="N_overlay_b" type="float" nodedef="ND_overlay_float">
      <input name="fg" type="float" nodename="N_split_fg" output="outb" />
      <input name="bg" type="float" nodename="N_split_bg" output="outb" />
      <input name="mix" type="float" interfacename="mix" />
    </overlay>
    <overlay name="N_overlay_a" type="float" nodedef="ND_overlay_float">
      <input name="fg" type="float" nodename="N_split_fg" output="outa" />
      <input name="bg" type="float" nodename="N_split_bg" output="outa" />
      <input name="mix" type="float" interfacename="mix" />
    </overlay>
    <combine4 name="N_combine" type="color4" nodedef="ND_combine4_color4">
      <input name="in1" type="float" nodename="N_overlay_r" />
      <input name="in2" type="float" nodename="N_overlay_g" />
      <input name="in3" type="float" nodename="N_overlay_b" />
      <input name="in4" type="float" nodename="N_overlay_a" />
    </combine4>
  </nodegraph>

  <!-- ======================================================================== -->
  <!-- Conditional nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- ======================================================================== -->
  <!-- Channel nodes                                                            -->
  <!-- ======================================================================== -->

  <!--
    Node: <convert>
    Convert a stream from one type to another; only certain unambiguous conversion
    types are supported.
  -->
  <nodegraph name="NG_convert_float_color3" nodedef="ND_convert_float_color3">
    <combine3 name="combine" type="color3">
      <input name="in1" type="float" interfacename="in" />
      <input name="in2" type="float" interfacename="in" />
      <input name="in3" type="float" interfacename="in" />
    </combine3>
    <output name="out" type="color3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_float_color4" nodedef="ND_convert_float_color4">
    <combine4 name="combine" type="color4">
      <input name="in1" type="float" interfacename="in" />
      <input name="in2" type="float" interfacename="in" />
      <input name="in3" type="float" interfacename="in" />
      <input name="in4" type="float" interfacename="in" />
    </combine4>
    <output name="out" type="color4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_float_vector2" nodedef="ND_convert_float_vector2">
    <combine2 name="combine" type="vector2">
      <input name="in1" type="float" interfacename="in" />
      <input name="in2" type="float" interfacename="in" />
    </combine2>
    <output name="out" type="vector2" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_float_vector3" nodedef="ND_convert_float_vector3">
    <combine3 name="combine" type="vector3">
      <input name="in1" type="float" interfacename="in" />
      <input name="in2" type="float" interfacename="in" />
      <input name="in3" type="float" interfacename="in" />
    </combine3>
    <output name="out" type="vector3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_float_vector4" nodedef="ND_convert_float_vector4">
    <combine4 name="combine" type="vector4">
      <input name="in1" type="float" interfacename="in" />
      <input name="in2" type="float" interfacename="in" />
      <input name="in3" type="float" interfacename="in" />
      <input name="in4" type="float" interfacename="in" />
    </combine4>
    <output name="out" type="vector4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_color3_color4" nodedef="ND_convert_color3_color4">
    <separate3 name="separate" type="multioutput">
      <input name="in" type="color3" interfacename="in" />
    </separate3>
    <combine4 name="combine" type="color4">
      <input name="in1" type="float" nodename="separate" output="outr" />
      <input name="in2" type="float" nodename="separate" output="outg" />
      <input name="in3" type="float" nodename="separate" output="outb" />
      <input name="in4" type="float" value="1.0" />
    </combine4>
    <output name="out" type="color4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_color3_vector2" nodedef="ND_convert_color3_vector2">
    <separate3 name="separate" type="multioutput">
      <input name="in" type="color3" interfacename="in" />
    </separate3>
    <combine2 name="combine" type="vector2">
      <input name="in1" type="float" nodename="separate" output="outr" />
      <input name="in2" type="float" nodename="separate" output="outg" />
    </combine2>
    <output name="out" type="vector2" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_color3_vector3" nodedef="ND_convert_color3_vector3">
    <separate3 name="separate" type="multioutput">
      <input name="in" type="color3" interfacename="in" />
    </separate3>
    <combine3 name="combine" type="vector3">
      <input name="in1" type="float" nodename="separate" output="outr" />
      <input name="in2" type="float" nodename="separate" output="outg" />
      <input name="in3" type="float" nodename="separate" output="outb" />
    </combine3>
    <output name="out" type="vector3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_color3_vector4" nodedef="ND_convert_color3_vector4">
    <separate3 name="separate" type="multioutput">
      <input name="in" type="color3" interfacename="in" />
    </separate3>
    <combine4 name="combine" type="vector4">
      <input name="in1" type="float" nodename="separate" output="outr" />
      <input name="in2" type="float" nodename="separate" output="outg" />
      <input name="in3" type="float" nodename="separate" output="outb" />
      <input name="in4" type="float" value="1.0" />
    </combine4>
    <output name="out" type="vector4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_color4_color3" nodedef="ND_convert_color4_color3">
    <separate4 name="separate" type="multioutput">
      <input name="in" type="color4" interfacename="in" />
    </separate4>
    <combine3 name="combine" type="color3">
      <input name="in1" type="float" nodename="separate" output="outr" />
      <input name="in2" type="float" nodename="separate" output="outg" />
      <input name="in3" type="float" nodename="separate" output="outb" />
    </combine3>
    <output name="out" type="color3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_color4_vector2" nodedef="ND_convert_color4_vector2">
    <separate4 name="separate" type="multioutput">
      <input name="in" type="color4" interfacename="in" />
    </separate4>
    <combine2 name="combine" type="vector2">
      <input name="in1" type="float" nodename="separate" output="outr" />
      <input name="in2" type="float" nodename="separate" output="outg" />
    </combine2>
    <output name="out" type="vector2" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_color4_vector3" nodedef="ND_convert_color4_vector3">
    <separate4 name="separate" type="multioutput">
      <input name="in" type="color4" interfacename="in" />
    </separate4>
    <combine3 name="combine" type="vector3">
      <input name="in1" type="float" nodename="separate" output="outr" />
      <input name="in2" type="float" nodename="separate" output="outg" />
      <input name="in3" type="float" nodename="separate" output="outb" />
    </combine3>
    <output name="out" type="vector3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_color4_vector4" nodedef="ND_convert_color4_vector4">
    <separate4 name="separate" type="multioutput">
      <input name="in" type="color4" interfacename="in" />
    </separate4>
    <combine4 name="combine" type="vector4">
      <input name="in1" type="float" nodename="separate" output="outr" />
      <input name="in2" type="float" nodename="separate" output="outg" />
      <input name="in3" type="float" nodename="separate" output="outb" />
      <input name="in4" type="float" nodename="separate" output="outa" />
    </combine4>
    <output name="out" type="vector4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector2_color3" nodedef="ND_convert_vector2_color3">
    <separate2 name="separate" type="multioutput">
      <input name="in" type="vector2" interfacename="in" />
    </separate2>
    <combine3 name="combine" type="color3">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" value="0.0" />
    </combine3>
    <output name="out" type="color3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector2_color4" nodedef="ND_convert_vector2_color4">
    <separate2 name="separate" type="multioutput">
      <input name="in" type="vector2" interfacename="in" />
    </separate2>
    <combine4 name="combine" type="color4">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" value="0.0" />
      <input name="in4" type="float" value="1.0" />
    </combine4>
    <output name="out" type="color4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector2_vector3" nodedef="ND_convert_vector2_vector3">
    <separate2 name="separate" type="multioutput">
      <input name="in" type="vector2" interfacename="in" />
    </separate2>
    <combine3 name="combine" type="vector3">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" value="0.0" />
    </combine3>
    <output name="out" type="vector3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector2_vector4" nodedef="ND_convert_vector2_vector4">
    <separate2 name="separate" type="multioutput">
      <input name="in" type="vector2" interfacename="in" />
    </separate2>
    <combine4 name="combine" type="vector4">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" value="0.0" />
      <input name="in4" type="float" value="1.0" />
    </combine4>
    <output name="out" type="vector4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector3_color3" nodedef="ND_convert_vector3_color3">
    <separate3 name="separate" type="multioutput">
      <input name="in" type="vector3" interfacename="in" />
    </separate3>
    <combine3 name="combine" type="color3">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" nodename="separate" output="outz" />
    </combine3>
    <output name="out" type="color3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector3_color4" nodedef="ND_convert_vector3_color4">
    <separate3 name="separate" type="multioutput">
      <input name="in" type="vector3" interfacename="in" />
    </separate3>
    <combine4 name="combine" type="color4">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" nodename="separate" output="outz" />
      <input name="in4" type="float" value="1.0" />
    </combine4>
    <output name="out" type="color4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector3_vector2" nodedef="ND_convert_vector3_vector2">
    <separate3 name="separate" type="multioutput">
      <input name="in" type="vector3" interfacename="in" />
    </separate3>
    <combine2 name="combine" type="vector2">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
    </combine2>
    <output name="out" type="vector2" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector3_vector4" nodedef="ND_convert_vector3_vector4">
    <separate3 name="separate" type="multioutput">
      <input name="in" type="vector3" interfacename="in" />
    </separate3>
    <combine4 name="combine" type="vector4">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" nodename="separate" output="outz" />
      <input name="in4" type="float" value="1.0" />
    </combine4>
    <output name="out" type="vector4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector4_color3" nodedef="ND_convert_vector4_color3">
    <separate4 name="separate" type="multioutput">
      <input name="in" type="vector4" interfacename="in" />
    </separate4>
    <combine3 name="combine" type="color3">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" nodename="separate" output="outz" />
    </combine3>
    <output name="out" type="color3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector4_color4" nodedef="ND_convert_vector4_color4">
    <separate4 name="separate" type="multioutput">
      <input name="in" type="vector4" interfacename="in" />
    </separate4>
    <combine4 name="combine" type="color4">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" nodename="separate" output="outz" />
      <input name="in4" type="float" nodename="separate" output="outw" />
    </combine4>
    <output name="out" type="color4" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector4_vector2" nodedef="ND_convert_vector4_vector2">
    <separate4 name="separate" type="multioutput">
      <input name="in" type="vector4" interfacename="in" />
    </separate4>
    <combine2 name="combine" type="vector2">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
    </combine2>
    <output name="out" type="vector2" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_vector4_vector3" nodedef="ND_convert_vector4_vector3">
    <separate4 name="separate" type="multioutput">
      <input name="in" type="vector4" interfacename="in" />
    </separate4>
    <combine3 name="combine" type="vector3">
      <input name="in1" type="float" nodename="separate" output="outx" />
      <input name="in2" type="float" nodename="separate" output="outy" />
      <input name="in3" type="float" nodename="separate" output="outz" />
    </combine3>
    <output name="out" type="vector3" nodename="combine" />
  </nodegraph>
  <nodegraph name="NG_convert_boolean_color3" nodedef="ND_convert_boolean_color3">
    <convert name="convert_to_float" type="float">
      <input name="in" type="boolean" interfacename="in" />
    </convert>
    <convert name="convert" type="color3">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="color3" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_boolean_color4" nodedef="ND_convert_boolean_color4">
    <convert name="convert_to_float" type="float">
      <input name="in" type="boolean" interfacename="in" />
    </convert>
    <convert name="convert" type="color4">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="color4" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_boolean_vector2" nodedef="ND_convert_boolean_vector2">
    <convert name="convert_to_float" type="float">
      <input name="in" type="boolean" interfacename="in" />
    </convert>
    <convert name="convert" type="vector2">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="vector2" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_boolean_vector3" nodedef="ND_convert_boolean_vector3">
    <convert name="convert_to_float" type="float">
      <input name="in" type="boolean" interfacename="in" />
    </convert>
    <convert name="convert" type="vector3">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="vector3" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_boolean_vector4" nodedef="ND_convert_boolean_vector4">
    <convert name="convert_to_float" type="float">
      <input name="in" type="boolean" interfacename="in" />
    </convert>
    <convert name="convert" type="vector4">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="vector4" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_boolean_integer" nodedef="ND_convert_boolean_integer">
    <ifequal name="ifequal" type="integer">
      <input name="value1" type="boolean" interfacename="in" />
      <input name="value2" type="boolean" value="true" />
      <input name="in1" type="integer" value="1" />
      <input name="in2" type="integer" value="0" />
    </ifequal>
    <output name="out" type="integer" nodename="ifequal" />
  </nodegraph>
  <nodegraph name="NG_convert_integer_color3" nodedef="ND_convert_integer_color3">
    <convert name="convert_to_float" type="float">
      <input name="in" type="integer" interfacename="in" />
    </convert>
    <convert name="convert" type="color3">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="color3" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_integer_color4" nodedef="ND_convert_integer_color4">
    <convert name="convert_to_float" type="float">
      <input name="in" type="integer" interfacename="in" />
    </convert>
    <convert name="convert" type="color4">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="color4" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_integer_vector2" nodedef="ND_convert_integer_vector2">
    <convert name="convert_to_float" type="float">
      <input name="in" type="integer" interfacename="in" />
    </convert>
    <convert name="convert" type="vector2">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="vector2" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_integer_vector3" nodedef="ND_convert_integer_vector3">
    <convert name="convert_to_float" type="float">
      <input name="in" type="integer" interfacename="in" />
    </convert>
    <convert name="convert" type="vector3">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="vector3" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_integer_vector4" nodedef="ND_convert_integer_vector4">
    <convert name="convert_to_float" type="float">
      <input name="in" type="integer" interfacename="in" />
    </convert>
    <convert name="convert" type="vector4">
      <input name="in" type="float" nodename="convert_to_float" />
    </convert>
    <output name="out" type="vector4" nodename="convert" />
  </nodegraph>
  <nodegraph name="NG_convert_integer_boolean" nodedef="ND_convert_integer_boolean">
    <ifequal name="ifequal" type="boolean">
      <input name="value1" type="integer" interfacename="in" />
      <input name="value2" type="integer" value="0" />
    </ifequal>
    <not name="not" type="boolean">
      <input name="in" type="boolean" nodename="ifequal" />
    </not>
    <output name="out" type="boolean" nodename="not" />
  </nodegraph>
  <nodegraph name="NG_convert_color3_surfaceshader" nodedef="ND_convert_color3_surfaceshader">
    <surface_unlit name="surface" type="surfaceshader">
      <input name="emission_color" type="color3" interfacename="in" />
    </surface_unlit>
    <output name="out" type="surfaceshader" nodename="surface" />
  </nodegraph>
  <nodegraph name="NG_convert_color4_surfaceshader" nodedef="ND_convert_color4_surfaceshader">
    <surface_unlit name="surface" type="surfaceshader">
      <input name="emission_color" type="color3" nodename="convert" />
      <input name="opacity" type="float" nodename="extract" />
    </surface_unlit>
    <extract name="extract" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" uniform="true" value="3" />
    </extract>
    <convert name="convert" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <output name="out" type="surfaceshader" nodename="surface" />
  </nodegraph>
  <nodegraph name="NG_convert_float_surfaceshader" nodedef="ND_convert_float_surfaceshader">
    <convert name="float_to_color3" type="color3">
      <input name="in" type="float" interfacename="in" />
    </convert>
    <surface_unlit name="surface" type="surfaceshader">
      <input name="emission_color" type="color3" nodename="float_to_color3" />
    </surface_unlit>
    <output name="out" type="surfaceshader" nodename="surface" />
  </nodegraph>
  <nodegraph name="NG_convert_vector2_surfaceshader" nodedef="ND_convert_vector2_surfaceshader">
    <surface_unlit name="surface" type="surfaceshader">
      <input name="emission_color" type="color3" nodename="vec3_to_color3" />
    </surface_unlit>
    <convert name="vec2_to_vec3" type="vector3">
      <input name="in" type="vector2" interfacename="in" />
    </convert>
    <convert name="vec3_to_color3" type="color3">
      <input name="in" type="vector3" nodename="vec2_to_vec3" />
    </convert>
    <output name="out" type="surfaceshader" nodename="surface" />
  </nodegraph>
  <nodegraph name="NG_convert_vector3_surfaceshader" nodedef="ND_convert_vector3_surfaceshader">
    <surface_unlit name="surface" type="surfaceshader">
      <input name="emission_color" type="color3" nodename="vec3_to_color3" />
    </surface_unlit>
    <convert name="vec3_to_color3" type="color3">
      <input name="in" type="vector3" interfacename="in" />
    </convert>
    <output name="out" type="surfaceshader" nodename="surface" />
  </nodegraph>
  <nodegraph name="NG_convert_vector4_surfaceshader" nodedef="ND_convert_vector4_surfaceshader">
    <surface_unlit name="surface" type="surfaceshader">
      <input name="emission_color" type="color3" nodename="color4_to_color3" />
      <input name="opacity" type="float" nodename="color4_to_float" />
    </surface_unlit>
    <convert name="vec4_to_color4" type="color4">
      <input name="in" type="vector4" interfacename="in" />
    </convert>
    <extract name="color4_to_float" type="float">
      <input name="in" type="color4" nodename="vec4_to_color4" />
      <input name="index" type="integer" uniform="true" value="3" />
    </extract>
    <convert name="color4_to_color3" type="color3">
      <input name="in" type="color4" nodename="vec4_to_color4" />
    </convert>
    <output name="out" type="surfaceshader" nodename="surface" />
  </nodegraph>
  <nodegraph name="NG_convert_integer_surfaceshader" nodedef="ND_convert_integer_surfaceshader">
    <convert name="int_to_float" type="float">
      <input name="in" type="integer" interfacename="in" />
    </convert>
    <convert name="float_to_color3" type="color3">
      <input name="in" type="float" nodename="int_to_float" />
    </convert>
    <surface_unlit name="surface" type="surfaceshader">
      <input name="emission_color" type="color3" nodename="float_to_color3" />
    </surface_unlit>
    <output name="out" type="surfaceshader" nodename="surface" />
  </nodegraph>
  <nodegraph name="NG_convert_boolean_surfaceshader" nodedef="ND_convert_boolean_surfaceshader">
    <convert name="bool_to_float" type="float">
      <input name="in" type="boolean" interfacename="in" />
    </convert>
    <convert name="float_to_color3" type="color3">
      <input name="in" type="float" nodename="bool_to_float" />
    </convert>
    <surface_unlit name="surface" type="surfaceshader">
      <input name="emission_color" type="color3" nodename="float_to_color3" />
    </surface_unlit>
    <output name="out" type="surfaceshader" nodename="surface" />
  </nodegraph>

  <!--
    Nodes: <separate2>, <separate3>, <separate4>
    Output each of the channels of a color/vector stream as a separate float output.
  -->
  <nodegraph name="NG_separate3_color3" nodedef="ND_separate3_color3">
    <extract name="N_extract_0" type="float">
      <input name="in" type="color3" interfacename="in" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extract_1" type="float">
      <input name="in" type="color3" interfacename="in" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extract_2" type="float">
      <input name="in" type="color3" interfacename="in" />
      <input name="index" type="integer" value="2" />
    </extract>
    <output name="outr" type="float" nodename="N_extract_0" />
    <output name="outg" type="float" nodename="N_extract_1" />
    <output name="outb" type="float" nodename="N_extract_2" />
  </nodegraph>
  <nodegraph name="NG_separate4_color4" nodedef="ND_separate4_color4">
    <extract name="N_extract_0" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extract_1" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extract_2" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="2" />
    </extract>
    <extract name="N_extract_3" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <output name="outr" type="float" nodename="N_extract_0" />
    <output name="outg" type="float" nodename="N_extract_1" />
    <output name="outb" type="float" nodename="N_extract_2" />
    <output name="outa" type="float" nodename="N_extract_3" />
  </nodegraph>
  <nodegraph name="NG_separate2_vector2" nodedef="ND_separate2_vector2">
    <extract name="N_extract_0" type="float">
      <input name="in" type="vector2" interfacename="in" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extract_1" type="float">
      <input name="in" type="vector2" interfacename="in" />
      <input name="index" type="integer" value="1" />
    </extract>
    <output name="outx" type="float" nodename="N_extract_0" />
    <output name="outy" type="float" nodename="N_extract_1" />
  </nodegraph>
  <nodegraph name="NG_separate3_vector3" nodedef="ND_separate3_vector3">
    <extract name="N_extract_0" type="float">
      <input name="in" type="vector3" interfacename="in" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extract_1" type="float">
      <input name="in" type="vector3" interfacename="in" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extract_2" type="float">
      <input name="in" type="vector3" interfacename="in" />
      <input name="index" type="integer" value="2" />
    </extract>
    <output name="outx" type="float" nodename="N_extract_0" />
    <output name="outy" type="float" nodename="N_extract_1" />
    <output name="outz" type="float" nodename="N_extract_2" />
  </nodegraph>
  <nodegraph name="NG_separate4_vector4" nodedef="ND_separate4_vector4">
    <extract name="N_extract_0" type="float">
      <input name="in" type="vector4" interfacename="in" />
      <input name="index" type="integer" value="0" />
    </extract>
    <extract name="N_extract_1" type="float">
      <input name="in" type="vector4" interfacename="in" />
      <input name="index" type="integer" value="1" />
    </extract>
    <extract name="N_extract_2" type="float">
      <input name="in" type="vector4" interfacename="in" />
      <input name="index" type="integer" value="2" />
    </extract>
    <extract name="N_extract_3" type="float">
      <input name="in" type="vector4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <output name="outx" type="float" nodename="N_extract_0" />
    <output name="outy" type="float" nodename="N_extract_1" />
    <output name="outz" type="float" nodename="N_extract_2" />
    <output name="outw" type="float" nodename="N_extract_3" />
  </nodegraph>

  <!-- ======================================================================== -->
  <!-- Switch nodes                                                             -->
  <!-- ======================================================================== -->

  <nodegraph name="NG_switch_float" nodedef="ND_switch_float">
    <ifgreater name="ifgreater_10" type="float">
      <input name="value1" type="float" value="10.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in10" />
      <input name="in2" type="float" value="0.0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="float">
      <input name="value1" type="float" value="9.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in9" />
      <input name="in2" type="float" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="float">
      <input name="value1" type="float" value="8.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in8" />
      <input name="in2" type="float" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="float">
      <input name="value1" type="float" value="7.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in7" />
      <input name="in2" type="float" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="float">
      <input name="value1" type="float" value="6.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in6" />
      <input name="in2" type="float" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="float">
      <input name="value1" type="float" value="5.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in5" />
      <input name="in2" type="float" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="float">
      <input name="value1" type="float" value="4.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in4" />
      <input name="in2" type="float" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="float">
      <input name="value1" type="float" value="3.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in3" />
      <input name="in2" type="float" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="float">
      <input name="value1" type="float" value="2.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in2" />
      <input name="in2" type="float" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="float">
      <input name="value1" type="float" value="1.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="float" interfacename="in1" />
      <input name="in2" type="float" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="float" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_color3" nodedef="ND_switch_color3">
    <ifgreater name="ifgreater_10" type="color3">
      <input name="value1" type="float" value="10.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in10" />
      <input name="in2" type="color3" value="0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="color3">
      <input name="value1" type="float" value="9.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in9" />
      <input name="in2" type="color3" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="color3">
      <input name="value1" type="float" value="8.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in8" />
      <input name="in2" type="color3" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="color3">
      <input name="value1" type="float" value="7.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in7" />
      <input name="in2" type="color3" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="color3">
      <input name="value1" type="float" value="6.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in6" />
      <input name="in2" type="color3" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="color3">
      <input name="value1" type="float" value="5.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in5" />
      <input name="in2" type="color3" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="color3">
      <input name="value1" type="float" value="4.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in4" />
      <input name="in2" type="color3" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="color3">
      <input name="value1" type="float" value="3.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in3" />
      <input name="in2" type="color3" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="color3">
      <input name="value1" type="float" value="2.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in2" />
      <input name="in2" type="color3" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="color3">
      <input name="value1" type="float" value="1.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color3" interfacename="in1" />
      <input name="in2" type="color3" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="color3" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_color4" nodedef="ND_switch_color4">
    <ifgreater name="ifgreater_10" type="color4">
      <input name="value1" type="float" value="10.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in10" />
      <input name="in2" type="color4" value="0,0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="color4">
      <input name="value1" type="float" value="9.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in9" />
      <input name="in2" type="color4" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="color4">
      <input name="value1" type="float" value="8.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in8" />
      <input name="in2" type="color4" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="color4">
      <input name="value1" type="float" value="7.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in7" />
      <input name="in2" type="color4" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="color4">
      <input name="value1" type="float" value="6.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in6" />
      <input name="in2" type="color4" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="color4">
      <input name="value1" type="float" value="5.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in5" />
      <input name="in2" type="color4" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="color4">
      <input name="value1" type="float" value="4.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in4" />
      <input name="in2" type="color4" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="color4">
      <input name="value1" type="float" value="3.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in3" />
      <input name="in2" type="color4" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="color4">
      <input name="value1" type="float" value="2.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in2" />
      <input name="in2" type="color4" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="color4">
      <input name="value1" type="float" value="1.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="color4" interfacename="in1" />
      <input name="in2" type="color4" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="color4" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_vector2" nodedef="ND_switch_vector2">
    <ifgreater name="ifgreater_10" type="vector2">
      <input name="value1" type="float" value="10.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in10" />
      <input name="in2" type="vector2" value="0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="vector2">
      <input name="value1" type="float" value="9.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in9" />
      <input name="in2" type="vector2" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="vector2">
      <input name="value1" type="float" value="8.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in8" />
      <input name="in2" type="vector2" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="vector2">
      <input name="value1" type="float" value="7.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in7" />
      <input name="in2" type="vector2" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="vector2">
      <input name="value1" type="float" value="6.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in6" />
      <input name="in2" type="vector2" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="vector2">
      <input name="value1" type="float" value="5.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in5" />
      <input name="in2" type="vector2" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="vector2">
      <input name="value1" type="float" value="4.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in4" />
      <input name="in2" type="vector2" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="vector2">
      <input name="value1" type="float" value="3.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in3" />
      <input name="in2" type="vector2" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="vector2">
      <input name="value1" type="float" value="2.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in2" />
      <input name="in2" type="vector2" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="vector2">
      <input name="value1" type="float" value="1.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in1" />
      <input name="in2" type="vector2" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="vector2" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_vector3" nodedef="ND_switch_vector3">
    <ifgreater name="ifgreater_10" type="vector3">
      <input name="value1" type="float" value="10.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in10" />
      <input name="in2" type="vector3" value="0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="vector3">
      <input name="value1" type="float" value="9.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in9" />
      <input name="in2" type="vector3" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="vector3">
      <input name="value1" type="float" value="8.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in8" />
      <input name="in2" type="vector3" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="vector3">
      <input name="value1" type="float" value="7.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in7" />
      <input name="in2" type="vector3" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="vector3">
      <input name="value1" type="float" value="6.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in6" />
      <input name="in2" type="vector3" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="vector3">
      <input name="value1" type="float" value="5.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in5" />
      <input name="in2" type="vector3" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="vector3">
      <input name="value1" type="float" value="4.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in4" />
      <input name="in2" type="vector3" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="vector3">
      <input name="value1" type="float" value="3.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in3" />
      <input name="in2" type="vector3" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="vector3">
      <input name="value1" type="float" value="2.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in2" />
      <input name="in2" type="vector3" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="vector3">
      <input name="value1" type="float" value="1.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in1" />
      <input name="in2" type="vector3" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="vector3" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_vector4" nodedef="ND_switch_vector4">
    <ifgreater name="ifgreater_10" type="vector4">
      <input name="value1" type="float" value="10.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in10" />
      <input name="in2" type="vector4" value="0,0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="vector4">
      <input name="value1" type="float" value="9.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in9" />
      <input name="in2" type="vector4" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="vector4">
      <input name="value1" type="float" value="8.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in8" />
      <input name="in2" type="vector4" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="vector4">
      <input name="value1" type="float" value="7.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in7" />
      <input name="in2" type="vector4" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="vector4">
      <input name="value1" type="float" value="6.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in6" />
      <input name="in2" type="vector4" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="vector4">
      <input name="value1" type="float" value="5.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in5" />
      <input name="in2" type="vector4" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="vector4">
      <input name="value1" type="float" value="4.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in4" />
      <input name="in2" type="vector4" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="vector4">
      <input name="value1" type="float" value="3.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in3" />
      <input name="in2" type="vector4" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="vector4">
      <input name="value1" type="float" value="2.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in2" />
      <input name="in2" type="vector4" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="vector4">
      <input name="value1" type="float" value="1.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in1" />
      <input name="in2" type="vector4" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="vector4" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_matrix33" nodedef="ND_switch_matrix33">
    <ifgreater name="ifgreater_10" type="matrix33">
      <input name="value1" type="float" value="10.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in10" />
      <input name="in2" type="matrix33" value="0,0,0,0,0,0,0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="matrix33">
      <input name="value1" type="float" value="9.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in9" />
      <input name="in2" type="matrix33" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="matrix33">
      <input name="value1" type="float" value="8.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in8" />
      <input name="in2" type="matrix33" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="matrix33">
      <input name="value1" type="float" value="7.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in7" />
      <input name="in2" type="matrix33" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="matrix33">
      <input name="value1" type="float" value="6.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in6" />
      <input name="in2" type="matrix33" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="matrix33">
      <input name="value1" type="float" value="5.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in5" />
      <input name="in2" type="matrix33" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="matrix33">
      <input name="value1" type="float" value="4.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in4" />
      <input name="in2" type="matrix33" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="matrix33">
      <input name="value1" type="float" value="3.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in3" />
      <input name="in2" type="matrix33" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="matrix33">
      <input name="value1" type="float" value="2.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in2" />
      <input name="in2" type="matrix33" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="matrix33">
      <input name="value1" type="float" value="1.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in1" />
      <input name="in2" type="matrix33" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="matrix33" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_matrix44" nodedef="ND_switch_matrix44">
    <ifgreater name="ifgreater_10" type="matrix44">
      <input name="value1" type="float" value="10.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in10" />
      <input name="in2" type="matrix44" value="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="matrix44">
      <input name="value1" type="float" value="9.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in9" />
      <input name="in2" type="matrix44" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="matrix44">
      <input name="value1" type="float" value="8.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in8" />
      <input name="in2" type="matrix44" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="matrix44">
      <input name="value1" type="float" value="7.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in7" />
      <input name="in2" type="matrix44" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="matrix44">
      <input name="value1" type="float" value="6.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in6" />
      <input name="in2" type="matrix44" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="matrix44">
      <input name="value1" type="float" value="5.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in5" />
      <input name="in2" type="matrix44" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="matrix44">
      <input name="value1" type="float" value="4.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in4" />
      <input name="in2" type="matrix44" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="matrix44">
      <input name="value1" type="float" value="3.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in3" />
      <input name="in2" type="matrix44" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="matrix44">
      <input name="value1" type="float" value="2.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in2" />
      <input name="in2" type="matrix44" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="matrix44">
      <input name="value1" type="float" value="1.0" />
      <input name="value2" type="float" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in1" />
      <input name="in2" type="matrix44" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="matrix44" nodename="ifgreater_1" />
  </nodegraph>

  <nodegraph name="NG_switch_floatI" nodedef="ND_switch_floatI">
    <ifgreater name="ifgreater_10" type="float">
      <input name="value1" type="integer" value="10" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in10" />
      <input name="in2" type="float" value="0.0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="float">
      <input name="value1" type="integer" value="9" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in9" />
      <input name="in2" type="float" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="float">
      <input name="value1" type="integer" value="8" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in8" />
      <input name="in2" type="float" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="float">
      <input name="value1" type="integer" value="7" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in7" />
      <input name="in2" type="float" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="float">
      <input name="value1" type="integer" value="6" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in6" />
      <input name="in2" type="float" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="float">
      <input name="value1" type="integer" value="5" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in5" />
      <input name="in2" type="float" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="float">
      <input name="value1" type="integer" value="4" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in4" />
      <input name="in2" type="float" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="float">
      <input name="value1" type="integer" value="3" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in3" />
      <input name="in2" type="float" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="float">
      <input name="value1" type="integer" value="2" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in2" />
      <input name="in2" type="float" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="float">
      <input name="value1" type="integer" value="1" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="float" interfacename="in1" />
      <input name="in2" type="float" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="float" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_color3I" nodedef="ND_switch_color3I">
    <ifgreater name="ifgreater_10" type="color3">
      <input name="value1" type="integer" value="10" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in10" />
      <input name="in2" type="color3" value="0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="color3">
      <input name="value1" type="integer" value="9" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in9" />
      <input name="in2" type="color3" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="color3">
      <input name="value1" type="integer" value="8" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in8" />
      <input name="in2" type="color3" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="color3">
      <input name="value1" type="integer" value="7" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in7" />
      <input name="in2" type="color3" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="color3">
      <input name="value1" type="integer" value="6" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in6" />
      <input name="in2" type="color3" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="color3">
      <input name="value1" type="integer" value="5" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in5" />
      <input name="in2" type="color3" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="color3">
      <input name="value1" type="integer" value="4" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in4" />
      <input name="in2" type="color3" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="color3">
      <input name="value1" type="integer" value="3" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in3" />
      <input name="in2" type="color3" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="color3">
      <input name="value1" type="integer" value="2" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in2" />
      <input name="in2" type="color3" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="color3">
      <input name="value1" type="integer" value="1" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color3" interfacename="in1" />
      <input name="in2" type="color3" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="color3" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_color4I" nodedef="ND_switch_color4I">
    <ifgreater name="ifgreater_10" type="color4">
      <input name="value1" type="integer" value="10" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in10" />
      <input name="in2" type="color4" value="0,0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="color4">
      <input name="value1" type="integer" value="9" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in9" />
      <input name="in2" type="color4" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="color4">
      <input name="value1" type="integer" value="8" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in8" />
      <input name="in2" type="color4" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="color4">
      <input name="value1" type="integer" value="7" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in7" />
      <input name="in2" type="color4" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="color4">
      <input name="value1" type="integer" value="6" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in6" />
      <input name="in2" type="color4" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="color4">
      <input name="value1" type="integer" value="5" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in5" />
      <input name="in2" type="color4" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="color4">
      <input name="value1" type="integer" value="4" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in4" />
      <input name="in2" type="color4" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="color4">
      <input name="value1" type="integer" value="3" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in3" />
      <input name="in2" type="color4" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="color4">
      <input name="value1" type="integer" value="2" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in2" />
      <input name="in2" type="color4" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="color4">
      <input name="value1" type="integer" value="1" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="color4" interfacename="in1" />
      <input name="in2" type="color4" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="color4" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_vector2I" nodedef="ND_switch_vector2I">
    <ifgreater name="ifgreater_10" type="vector2">
      <input name="value1" type="integer" value="10" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in10" />
      <input name="in2" type="vector2" value="0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="vector2">
      <input name="value1" type="integer" value="9" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in9" />
      <input name="in2" type="vector2" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="vector2">
      <input name="value1" type="integer" value="8" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in8" />
      <input name="in2" type="vector2" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="vector2">
      <input name="value1" type="integer" value="7" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in7" />
      <input name="in2" type="vector2" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="vector2">
      <input name="value1" type="integer" value="6" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in6" />
      <input name="in2" type="vector2" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="vector2">
      <input name="value1" type="integer" value="5" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in5" />
      <input name="in2" type="vector2" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="vector2">
      <input name="value1" type="integer" value="4" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in4" />
      <input name="in2" type="vector2" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="vector2">
      <input name="value1" type="integer" value="3" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in3" />
      <input name="in2" type="vector2" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="vector2">
      <input name="value1" type="integer" value="2" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in2" />
      <input name="in2" type="vector2" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="vector2">
      <input name="value1" type="integer" value="1" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector2" interfacename="in1" />
      <input name="in2" type="vector2" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="vector2" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_vector3I" nodedef="ND_switch_vector3I">
    <ifgreater name="ifgreater_10" type="vector3">
      <input name="value1" type="integer" value="10" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in10" />
      <input name="in2" type="vector3" value="0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="vector3">
      <input name="value1" type="integer" value="9" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in9" />
      <input name="in2" type="vector3" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="vector3">
      <input name="value1" type="integer" value="8" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in8" />
      <input name="in2" type="vector3" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="vector3">
      <input name="value1" type="integer" value="7" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in7" />
      <input name="in2" type="vector3" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="vector3">
      <input name="value1" type="integer" value="6" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in6" />
      <input name="in2" type="vector3" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="vector3">
      <input name="value1" type="integer" value="5" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in5" />
      <input name="in2" type="vector3" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="vector3">
      <input name="value1" type="integer" value="4" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in4" />
      <input name="in2" type="vector3" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="vector3">
      <input name="value1" type="integer" value="3" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in3" />
      <input name="in2" type="vector3" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="vector3">
      <input name="value1" type="integer" value="2" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in2" />
      <input name="in2" type="vector3" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="vector3">
      <input name="value1" type="integer" value="1" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector3" interfacename="in1" />
      <input name="in2" type="vector3" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="vector3" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_vector4I" nodedef="ND_switch_vector4I">
    <ifgreater name="ifgreater_10" type="vector4">
      <input name="value1" type="integer" value="10" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in10" />
      <input name="in2" type="vector4" value="0,0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="vector4">
      <input name="value1" type="integer" value="9" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in9" />
      <input name="in2" type="vector4" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="vector4">
      <input name="value1" type="integer" value="8" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in8" />
      <input name="in2" type="vector4" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="vector4">
      <input name="value1" type="integer" value="7" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in7" />
      <input name="in2" type="vector4" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="vector4">
      <input name="value1" type="integer" value="6" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in6" />
      <input name="in2" type="vector4" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="vector4">
      <input name="value1" type="integer" value="5" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in5" />
      <input name="in2" type="vector4" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="vector4">
      <input name="value1" type="integer" value="4" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in4" />
      <input name="in2" type="vector4" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="vector4">
      <input name="value1" type="integer" value="3" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in3" />
      <input name="in2" type="vector4" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="vector4">
      <input name="value1" type="integer" value="2" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in2" />
      <input name="in2" type="vector4" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="vector4">
      <input name="value1" type="integer" value="1" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="vector4" interfacename="in1" />
      <input name="in2" type="vector4" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="vector4" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_matrix33I" nodedef="ND_switch_matrix33I">
    <ifgreater name="ifgreater_10" type="matrix33">
      <input name="value1" type="integer" value="10" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in10" />
      <input name="in2" type="matrix33" value="0,0,0,0,0,0,0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="matrix33">
      <input name="value1" type="integer" value="9" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in9" />
      <input name="in2" type="matrix33" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="matrix33">
      <input name="value1" type="integer" value="8" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in8" />
      <input name="in2" type="matrix33" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="matrix33">
      <input name="value1" type="integer" value="7" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in7" />
      <input name="in2" type="matrix33" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="matrix33">
      <input name="value1" type="integer" value="6" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in6" />
      <input name="in2" type="matrix33" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="matrix33">
      <input name="value1" type="integer" value="5" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in5" />
      <input name="in2" type="matrix33" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="matrix33">
      <input name="value1" type="integer" value="4" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in4" />
      <input name="in2" type="matrix33" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="matrix33">
      <input name="value1" type="integer" value="3" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in3" />
      <input name="in2" type="matrix33" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="matrix33">
      <input name="value1" type="integer" value="2" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in2" />
      <input name="in2" type="matrix33" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="matrix33">
      <input name="value1" type="integer" value="1" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix33" interfacename="in1" />
      <input name="in2" type="matrix33" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="matrix33" nodename="ifgreater_1" />
  </nodegraph>
  <nodegraph name="NG_switch_matrix44I" nodedef="ND_switch_matrix44I">
    <ifgreater name="ifgreater_10" type="matrix44">
      <input name="value1" type="integer" value="10" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in10" />
      <input name="in2" type="matrix44" value="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" />
    </ifgreater>
    <ifgreater name="ifgreater_9" type="matrix44">
      <input name="value1" type="integer" value="9" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in9" />
      <input name="in2" type="matrix44" nodename="ifgreater_10" />
    </ifgreater>
    <ifgreater name="ifgreater_8" type="matrix44">
      <input name="value1" type="integer" value="8" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in8" />
      <input name="in2" type="matrix44" nodename="ifgreater_9" />
    </ifgreater>
    <ifgreater name="ifgreater_7" type="matrix44">
      <input name="value1" type="integer" value="7" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in7" />
      <input name="in2" type="matrix44" nodename="ifgreater_8" />
    </ifgreater>
    <ifgreater name="ifgreater_6" type="matrix44">
      <input name="value1" type="integer" value="6" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in6" />
      <input name="in2" type="matrix44" nodename="ifgreater_7" />
    </ifgreater>
    <ifgreater name="ifgreater_5" type="matrix44">
      <input name="value1" type="integer" value="5" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in5" />
      <input name="in2" type="matrix44" nodename="ifgreater_6" />
    </ifgreater>
    <ifgreater name="ifgreater_4" type="matrix44">
      <input name="value1" type="integer" value="4" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in4" />
      <input name="in2" type="matrix44" nodename="ifgreater_5" />
    </ifgreater>
    <ifgreater name="ifgreater_3" type="matrix44">
      <input name="value1" type="integer" value="3" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in3" />
      <input name="in2" type="matrix44" nodename="ifgreater_4" />
    </ifgreater>
    <ifgreater name="ifgreater_2" type="matrix44">
      <input name="value1" type="integer" value="2" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in2" />
      <input name="in2" type="matrix44" nodename="ifgreater_3" />
    </ifgreater>
    <ifgreater name="ifgreater_1" type="matrix44">
      <input name="value1" type="integer" value="1" />
      <input name="value2" type="integer" interfacename="which" />
      <input name="in1" type="matrix44" interfacename="in1" />
      <input name="in2" type="matrix44" nodename="ifgreater_2" />
    </ifgreater>
    <output name="out" type="matrix44" nodename="ifgreater_1" />
  </nodegraph>


  <!-- ======================================================================== -->
  <!-- Logical operator nodes                                                   -->
  <!-- ======================================================================== -->

  <!--
    Node: <xor>
    Logical XOR operation for two boolean values.
  -->
  <nodegraph name="NG_logical_xor" nodedef="ND_logical_xor">
    <not name="not_in1" type="boolean">
      <input name="in" type="boolean" interfacename="in1"/>
    </not>
    <not name="not_in2" type="boolean">
      <input name="in" type="boolean" interfacename="in2"/>
    </not>
    <and name="in1_and_not_in2" type="boolean">
      <input name="in1" type="boolean" interfacename="in1" />
      <input name="in2" type="boolean" nodename="not_in2" />
    </and>
    <and name="in2_and_not_in1" type="boolean">
      <input name="in1" type="boolean" interfacename="in2" />
      <input name="in2" type="boolean" nodename="not_in1" />
    </and>
    <or name="or" type="boolean">
      <input name="in1" type="boolean" nodename="in1_and_not_in2"/>
      <input name="in2" type="boolean" nodename="in2_and_not_in1"/>
    </or>
    <output name="out" type="boolean" nodename="or" />
  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations for msl implementations of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- Shader nodes                                                             -->
  <!-- ======================================================================== -->

  <!-- <surfacematerial> -->
  <implementation name="IM_surfacematerial_genmsl" nodedef="ND_surfacematerial" target="genmsl" />

  <!-- ======================================================================== -->
  <!-- Texture nodes                                                            -->
  <!-- ======================================================================== -->

  <!-- <image> -->
  <implementation name="IM_image_float_genmsl" nodedef="ND_image_float" file="../genglsl/mx_image_float.glsl" function="mx_image_float" target="genmsl">
    <input name="default" type="float" implname="default_value" />
  </implementation>
  <implementation name="IM_image_color3_genmsl" nodedef="ND_image_color3" file="../genglsl/mx_image_color3.glsl" function="mx_image_color3" target="genmsl">
    <input name="default" type="color3" implname="default_value" />
  </implementation>
  <implementation name="IM_image_color4_genmsl" nodedef="ND_image_color4" file="../genglsl/mx_image_color4.glsl" function="mx_image_color4" target="genmsl">
    <input name="default" type="color4" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector2_genmsl" nodedef="ND_image_vector2" file="../genglsl/mx_image_vector2.glsl" function="mx_image_vector2" target="genmsl">
    <input name="default" type="vector2" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector3_genmsl" nodedef="ND_image_vector3" file="../genglsl/mx_image_vector3.glsl" function="mx_image_vector3" target="genmsl">
    <input name="default" type="vector3" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector4_genmsl" nodedef="ND_image_vector4" file="../genglsl/mx_image_vector4.glsl" function="mx_image_vector4" target="genmsl">
    <input name="default" type="vector4" implname="default_value" />
  </implementation>

  <!-- ======================================================================== -->
  <!-- Procedural nodes                                                         -->
  <!-- ======================================================================== -->

  <!-- ======================================================================== -->
  <!-- Geometric nodes                                                          -->
  <!-- ======================================================================== -->

  <!-- <position> -->
  <implementation name="IM_position_vector3_genmsl" nodedef="ND_position_vector3" target="genmsl" />

  <!-- <normal> -->
  <implementation name="IM_normal_vector3_genmsl" nodedef="ND_normal_vector3" target="genmsl" />

  <!-- <tangent> -->
  <implementation name="IM_tangent_vector3_genmsl" nodedef="ND_tangent_vector3" target="genmsl" />

  <!-- <bitangent> -->
  <implementation name="IM_bitangent_vector3_genmsl" nodedef="ND_bitangent_vector3" target="genmsl" />

  <!-- <texcoord> -->
  <implementation name="IM_texcoord_vector2_genmsl" nodedef="ND_texcoord_vector2" target="genmsl" />
  <implementation name="IM_texcoord_vector3_genmsl" nodedef="ND_texcoord_vector3" target="genmsl" />

  <!-- <geomcolor> -->
  <implementation name="IM_geomcolor_float_genmsl" nodedef="ND_geomcolor_float" target="genmsl" />
  <implementation name="IM_geomcolor_color3_genmsl" nodedef="ND_geomcolor_color3" target="genmsl" />
  <implementation name="IM_geomcolor_color4_genmsl" nodedef="ND_geomcolor_color4" target="genmsl" />

  <!-- <geompropvalue> -->
  <implementation name="IM_geompropvalue_integer_genmsl" nodedef="ND_geompropvalue_integer" function="mx_geompropvalue_int" target="genmsl" />
  <implementation name="IM_geompropvalue_boolean_genmsl" nodedef="ND_geompropvalue_boolean" function="mx_geompropvalue_bool" target="genmsl" />
  <implementation name="IM_geompropvalue_float_genmsl" nodedef="ND_geompropvalue_float" function="mx_geompropvalue_float" target="genmsl" />
  <implementation name="IM_geompropvalue_color3_genmsl" nodedef="ND_geompropvalue_color3" function="mx_geompropvalue_color" target="genmsl" />
  <implementation name="IM_geompropvalue_color4_genmsl" nodedef="ND_geompropvalue_color4" function="mx_geompropvalue_color4" target="genmsl" />
  <implementation name="IM_geompropvalue_vector2_genmsl" nodedef="ND_geompropvalue_vector2" function="mx_geompropvalue_vector2" target="genmsl" />
  <implementation name="IM_geompropvalue_vector3_genmsl" nodedef="ND_geompropvalue_vector3" function="mx_geompropvalue_vector" target="genmsl" />
  <implementation name="IM_geompropvalue_vector4_genmsl" nodedef="ND_geompropvalue_vector4" function="mx_geompropvalue_vector4" target="genmsl" />

  <!-- <geompropvalueuniform> -->
  <implementation name="IM_geompropvalue_string_genmsl" nodedef="ND_geompropvalueuniform_string" function="mx_geompropvalue_string" target="genmsl" />
  <implementation name="IM_geompropvalue_filename_genmsl" nodedef="ND_geompropvalueuniform_filename" function="mx_geompropvalue_string" target="genmsl" />

  <!-- ======================================================================== -->
  <!-- Application nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <frame> -->
  <implementation name="IM_frame_float_genmsl" nodedef="ND_frame_float" function="mx_frame_float" target="genmsl" />

  <!-- <time> -->
  <implementation name="IM_time_float_genmsl" nodedef="ND_time_float" function="mx_time_float" target="genmsl" />

  <!-- ======================================================================== -->
  <!-- Math nodes                                                               -->
  <!-- ======================================================================== -->

  <!-- <transformpoint> -->
  <implementation name="IM_transformpoint_vector3_genmsl" nodedef="ND_transformpoint_vector3" target="genmsl" />

  <!-- <transformvector> -->
  <implementation name="IM_transformvector_vector3_genmsl" nodedef="ND_transformvector_vector3" target="genmsl" />

  <!-- <transformnormal> -->
  <implementation name="IM_transformnormal_vector3_genmsl" nodedef="ND_transformnormal_vector3" target="genmsl" />

  <!-- ======================================================================== -->
  <!-- Adjustment nodes                                                         -->
  <!-- ======================================================================== -->

  <!-- ======================================================================== -->
  <!-- Compositing nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- ======================================================================== -->
  <!-- Conditional nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- ======================================================================== -->
  <!-- Channel nodes                                                            -->
  <!-- ======================================================================== -->

  <!-- <combine2> -->
  <implementation name="IM_combine2_vector2_genmsl" nodedef="ND_combine2_vector2" target="genmsl" sourcecode="{ {{in1}},{{in2}} }" />
  <implementation name="IM_combine2_color4CF_genmsl" nodedef="ND_combine2_color4CF" target="genmsl" sourcecode="{ {{in1}}[0],{{in1}}[1],{{in1}}[2],{{in2}} }" />
  <implementation name="IM_combine2_vector4VF_genmsl" nodedef="ND_combine2_vector4VF" target="genmsl" sourcecode="{ {{in1}}[0],{{in1}}[1],{{in1}}[2],{{in2}} }" />
  <implementation name="IM_combine2_vector4VV_genmsl" nodedef="ND_combine2_vector4VV" target="genmsl" sourcecode="{ {{in1}}[0],{{in1}}[1],{{in2}}[0],{{in2}}[1] }" />

  <!-- <combine3> -->
  <implementation name="IM_combine3_color3_genmsl" nodedef="ND_combine3_color3" target="genmsl" sourcecode="{ {{in1}},{{in2}},{{in3}} }" />
  <implementation name="IM_combine3_vector3_genmsl" nodedef="ND_combine3_vector3" target="genmsl" sourcecode="{ {{in1}},{{in2}},{{in3}} }" />

  <!-- <combine4> -->
  <implementation name="IM_combine4_color4_genmsl" nodedef="ND_combine4_color4" target="genmsl" sourcecode="{ {{in1}},{{in2}},{{in3}},{{in4}} }" />
  <implementation name="IM_combine4_vector4_genmsl" nodedef="ND_combine4_vector4" target="genmsl" sourcecode="{ {{in1}},{{in2}},{{in3}},{{in4}} }" />

  <!-- ======================================================================== -->
  <!-- Convolution nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <blur> -->
  <implementation name="IM_blur_float_genmsl" nodedef="ND_blur_float" target="genmsl" />
  <implementation name="IM_blur_color3_genmsl" nodedef="ND_blur_color3" target="genmsl" />
  <implementation name="IM_blur_color4_genmsl" nodedef="ND_blur_color4" target="genmsl" />
  <implementation name="IM_blur_vector2_genmsl" nodedef="ND_blur_vector2" target="genmsl" />
  <implementation name="IM_blur_vector3_genmsl" nodedef="ND_blur_vector3" target="genmsl" />
  <implementation name="IM_blur_vector4_genmsl" nodedef="ND_blur_vector4" target="genmsl" />

  <!-- ======================================================================== -->
  <!-- Logical operator nodes                                                   -->
  <!-- ======================================================================== -->

  <!-- ======================================================================== -->
  <!-- Organization nodes                                                       -->
  <!-- ======================================================================== -->

</materialx>
// Restrict to 7x7 kernel size for performance reasons
#define MX_MAX_SAMPLE_COUNT 49
// Size of all weights for all levels (including level 1)
#define MX_WEIGHT_ARRAY_SIZE 84

//
// Function to compute the sample size relative to a texture coordinate
//
vec2 mx_compute_sample_size_uv(vec2 uv, float filterSize, float filterOffset)
{
   vec2 derivUVx = dFdx(uv) * 0.5f;
   vec2 derivUVy = dFdy(uv) * 0.5f;
   float derivX = abs(derivUVx.x) + abs(derivUVy.x);
   float derivY = abs(derivUVx.y) + abs(derivUVy.y);
   float sampleSizeU = 2.0f * filterSize * derivX + filterOffset;
   if (sampleSizeU < 1.0E-05f)
       sampleSizeU = 1.0E-05f;
   float sampleSizeV = 2.0f * filterSize * derivY + filterOffset;
   if (sampleSizeV < 1.0E-05f)
       sampleSizeV = 1.0E-05f;
   return vec2(sampleSizeU, sampleSizeV);
}

//
// Apply filter for float samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
float mx_convolution_float(float S[MX_MAX_SAMPLE_COUNT], constant float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    float result = 0.0;
    for (int i = 0;  i < sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vec2 samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vec2 mx_convolution_vec2(vec2 S[MX_MAX_SAMPLE_COUNT], constant float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vec2 result = vec2(0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vec3 samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vec3 mx_convolution_vec3(vec3 S[MX_MAX_SAMPLE_COUNT], constant float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vec3 result = vec3(0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vec4 samples S, using weights W.
// sampleCount should be a square of a odd number { 1, 3, 5, 7 }
//
vec4 mx_convolution_vec4(vec4 S[MX_MAX_SAMPLE_COUNT], constant float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vec4 result = vec4(0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}
float3x3 operator+(float3x3 a, float b)
{
    return a + float3x3(b,b,b,b,b,b,b,b,b);
}

float4x4 operator+(float4x4 a, float b)
{
    return a + float4x4(b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b);
}

float3x3 operator-(float3x3 a, float b)
{
    return a - float3x3(b,b,b,b,b,b,b,b,b);
}

float4x4 operator-(float4x4 a, float b)
{
    return a - float4x4(b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b);
}

float3x3 operator/(float3x3 a, float3x3 b)
{
    for(int i = 0; i < 3; ++i)
        for(int j = 0; j < 3; ++j)
            a[i][j] /= b[i][j];

    return a;
}

float4x4 operator/(float4x4 a, float4x4 b)
{
    for(int i = 0; i < 4; ++i)
        for(int j = 0; j < 4; ++j)
            a[i][j] /= b[i][j];

    return a;
}

float3x3 operator/(float3x3 a, float b)
{
    for(int i = 0; i < 3; ++i)
        for(int j = 0; j < 3; ++j)
            a[i][j] /= b;

    return a;
}

float4x4 operator/(float4x4 a, float b)
{
    for(int i = 0; i < 4; ++i)
        for(int j = 0; j < 4; ++j)
            a[i][j] /= b;

    return a;
}
#define M_FLOAT_EPS 1e-8

#define mx_sin metal::sin
#define mx_cos metal::cos
#define mx_tan metal::tan
#define mx_asin metal::asin
#define mx_acos metal::acos

float mx_square(float x)
{
    return x*x;
}

vec2 mx_square(vec2 x)
{
    return x*x;
}

vec3 mx_square(vec3 x)
{
    return x*x;
}

float mx_inversesqrt(float x)
{
    return metal::rsqrt(x);
}

template<class T1, class T2>
T1 mx_mod(T1 x, T2 y)
{
    return x - y * floor(x/y);
}

float3x3 mx_inverse(float3x3 m)
{
    float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0];
    float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1];
    float n31 = m[0][2], n32 = m[1][2], n33 = m[2][2];

    float det = metal::determinant(m);
    float idet = 1.0f / det;

    float3x3 ret;

    ret[0][0] = idet * (n22 * n33 - n32 * n23);
    ret[1][0] = idet * (n32 * n13 - n12 * n33);
    ret[2][0] = idet * (n12 * n23 - n22 * n13);
    
    ret[0][1] = idet * (n31 * n23 - n21 * n33);
    ret[1][1] = idet * (n11 * n33 - n31 * n13);
    ret[2][1] = idet * (n21 * n13 - n11 * n23);
    
    ret[0][2] = idet * (n21 * n32 - n31 * n22);
    ret[1][2] = idet * (n31 * n12 - n11 * n32);
    ret[2][2] = idet * (n11 * n22 - n21 * n12);

    return ret;
}

float4x4 mx_inverse(float4x4 m)
{
    float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0], n14 = m[3][0];
    float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1], n24 = m[3][1];
    float n31 = m[0][2], n32 = m[1][2], n33 = m[2][2], n34 = m[3][2];
    float n41 = m[0][3], n42 = m[1][3], n43 = m[2][3], n44 = m[3][3];

    float t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44;
    float t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44;
    float t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44;
    float t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;

    float det = metal::determinant(m);
    float idet = 1.0f / det;

    float4x4 ret;

    ret[0][0] = t11 * idet;
    ret[0][1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * idet;
    ret[0][2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * idet;
    ret[0][3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * idet;

    ret[1][0] = t12 * idet;
    ret[1][1] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * idet;
    ret[1][2] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * idet;
    ret[1][3] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * idet;

    ret[2][0] = t13 * idet;
    ret[2][1] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * idet;
    ret[2][2] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * idet;
    ret[2][3] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * idet;

    ret[3][0] = t14 * idet;
    ret[3][1] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * idet;
    ret[3][2] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * idet;
    ret[3][3] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * idet;

    return ret;
}

float mx_atan(float y_over_x)
{
    return metal::atan(y_over_x);
}

float mx_atan(float y, float x)
{
    return metal::atan2(y, x);
}

vec2 mx_atan(vec2 y, vec2 x)
{
    return metal::atan2(y, x);
}

vec3 mx_atan(vec3 y, vec3 x)
{
    return metal::atan2(y, x);
}

vec4 mx_atan(vec4 y, vec4 x)
{
    return metal::atan2(y, x);
}

float mx_radians(float degree)
{
    return (degree * M_PI_F / 180.0f);
}

vec2 mx_radians(vec2 degree)
{
    return (degree * M_PI_F / 180.0f);
}
struct MetalTexture
{
    texture2d<float> tex;
    sampler s;

    // needed for Storm
    int get_width() { return tex.get_width(); }
    int get_height() { return tex.get_height(); }
    int get_num_mip_levels() { return tex.get_num_mip_levels(); }
};

float4 texture(MetalTexture mtlTex, float2 uv)
{
    return mtlTex.tex.sample(mtlTex.s, uv);
}

float4 textureLod(MetalTexture mtlTex, float2 uv, float lod)
{
    return mtlTex.tex.sample(mtlTex.s, uv, level(lod));
}

float4 textureGrad(MetalTexture mtlTex, float2 uv, float2 dx, float2 dy)
{
    return mtlTex.tex.sample(mtlTex.s, uv, gradient2d(dx, dy));
}

int2 textureSize(MetalTexture mtlTex, int mipLevel)
{
    return int2(mtlTex.tex.get_width(), mtlTex.tex.get_height());
}
#include "lib/mx_noise.glsl"

void mx_noise3d_vector2(vec2 amplitude, float pivot, vec3 position, out vec2 result)
{
    vec3 value = mx_perlin_noise_vec3(position);
    result = value.xy * amplitude + pivot;
}
void mx_smoothstep_float(float val, float low, float high, out float result)
{
    if (val >= high)
        result = 1.0;
    else if (val <= low)
        result = 0.0;
    else
        result = smoothstep(low, high, val);
}
#include "mx_aastep.glsl"

void mx_splittb_float(float valuet, float valueb, float center, vec2 texcoord, out float result)
{
    result = mix(valuet, valueb, mx_aastep(center, texcoord.y));
}
#include "lib/$fileTransformUv"

#ifdef HW_SEPARATE_SAMPLERS
void mx_image_vector3(texture2D tex_texture, sampler tex_sampler, int layer, vec3 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec3 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(sampler2D(tex_texture, tex_sampler), uv).rgb;
}
#else
void mx_image_vector3(sampler2D tex_sampler, int layer, vec3 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec3 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(tex_sampler, uv).rgb;
}
#endif
#include "mx_aastep.glsl"

void mx_splittb_vector3(vec3 valuet, vec3 valueb, float center, vec2 texcoord, out vec3 result)
{
    result = mix(valuet, valueb, mx_aastep(center, texcoord.y));
}
#include "mx_burn_float.glsl"

void mx_burn_color3(vec3 fg, vec3 bg, float mixval, out vec3 result)
{
    float f;
    mx_burn_float(fg.x, bg.x, mixval, f); result.x = f;
    mx_burn_float(fg.y, bg.y, mixval, f); result.y = f;
    mx_burn_float(fg.z, bg.z, mixval, f); result.z = f;
}
void mx_dodge_float(float fg, float bg, float mixval, out float result)
{
    if (abs(1.0 - fg) < M_FLOAT_EPS)
    {
        result = 0.0;
        return;
    }
    result = mixval*(bg / (1.0 - fg)) + ((1.0-mixval)*bg);
}
void mx_disjointover_color4(vec4 fg, vec4 bg, float mixval, out vec4 result)
{
    float summedAlpha = fg.w + bg.w;

    if (summedAlpha <= 1.0)
    {
        result.xyz = fg.xyz + bg.xyz;
    }
    else
    {
        if (abs(bg.w) < M_FLOAT_EPS)
        {
            result.xyz = vec3(0.0);
        }
        else
        {
            float x = (1.0 - fg.w) / bg.w;
            result.xyz = fg.xyz + bg.xyz * x;
        }
    }
    result.w = min(summedAlpha, 1.0);

    result.xyz = result.xyz * mixval + (1.0 - mixval) * bg.xyz;
    result.w = result.w * mixval + (1.0 - mixval) * bg.w;
}
void mx_premult_color4(vec4 _in, out vec4 result)
{
    result = vec4(_in.rgb * _in.a, _in.a);
}
#include "lib/mx_noise.glsl"

void mx_fractal2d_vector2(vec2 amplitude, int octaves, float lacunarity, float diminish, vec2 texcoord, out vec2 result)
{
    vec2 value = mx_fractal2d_noise_vec2(texcoord, octaves, lacunarity, diminish);
    result = value * amplitude;
}
void mx_normalmap_vector2(vec3 value, vec2 normal_scale, vec3 N, vec3 T, vec3 B, out vec3 result)
{
    value = (dot(value, value) == 0.0) ? vec3(0.0, 0.0, 1.0) : value * 2.0 - 1.0;
    value = T * value.x * normal_scale.x +
            B * value.y * normal_scale.y +
            N * value.z;
    result = normalize(value);
}

void mx_normalmap_float(vec3 value, float normal_scale, vec3 N, vec3 T, vec3 B, out vec3 result)
{
    mx_normalmap_vector2(value, vec2(normal_scale), N, T, B, result);
}
#include "lib/mx_noise.glsl"

void mx_cellnoise3d_float(vec3 position, out float result)
{
    result = mx_cell_noise_float(position);
}
#include "lib/mx_noise.glsl"

void mx_noise3d_float(float amplitude, float pivot, vec3 position, out float result)
{
    float value = mx_perlin_noise_float(position);
    result = value * amplitude + pivot;
}
#include "lib/mx_noise.glsl"

void mx_fractal2d_vector4(vec4 amplitude, int octaves, float lacunarity, float diminish, vec2 texcoord, out vec4 result)
{
    vec4 value = mx_fractal2d_noise_vec4(texcoord, octaves, lacunarity, diminish);
    result = value * amplitude;
}
void mx_creatematrix_vector4_matrix44(vec4 in1, vec4 in2, vec4 in3, vec4 in4, out mat4 result)
{
    result = mat4(in1.x, in1.y, in1.z, in1.w,
                  in2.x, in2.y, in2.z, in2.w,
                  in3.x, in3.y, in3.z, in3.w,
                  in4.x, in4.y, in4.z, in4.w);
}
#include "mx_aastep.glsl"

void mx_splitlr_vector2(vec2 valuel, vec2 valuer, float center, vec2 texcoord, out vec2 result)
{
    result = mix(valuel, valuer, mx_aastep(center, texcoord.x));
}
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations for glsl implementations of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- Shader nodes                                                             -->
  <!-- ======================================================================== -->

  <!-- <surfacematerial> -->
  <implementation name="IM_surfacematerial_genglsl" nodedef="ND_surfacematerial" target="genglsl" />

  <!-- <surface_unlit> -->
  <implementation name="IM_surface_unlit_genglsl" nodedef="ND_surface_unlit" file="mx_surface_unlit.glsl" function="mx_surface_unlit" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Texture nodes                                                            -->
  <!-- ======================================================================== -->

  <!-- <image> -->
  <implementation name="IM_image_float_genglsl" nodedef="ND_image_float" file="mx_image_float.glsl" function="mx_image_float" target="genglsl">
    <input name="default" type="float" implname="default_value" />
  </implementation>
  <implementation name="IM_image_color3_genglsl" nodedef="ND_image_color3" file="mx_image_color3.glsl" function="mx_image_color3" target="genglsl">
    <input name="default" type="color3" implname="default_value" />
  </implementation>
  <implementation name="IM_image_color4_genglsl" nodedef="ND_image_color4" file="mx_image_color4.glsl" function="mx_image_color4" target="genglsl">
    <input name="default" type="color4" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector2_genglsl" nodedef="ND_image_vector2" file="mx_image_vector2.glsl" function="mx_image_vector2" target="genglsl">
    <input name="default" type="vector2" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector3_genglsl" nodedef="ND_image_vector3" file="mx_image_vector3.glsl" function="mx_image_vector3" target="genglsl">
    <input name="default" type="vector3" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector4_genglsl" nodedef="ND_image_vector4" file="mx_image_vector4.glsl" function="mx_image_vector4" target="genglsl">
    <input name="default" type="vector4" implname="default_value" />
  </implementation>

  <!-- <hextiledimage> -->
  <implementation name="IM_hextiledimage_color3_genglsl" nodedef="ND_hextiledimage_color3" file="mx_hextiledimage.glsl" function="mx_hextiledimage_color3" target="genglsl">
    <input name="default" type="color3" implname="default_value" />
  </implementation>
  <implementation name="IM_hextiledimage_color4_genglsl" nodedef="ND_hextiledimage_color4" file="mx_hextiledimage.glsl" function="mx_hextiledimage_color4" target="genglsl">
    <input name="default" type="color4" implname="default_value" />
  </implementation>

  <!-- <normalmap> -->
  <implementation name="IM_normalmap_float_genglsl" nodedef="ND_normalmap_float" file="mx_normalmap.glsl" function="mx_normalmap_float" target="genglsl" />
  <implementation name="IM_normalmap_vector2_genglsl" nodedef="ND_normalmap_vector2" file="mx_normalmap.glsl" function="mx_normalmap_vector2" target="genglsl" />

  <!-- <hextilednormalmap> -->
  <implementation name="IM_hextilednormalmap_vector3_genglsl" nodedef="ND_hextilednormalmap_vector3" file="mx_hextilednormalmap.glsl" function="mx_hextilednormalmap_vector3" target="genglsl">
    <input name="default" type="vector3" implname="default_value" />
  </implementation>

  <!-- ======================================================================== -->
  <!-- Procedural nodes                                                         -->
  <!-- ======================================================================== -->

  <!-- <constant> -->
  <implementation name="IM_constant_float_genglsl" nodedef="ND_constant_float" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_color3_genglsl" nodedef="ND_constant_color3" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_color4_genglsl" nodedef="ND_constant_color4" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_vector2_genglsl" nodedef="ND_constant_vector2" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_vector3_genglsl" nodedef="ND_constant_vector3" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_vector4_genglsl" nodedef="ND_constant_vector4" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_boolean_genglsl" nodedef="ND_constant_boolean" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_integer_genglsl" nodedef="ND_constant_integer" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_matrix33_genglsl" nodedef="ND_constant_matrix33" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_matrix44_genglsl" nodedef="ND_constant_matrix44" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_string_genglsl" nodedef="ND_constant_string" target="genglsl" sourcecode="{{value}}" />
  <implementation name="IM_constant_filename_genglsl" nodedef="ND_constant_filename" target="genglsl" sourcecode="{{value}}" />

  <!-- <ramplr> -->
  <implementation name="IM_ramplr_float_genglsl" nodedef="ND_ramplr_float" file="mx_ramplr_float.glsl" function="mx_ramplr_float" target="genglsl" />
  <implementation name="IM_ramplr_color3_genglsl" nodedef="ND_ramplr_color3" file="mx_ramplr_vector3.glsl" function="mx_ramplr_vector3" target="genglsl" />
  <implementation name="IM_ramplr_color4_genglsl" nodedef="ND_ramplr_color4" file="mx_ramplr_vector4.glsl" function="mx_ramplr_vector4" target="genglsl" />
  <implementation name="IM_ramplr_vector2_genglsl" nodedef="ND_ramplr_vector2" file="mx_ramplr_vector2.glsl" function="mx_ramplr_vector2" target="genglsl" />
  <implementation name="IM_ramplr_vector3_genglsl" nodedef="ND_ramplr_vector3" file="mx_ramplr_vector3.glsl" function="mx_ramplr_vector3" target="genglsl" />
  <implementation name="IM_ramplr_vector4_genglsl" nodedef="ND_ramplr_vector4" file="mx_ramplr_vector4.glsl" function="mx_ramplr_vector4" target="genglsl" />

  <!-- <ramptb> -->
  <implementation name="IM_ramptb_float_genglsl" nodedef="ND_ramptb_float" file="mx_ramptb_float.glsl" function="mx_ramptb_float" target="genglsl" />
  <implementation name="IM_ramptb_color3_genglsl" nodedef="ND_ramptb_color3" file="mx_ramptb_vector3.glsl" function="mx_ramptb_vector3" target="genglsl" />
  <implementation name="IM_ramptb_color4_genglsl" nodedef="ND_ramptb_color4" file="mx_ramptb_vector4.glsl" function="mx_ramptb_vector4" target="genglsl" />
  <implementation name="IM_ramptb_vector2_genglsl" nodedef="ND_ramptb_vector2" file="mx_ramptb_vector2.glsl" function="mx_ramptb_vector2" target="genglsl" />
  <implementation name="IM_ramptb_vector3_genglsl" nodedef="ND_ramptb_vector3" file="mx_ramptb_vector3.glsl" function="mx_ramptb_vector3" target="genglsl" />
  <implementation name="IM_ramptb_vector4_genglsl" nodedef="ND_ramptb_vector4" file="mx_ramptb_vector4.glsl" function="mx_ramptb_vector4" target="genglsl" />

  <!-- <splitlr> -->
  <implementation name="IM_splitlr_float_genglsl" nodedef="ND_splitlr_float" file="mx_splitlr_float.glsl" function="mx_splitlr_float" target="genglsl" />
  <implementation name="IM_splitlr_color3_genglsl" nodedef="ND_splitlr_color3" file="mx_splitlr_vector3.glsl" function="mx_splitlr_vector3" target="genglsl" />
  <implementation name="IM_splitlr_color4_genglsl" nodedef="ND_splitlr_color4" file="mx_splitlr_vector4.glsl" function="mx_splitlr_vector4" target="genglsl" />
  <implementation name="IM_splitlr_vector2_genglsl" nodedef="ND_splitlr_vector2" file="mx_splitlr_vector2.glsl" function="mx_splitlr_vector2" target="genglsl" />
  <implementation name="IM_splitlr_vector3_genglsl" nodedef="ND_splitlr_vector3" file="mx_splitlr_vector3.glsl" function="mx_splitlr_vector3" target="genglsl" />
  <implementation name="IM_splitlr_vector4_genglsl" nodedef="ND_splitlr_vector4" file="mx_splitlr_vector4.glsl" function="mx_splitlr_vector4" target="genglsl" />

  <!-- <splittb> -->
  <implementation name="IM_splittb_float_genglsl" nodedef="ND_splittb_float" file="mx_splittb_float.glsl" function="mx_splittb_float" target="genglsl" />
  <implementation name="IM_splittb_color3_genglsl" nodedef="ND_splittb_color3" file="mx_splittb_vector3.glsl" function="mx_splittb_vector3" target="genglsl" />
  <implementation name="IM_splittb_color4_genglsl" nodedef="ND_splittb_color4" file="mx_splittb_vector4.glsl" function="mx_splittb_vector4" target="genglsl" />
  <implementation name="IM_splittb_vector2_genglsl" nodedef="ND_splittb_vector2" file="mx_splittb_vector2.glsl" function="mx_splittb_vector2" target="genglsl" />
  <implementation name="IM_splittb_vector3_genglsl" nodedef="ND_splittb_vector3" file="mx_splittb_vector3.glsl" function="mx_splittb_vector3" target="genglsl" />
  <implementation name="IM_splittb_vector4_genglsl" nodedef="ND_splittb_vector4" file="mx_splittb_vector4.glsl" function="mx_splittb_vector4" target="genglsl" />

  <!-- <noise2d> -->
  <implementation name="IM_noise2d_float_genglsl" nodedef="ND_noise2d_float" file="mx_noise2d_float.glsl" function="mx_noise2d_float" target="genglsl" />
  <implementation name="IM_noise2d_vector2_genglsl" nodedef="ND_noise2d_vector2" file="mx_noise2d_vector2.glsl" function="mx_noise2d_vector2" target="genglsl" />
  <implementation name="IM_noise2d_vector3_genglsl" nodedef="ND_noise2d_vector3" file="mx_noise2d_vector3.glsl" function="mx_noise2d_vector3" target="genglsl" />
  <implementation name="IM_noise2d_vector4_genglsl" nodedef="ND_noise2d_vector4" file="mx_noise2d_vector4.glsl" function="mx_noise2d_vector4" target="genglsl" />

  <!-- <noise3d> -->
  <implementation name="IM_noise3d_float_genglsl" nodedef="ND_noise3d_float" file="mx_noise3d_float.glsl" function="mx_noise3d_float" target="genglsl" />
  <implementation name="IM_noise3d_vector2_genglsl" nodedef="ND_noise3d_vector2" file="mx_noise3d_vector2.glsl" function="mx_noise3d_vector2" target="genglsl" />
  <implementation name="IM_noise3d_vector3_genglsl" nodedef="ND_noise3d_vector3" file="mx_noise3d_vector3.glsl" function="mx_noise3d_vector3" target="genglsl" />
  <implementation name="IM_noise3d_vector4_genglsl" nodedef="ND_noise3d_vector4" file="mx_noise3d_vector4.glsl" function="mx_noise3d_vector4" target="genglsl" />

  <!-- <fractal2d> -->
  <implementation name="IM_fractal2d_float_genglsl" nodedef="ND_fractal2d_float" file="mx_fractal2d_float.glsl" function="mx_fractal2d_float" target="genglsl" />
  <implementation name="IM_fractal2d_vector2_genglsl" nodedef="ND_fractal2d_vector2" file="mx_fractal2d_vector2.glsl" function="mx_fractal2d_vector2" target="genglsl" />
  <implementation name="IM_fractal2d_vector3_genglsl" nodedef="ND_fractal2d_vector3" file="mx_fractal2d_vector3.glsl" function="mx_fractal2d_vector3" target="genglsl" />
  <implementation name="IM_fractal2d_vector4_genglsl" nodedef="ND_fractal2d_vector4" file="mx_fractal2d_vector4.glsl" function="mx_fractal2d_vector4" target="genglsl" />

  <!-- <fractal3d> -->
  <implementation name="IM_fractal3d_float_genglsl" nodedef="ND_fractal3d_float" file="mx_fractal3d_float.glsl" function="mx_fractal3d_float" target="genglsl" />
  <implementation name="IM_fractal3d_vector2_genglsl" nodedef="ND_fractal3d_vector2" file="mx_fractal3d_vector2.glsl" function="mx_fractal3d_vector2" target="genglsl" />
  <implementation name="IM_fractal3d_vector3_genglsl" nodedef="ND_fractal3d_vector3" file="mx_fractal3d_vector3.glsl" function="mx_fractal3d_vector3" target="genglsl" />
  <implementation name="IM_fractal3d_vector4_genglsl" nodedef="ND_fractal3d_vector4" file="mx_fractal3d_vector4.glsl" function="mx_fractal3d_vector4" target="genglsl" />

  <!-- <cellnoise2d> -->
  <implementation name="IM_cellnoise2d_float_genglsl" nodedef="ND_cellnoise2d_float" file="mx_cellnoise2d_float.glsl" function="mx_cellnoise2d_float" target="genglsl" />

  <!-- <cellnoise3d> -->
  <implementation name="IM_cellnoise3d_float_genglsl" nodedef="ND_cellnoise3d_float" file="mx_cellnoise3d_float.glsl" function="mx_cellnoise3d_float" target="genglsl" />

  <!-- <worleynoise2d> -->
  <implementation name="IM_worleynoise2d_float_genglsl" nodedef="ND_worleynoise2d_float" file="mx_worleynoise2d_float.glsl" function="mx_worleynoise2d_float" target="genglsl" />
  <implementation name="IM_worleynoise2d_vector2_genglsl" nodedef="ND_worleynoise2d_vector2" file="mx_worleynoise2d_vector2.glsl" function="mx_worleynoise2d_vector2" target="genglsl" />
  <implementation name="IM_worleynoise2d_vector3_genglsl" nodedef="ND_worleynoise2d_vector3" file="mx_worleynoise2d_vector3.glsl" function="mx_worleynoise2d_vector3" target="genglsl" />

  <!-- <worleynoise3d> -->
  <implementation name="IM_worleynoise3d_float_genglsl" nodedef="ND_worleynoise3d_float" file="mx_worleynoise3d_float.glsl" function="mx_worleynoise3d_float" target="genglsl" />
  <implementation name="IM_worleynoise3d_vector2_genglsl" nodedef="ND_worleynoise3d_vector2" file="mx_worleynoise3d_vector2.glsl" function="mx_worleynoise3d_vector2" target="genglsl" />
  <implementation name="IM_worleynoise3d_vector3_genglsl" nodedef="ND_worleynoise3d_vector3" file="mx_worleynoise3d_vector3.glsl" function="mx_worleynoise3d_vector3" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Geometric nodes                                                          -->
  <!-- ======================================================================== -->

  <!-- <position> -->
  <implementation name="IM_position_vector3_genglsl" nodedef="ND_position_vector3" target="genglsl" />

  <!-- <normal> -->
  <implementation name="IM_normal_vector3_genglsl" nodedef="ND_normal_vector3" target="genglsl" />

  <!-- <tangent> -->
  <implementation name="IM_tangent_vector3_genglsl" nodedef="ND_tangent_vector3" target="genglsl" />

  <!-- <bitangent> -->
  <implementation name="IM_bitangent_vector3_genglsl" nodedef="ND_bitangent_vector3" target="genglsl" />

  <!-- <texcoord> -->
  <implementation name="IM_texcoord_vector2_genglsl" nodedef="ND_texcoord_vector2" target="genglsl" />
  <implementation name="IM_texcoord_vector3_genglsl" nodedef="ND_texcoord_vector3" target="genglsl" />

  <!-- <geomcolor> -->
  <implementation name="IM_geomcolor_float_genglsl" nodedef="ND_geomcolor_float" target="genglsl" />
  <implementation name="IM_geomcolor_color3_genglsl" nodedef="ND_geomcolor_color3" target="genglsl" />
  <implementation name="IM_geomcolor_color4_genglsl" nodedef="ND_geomcolor_color4" target="genglsl" />

  <!-- <geompropvalue> -->
  <implementation name="IM_geompropvalue_integer_genglsl" nodedef="ND_geompropvalue_integer" function="mx_geompropvalue_int" target="genglsl" />
  <implementation name="IM_geompropvalue_boolean_genglsl" nodedef="ND_geompropvalue_boolean" function="mx_geompropvalue_bool" target="genglsl" />
  <implementation name="IM_geompropvalue_float_genglsl" nodedef="ND_geompropvalue_float" function="mx_geompropvalue_float" target="genglsl" />
  <implementation name="IM_geompropvalue_color3_genglsl" nodedef="ND_geompropvalue_color3" function="mx_geompropvalue_color" target="genglsl" />
  <implementation name="IM_geompropvalue_color4_genglsl" nodedef="ND_geompropvalue_color4" function="mx_geompropvalue_color4" target="genglsl" />
  <implementation name="IM_geompropvalue_vector2_genglsl" nodedef="ND_geompropvalue_vector2" function="mx_geompropvalue_vector2" target="genglsl" />
  <implementation name="IM_geompropvalue_vector3_genglsl" nodedef="ND_geompropvalue_vector3" function="mx_geompropvalue_vector" target="genglsl" />
  <implementation name="IM_geompropvalue_vector4_genglsl" nodedef="ND_geompropvalue_vector4" function="mx_geompropvalue_vector4" target="genglsl" />

  <!-- <geompropvalueuniform> -->
  <implementation name="IM_geompropvalue_string_genglsl" nodedef="ND_geompropvalueuniform_string" function="mx_geompropvalue_string" target="genglsl" />
  <implementation name="IM_geompropvalue_filename_genglsl" nodedef="ND_geompropvalueuniform_filename" function="mx_geompropvalue_string" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Application nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <frame> -->
  <implementation name="IM_frame_float_genglsl" nodedef="ND_frame_float" function="mx_frame_float" target="genglsl" />

  <!-- <time> -->
  <implementation name="IM_time_float_genglsl" nodedef="ND_time_float" function="mx_time_float" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Math nodes                                                               -->
  <!-- ======================================================================== -->

  <!-- <add> -->
  <implementation name="IM_add_float_genglsl" nodedef="ND_add_float" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_integer_genglsl" nodedef="ND_add_integer" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_color3_genglsl" nodedef="ND_add_color3" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_color3FA_genglsl" nodedef="ND_add_color3FA" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_color4_genglsl" nodedef="ND_add_color4" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_color4FA_genglsl" nodedef="ND_add_color4FA" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector2_genglsl" nodedef="ND_add_vector2" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector2FA_genglsl" nodedef="ND_add_vector2FA" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector3_genglsl" nodedef="ND_add_vector3" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector3FA_genglsl" nodedef="ND_add_vector3FA" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector4_genglsl" nodedef="ND_add_vector4" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector4FA_genglsl" nodedef="ND_add_vector4FA" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_matrix33_genglsl" nodedef="ND_add_matrix33" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_matrix33FA_genglsl" nodedef="ND_add_matrix33FA" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_matrix44_genglsl" nodedef="ND_add_matrix44" target="genglsl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_matrix44FA_genglsl" nodedef="ND_add_matrix44FA" target="genglsl" sourcecode="{{in1}} + {{in2}}" />

  <!-- <subtract> -->
  <implementation name="IM_subtract_float_genglsl" nodedef="ND_subtract_float" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_integer_genglsl" nodedef="ND_subtract_integer" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_color3_genglsl" nodedef="ND_subtract_color3" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_color3FA_genglsl" nodedef="ND_subtract_color3FA" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_color4_genglsl" nodedef="ND_subtract_color4" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_color4FA_genglsl" nodedef="ND_subtract_color4FA" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector2_genglsl" nodedef="ND_subtract_vector2" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector2FA_genglsl" nodedef="ND_subtract_vector2FA" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector3_genglsl" nodedef="ND_subtract_vector3" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector3FA_genglsl" nodedef="ND_subtract_vector3FA" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector4_genglsl" nodedef="ND_subtract_vector4" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector4FA_genglsl" nodedef="ND_subtract_vector4FA" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_matrix33_genglsl" nodedef="ND_subtract_matrix33" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_matrix33FA_genglsl" nodedef="ND_subtract_matrix33FA" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_matrix44_genglsl" nodedef="ND_subtract_matrix44" target="genglsl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_matrix44FA_genglsl" nodedef="ND_subtract_matrix44FA" target="genglsl" sourcecode="{{in1}} - {{in2}}" />

  <!-- <multiply> -->
  <implementation name="IM_multiply_float_genglsl" nodedef="ND_multiply_float" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_color3_genglsl" nodedef="ND_multiply_color3" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_color3FA_genglsl" nodedef="ND_multiply_color3FA" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_color4_genglsl" nodedef="ND_multiply_color4" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_color4FA_genglsl" nodedef="ND_multiply_color4FA" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector2_genglsl" nodedef="ND_multiply_vector2" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector2FA_genglsl" nodedef="ND_multiply_vector2FA" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector3_genglsl" nodedef="ND_multiply_vector3" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector3FA_genglsl" nodedef="ND_multiply_vector3FA" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector4_genglsl" nodedef="ND_multiply_vector4" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector4FA_genglsl" nodedef="ND_multiply_vector4FA" target="genglsl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_matrix33_genglsl" nodedef="ND_multiply_matrix33" target="genglsl" sourcecode="{{in2}} * {{in1}}" />
  <implementation name="IM_multiply_matrix44_genglsl" nodedef="ND_multiply_matrix44" target="genglsl" sourcecode="{{in2}} * {{in1}}" />

  <!-- <divide> -->
  <implementation name="IM_divide_float_genglsl" nodedef="ND_divide_float" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_color3_genglsl" nodedef="ND_divide_color3" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_color3FA_genglsl" nodedef="ND_divide_color3FA" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_color4_genglsl" nodedef="ND_divide_color4" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_color4FA_genglsl" nodedef="ND_divide_color4FA" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector2_genglsl" nodedef="ND_divide_vector2" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector2FA_genglsl" nodedef="ND_divide_vector2FA" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector3_genglsl" nodedef="ND_divide_vector3" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector3FA_genglsl" nodedef="ND_divide_vector3FA" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector4_genglsl" nodedef="ND_divide_vector4" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector4FA_genglsl" nodedef="ND_divide_vector4FA" target="genglsl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_matrix33_genglsl" nodedef="ND_divide_matrix33" target="genglsl" sourcecode="mx_inverse({{in2}}) * {{in1}}" />
  <implementation name="IM_divide_matrix44_genglsl" nodedef="ND_divide_matrix44" target="genglsl" sourcecode="mx_inverse({{in2}}) * {{in1}}" />

  <!-- <modulo> -->
  <implementation name="IM_modulo_float_genglsl" nodedef="ND_modulo_float" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_color3_genglsl" nodedef="ND_modulo_color3" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_color3FA_genglsl" nodedef="ND_modulo_color3FA" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_color4_genglsl" nodedef="ND_modulo_color4" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_color4FA_genglsl" nodedef="ND_modulo_color4FA" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector2_genglsl" nodedef="ND_modulo_vector2" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector2FA_genglsl" nodedef="ND_modulo_vector2FA" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector3_genglsl" nodedef="ND_modulo_vector3" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector3FA_genglsl" nodedef="ND_modulo_vector3FA" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector4_genglsl" nodedef="ND_modulo_vector4" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector4FA_genglsl" nodedef="ND_modulo_vector4FA" target="genglsl" sourcecode="mx_mod({{in1}}, {{in2}})" />

  <!-- <fract> -->
  <implementation name="IM_fract_float_genglsl" nodedef="ND_fract_float" target="genglsl" sourcecode="fract({{in}})" />
  <implementation name="IM_fract_color3_genglsl" nodedef="ND_fract_color3" target="genglsl" sourcecode="fract({{in}})" />
  <implementation name="IM_fract_color4_genglsl" nodedef="ND_fract_color4" target="genglsl" sourcecode="fract({{in}})" />
  <implementation name="IM_fract_vector2_genglsl" nodedef="ND_fract_vector2" target="genglsl" sourcecode="fract({{in}})" />
  <implementation name="IM_fract_vector3_genglsl" nodedef="ND_fract_vector3" target="genglsl" sourcecode="fract({{in}})" />
  <implementation name="IM_fract_vector4_genglsl" nodedef="ND_fract_vector4" target="genglsl" sourcecode="fract({{in}})" />

  <!-- <invert> -->
  <implementation name="IM_invert_float_genglsl" nodedef="ND_invert_float" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_color3_genglsl" nodedef="ND_invert_color3" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_color3FA_genglsl" nodedef="ND_invert_color3FA" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_color4_genglsl" nodedef="ND_invert_color4" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_color4FA_genglsl" nodedef="ND_invert_color4FA" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector2_genglsl" nodedef="ND_invert_vector2" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector2FA_genglsl" nodedef="ND_invert_vector2FA" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector3_genglsl" nodedef="ND_invert_vector3" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector3FA_genglsl" nodedef="ND_invert_vector3FA" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector4_genglsl" nodedef="ND_invert_vector4" target="genglsl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector4FA_genglsl" nodedef="ND_invert_vector4FA" target="genglsl" sourcecode="{{amount}} - {{in}}" />

  <!-- <absval> -->
  <implementation name="IM_absval_float_genglsl" nodedef="ND_absval_float" target="genglsl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_color3_genglsl" nodedef="ND_absval_color3" target="genglsl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_color4_genglsl" nodedef="ND_absval_color4" target="genglsl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_vector2_genglsl" nodedef="ND_absval_vector2" target="genglsl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_vector3_genglsl" nodedef="ND_absval_vector3" target="genglsl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_vector4_genglsl" nodedef="ND_absval_vector4" target="genglsl" sourcecode="abs({{in}})" />

  <!-- <floor> -->
  <implementation name="IM_floor_float_genglsl" nodedef="ND_floor_float" target="genglsl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_color3_genglsl" nodedef="ND_floor_color3" target="genglsl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_color4_genglsl" nodedef="ND_floor_color4" target="genglsl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_vector2_genglsl" nodedef="ND_floor_vector2" target="genglsl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_vector3_genglsl" nodedef="ND_floor_vector3" target="genglsl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_vector4_genglsl" nodedef="ND_floor_vector4" target="genglsl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_integer_genglsl" nodedef="ND_floor_integer" target="genglsl" sourcecode="int(floor({{in}}))" />

  <!-- <ceil> -->
  <implementation name="IM_ceil_float_genglsl" nodedef="ND_ceil_float" target="genglsl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_color3_genglsl" nodedef="ND_ceil_color3" target="genglsl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_color4_genglsl" nodedef="ND_ceil_color4" target="genglsl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_vector2_genglsl" nodedef="ND_ceil_vector2" target="genglsl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_vector3_genglsl" nodedef="ND_ceil_vector3" target="genglsl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_vector4_genglsl" nodedef="ND_ceil_vector4" target="genglsl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_integer_genglsl" nodedef="ND_ceil_integer" target="genglsl" sourcecode="int(ceil({{in}}))" />

  <!-- <round> -->
  <implementation name="IM_round_float_genglsl" nodedef="ND_round_float" target="genglsl" sourcecode="round({{in}})" />
  <implementation name="IM_round_color3_genglsl" nodedef="ND_round_color3" target="genglsl" sourcecode="round({{in}})" />
  <implementation name="IM_round_color4_genglsl" nodedef="ND_round_color4" target="genglsl" sourcecode="round({{in}})" />
  <implementation name="IM_round_vector2_genglsl" nodedef="ND_round_vector2" target="genglsl" sourcecode="round({{in}})" />
  <implementation name="IM_round_vector3_genglsl" nodedef="ND_round_vector3" target="genglsl" sourcecode="round({{in}})" />
  <implementation name="IM_round_vector4_genglsl" nodedef="ND_round_vector4" target="genglsl" sourcecode="round({{in}})" />
  <implementation name="IM_round_integer_genglsl" nodedef="ND_round_integer" target="genglsl" sourcecode="int(round({{in}}))" />

  <!-- <power> -->
  <implementation name="IM_power_float_genglsl" nodedef="ND_power_float" target="genglsl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_color3_genglsl" nodedef="ND_power_color3" target="genglsl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_color3FA_genglsl" nodedef="ND_power_color3FA" target="genglsl" sourcecode="pow({{in1}}, vec3({{in2}}))" />
  <implementation name="IM_power_color4_genglsl" nodedef="ND_power_color4" target="genglsl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_color4FA_genglsl" nodedef="ND_power_color4FA" target="genglsl" sourcecode="pow({{in1}}, vec4({{in2}}))" />
  <implementation name="IM_power_vector2_genglsl" nodedef="ND_power_vector2" target="genglsl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector2FA_genglsl" nodedef="ND_power_vector2FA" target="genglsl" sourcecode="pow({{in1}}, vec2({{in2}}))" />
  <implementation name="IM_power_vector3_genglsl" nodedef="ND_power_vector3" target="genglsl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector3FA_genglsl" nodedef="ND_power_vector3FA" target="genglsl" sourcecode="pow({{in1}}, vec3({{in2}}))" />
  <implementation name="IM_power_vector4_genglsl" nodedef="ND_power_vector4" target="genglsl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector4FA_genglsl" nodedef="ND_power_vector4FA" target="genglsl" sourcecode="pow({{in1}}, vec4({{in2}}))" />

  <!-- <sin>, <cos>, <tan>, <asin>, <acos>, <atan2> -->
  <implementation name="IM_sin_float_genglsl" nodedef="ND_sin_float" target="genglsl" sourcecode="mx_sin({{in}})" />
  <implementation name="IM_cos_float_genglsl" nodedef="ND_cos_float" target="genglsl" sourcecode="mx_cos({{in}})" />
  <implementation name="IM_tan_float_genglsl" nodedef="ND_tan_float" target="genglsl" sourcecode="mx_tan({{in}})" />
  <implementation name="IM_asin_float_genglsl" nodedef="ND_asin_float" target="genglsl" sourcecode="mx_asin({{in}})" />
  <implementation name="IM_acos_float_genglsl" nodedef="ND_acos_float" target="genglsl" sourcecode="mx_acos({{in}})" />
  <implementation name="IM_atan2_float_genglsl" nodedef="ND_atan2_float" target="genglsl" sourcecode="mx_atan({{iny}}, {{inx}})" />
  <implementation name="IM_sin_vector2_genglsl" nodedef="ND_sin_vector2" target="genglsl" sourcecode="mx_sin({{in}})" />
  <implementation name="IM_cos_vector2_genglsl" nodedef="ND_cos_vector2" target="genglsl" sourcecode="mx_cos({{in}})" />
  <implementation name="IM_tan_vector2_genglsl" nodedef="ND_tan_vector2" target="genglsl" sourcecode="mx_tan({{in}})" />
  <implementation name="IM_asin_vector2_genglsl" nodedef="ND_asin_vector2" target="genglsl" sourcecode="mx_asin({{in}})" />
  <implementation name="IM_acos_vector2_genglsl" nodedef="ND_acos_vector2" target="genglsl" sourcecode="mx_acos({{in}})" />
  <implementation name="IM_atan2_vector2_genglsl" nodedef="ND_atan2_vector2" target="genglsl" sourcecode="mx_atan({{iny}}, {{inx}})" />
  <implementation name="IM_sin_vector3_genglsl" nodedef="ND_sin_vector3" target="genglsl" sourcecode="mx_sin({{in}})" />
  <implementation name="IM_cos_vector3_genglsl" nodedef="ND_cos_vector3" target="genglsl" sourcecode="mx_cos({{in}})" />
  <implementation name="IM_tan_vector3_genglsl" nodedef="ND_tan_vector3" target="genglsl" sourcecode="mx_tan({{in}})" />
  <implementation name="IM_asin_vector3_genglsl" nodedef="ND_asin_vector3" target="genglsl" sourcecode="mx_asin({{in}})" />
  <implementation name="IM_acos_vector3_genglsl" nodedef="ND_acos_vector3" target="genglsl" sourcecode="mx_acos({{in}})" />
  <implementation name="IM_atan2_vector3_genglsl" nodedef="ND_atan2_vector3" target="genglsl" sourcecode="mx_atan({{iny}}, {{inx}})" />
  <implementation name="IM_sin_vector4_genglsl" nodedef="ND_sin_vector4" target="genglsl" sourcecode="mx_sin({{in}})" />
  <implementation name="IM_cos_vector4_genglsl" nodedef="ND_cos_vector4" target="genglsl" sourcecode="mx_cos({{in}})" />
  <implementation name="IM_tan_vector4_genglsl" nodedef="ND_tan_vector4" target="genglsl" sourcecode="mx_tan({{in}})" />
  <implementation name="IM_asin_vector4_genglsl" nodedef="ND_asin_vector4" target="genglsl" sourcecode="mx_asin({{in}})" />
  <implementation name="IM_acos_vector4_genglsl" nodedef="ND_acos_vector4" target="genglsl" sourcecode="mx_acos({{in}})" />
  <implementation name="IM_atan2_vector4_genglsl" nodedef="ND_atan2_vector4" target="genglsl" sourcecode="mx_atan({{iny}}, {{inx}})" />

  <!-- <sqrt> -->
  <implementation name="IM_sqrt_float_genglsl" nodedef="ND_sqrt_float" target="genglsl" sourcecode="sqrt({{in}})" />
  <implementation name="IM_sqrt_vector2_genglsl" nodedef="ND_sqrt_vector2" target="genglsl" sourcecode="sqrt({{in}})" />
  <implementation name="IM_sqrt_vector3_genglsl" nodedef="ND_sqrt_vector3" target="genglsl" sourcecode="sqrt({{in}})" />
  <implementation name="IM_sqrt_vector4_genglsl" nodedef="ND_sqrt_vector4" target="genglsl" sourcecode="sqrt({{in}})" />

  <!-- <ln> -->
  <implementation name="IM_ln_float_genglsl" nodedef="ND_ln_float" target="genglsl" sourcecode="log({{in}})" />
  <implementation name="IM_ln_vector2_genglsl" nodedef="ND_ln_vector2" target="genglsl" sourcecode="log({{in}})" />
  <implementation name="IM_ln_vector3_genglsl" nodedef="ND_ln_vector3" target="genglsl" sourcecode="log({{in}})" />
  <implementation name="IM_ln_vector4_genglsl" nodedef="ND_ln_vector4" target="genglsl" sourcecode="log({{in}})" />

  <!-- <exp> -->
  <implementation name="IM_exp_float_genglsl" nodedef="ND_exp_float" target="genglsl" sourcecode="exp({{in}})" />
  <implementation name="IM_exp_vector2_genglsl" nodedef="ND_exp_vector2" target="genglsl" sourcecode="exp({{in}})" />
  <implementation name="IM_exp_vector3_genglsl" nodedef="ND_exp_vector3" target="genglsl" sourcecode="exp({{in}})" />
  <implementation name="IM_exp_vector4_genglsl" nodedef="ND_exp_vector4" target="genglsl" sourcecode="exp({{in}})" />

  <!-- sign -->
  <implementation name="IM_sign_float_genglsl" nodedef="ND_sign_float" target="genglsl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_color3_genglsl" nodedef="ND_sign_color3" target="genglsl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_color4_genglsl" nodedef="ND_sign_color4" target="genglsl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_vector2_genglsl" nodedef="ND_sign_vector2" target="genglsl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_vector3_genglsl" nodedef="ND_sign_vector3" target="genglsl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_vector4_genglsl" nodedef="ND_sign_vector4" target="genglsl" sourcecode="sign({{in}})" />

  <!-- <clamp> -->
  <implementation name="IM_clamp_float_genglsl" nodedef="ND_clamp_float" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_color3_genglsl" nodedef="ND_clamp_color3" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_color3FA_genglsl" nodedef="ND_clamp_color3FA" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_color4_genglsl" nodedef="ND_clamp_color4" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_color4FA_genglsl" nodedef="ND_clamp_color4FA" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector2_genglsl" nodedef="ND_clamp_vector2" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector2FA_genglsl" nodedef="ND_clamp_vector2FA" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector3_genglsl" nodedef="ND_clamp_vector3" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector3FA_genglsl" nodedef="ND_clamp_vector3FA" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector4_genglsl" nodedef="ND_clamp_vector4" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector4FA_genglsl" nodedef="ND_clamp_vector4FA" target="genglsl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />

  <!-- <min> -->
  <implementation name="IM_min_float_genglsl" nodedef="ND_min_float" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_color3_genglsl" nodedef="ND_min_color3" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_color3FA_genglsl" nodedef="ND_min_color3FA" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_color4_genglsl" nodedef="ND_min_color4" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_color4FA_genglsl" nodedef="ND_min_color4FA" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector2_genglsl" nodedef="ND_min_vector2" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector2FA_genglsl" nodedef="ND_min_vector2FA" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector3_genglsl" nodedef="ND_min_vector3" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector3FA_genglsl" nodedef="ND_min_vector3FA" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector4_genglsl" nodedef="ND_min_vector4" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector4FA_genglsl" nodedef="ND_min_vector4FA" target="genglsl" sourcecode="min({{in1}}, {{in2}})" />

  <!-- <max> -->
  <implementation name="IM_max_float_genglsl" nodedef="ND_max_float" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_color3_genglsl" nodedef="ND_max_color3" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_color3FA_genglsl" nodedef="ND_max_color3FA" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_color4_genglsl" nodedef="ND_max_color4" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_color4FA_genglsl" nodedef="ND_max_color4FA" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector2_genglsl" nodedef="ND_max_vector2" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector2FA_genglsl" nodedef="ND_max_vector2FA" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector3_genglsl" nodedef="ND_max_vector3" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector3FA_genglsl" nodedef="ND_max_vector3FA" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector4_genglsl" nodedef="ND_max_vector4" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector4FA_genglsl" nodedef="ND_max_vector4FA" target="genglsl" sourcecode="max({{in1}}, {{in2}})" />

  <!-- <normalize> -->
  <implementation name="IM_normalize_vector2_genglsl" nodedef="ND_normalize_vector2" target="genglsl" sourcecode="normalize({{in}})" />
  <implementation name="IM_normalize_vector3_genglsl" nodedef="ND_normalize_vector3" target="genglsl" sourcecode="normalize({{in}})" />
  <implementation name="IM_normalize_vector4_genglsl" nodedef="ND_normalize_vector4" target="genglsl" sourcecode="normalize({{in}})" />

  <!-- <magnitude> -->
  <implementation name="IM_magnitude_vector2_genglsl" nodedef="ND_magnitude_vector2" target="genglsl" sourcecode="length({{in}})" />
  <implementation name="IM_magnitude_vector3_genglsl" nodedef="ND_magnitude_vector3" target="genglsl" sourcecode="length({{in}})" />
  <implementation name="IM_magnitude_vector4_genglsl" nodedef="ND_magnitude_vector4" target="genglsl" sourcecode="length({{in}})" />

  <!-- <dotproduct> -->
  <implementation name="IM_dotproduct_vector2_genglsl" nodedef="ND_dotproduct_vector2" target="genglsl" sourcecode="dot({{in1}}, {{in2}})" />
  <implementation name="IM_dotproduct_vector3_genglsl" nodedef="ND_dotproduct_vector3" target="genglsl" sourcecode="dot({{in1}}, {{in2}})" />
  <implementation name="IM_dotproduct_vector4_genglsl" nodedef="ND_dotproduct_vector4" target="genglsl" sourcecode="dot({{in1}}, {{in2}})" />

  <!-- <crossproduct> -->
  <implementation name="IM_crossproduct_vector3_genglsl" nodedef="ND_crossproduct_vector3" target="genglsl" sourcecode="cross({{in1}}, {{in2}})" />

  <!-- <transformpoint> -->
  <implementation name="IM_transformpoint_vector3_genglsl" nodedef="ND_transformpoint_vector3" target="genglsl" />

  <!-- <transformvector> -->
  <implementation name="IM_transformvector_vector3_genglsl" nodedef="ND_transformvector_vector3" target="genglsl" />

  <!-- <transformnormal> -->
  <implementation name="IM_transformnormal_vector3_genglsl" nodedef="ND_transformnormal_vector3" target="genglsl" />

  <!-- <transformmatrix> -->
  <implementation name="IM_transformmatrix_vector2M3_genglsl" nodedef="ND_transformmatrix_vector2M3" function="mx_transformmatrix_vector2M3" file="mx_transformmatrix_vector2M3.glsl" target="genglsl" />
  <implementation name="IM_transformmatrix_vector3_genglsl" nodedef="ND_transformmatrix_vector3" target="genglsl" sourcecode="{{mat}} * {{in}}" />
  <implementation name="IM_transformmatrix_vector3M4_genglsl" nodedef="ND_transformmatrix_vector3M4" function="mx_transformmatrix_vector3M4" file="mx_transformmatrix_vector3M4.glsl" target="genglsl" />
  <implementation name="IM_transformmatrix_vector4_genglsl" nodedef="ND_transformmatrix_vector4" target="genglsl" sourcecode="{{mat}} * {{in}}" />

  <!-- <transpose> -->
  <implementation name="IM_transpose_matrix33_genglsl" nodedef="ND_transpose_matrix33" target="genglsl" sourcecode="transpose({{in}})" />
  <implementation name="IM_transpose_matrix44_genglsl" nodedef="ND_transpose_matrix44" target="genglsl" sourcecode="transpose({{in}})" />

  <!-- <determinant> -->
  <implementation name="IM_determinant_matrix33_genglsl" nodedef="ND_determinant_matrix33" target="genglsl" sourcecode="determinant({{in}})" />
  <implementation name="IM_determinant_matrix44_genglsl" nodedef="ND_determinant_matrix44" target="genglsl" sourcecode="determinant({{in}})" />

  <!-- <invertmatrix> -->
  <implementation name="IM_invertmatrix_matrix33_genglsl" nodedef="ND_invertmatrix_matrix33" target="genglsl" sourcecode="mx_inverse({{in}})" />
  <implementation name="IM_invertmatrix_matrix44_genglsl" nodedef="ND_invertmatrix_matrix44" target="genglsl" sourcecode="mx_inverse({{in}})" />

  <!-- <rotate2d> -->
  <implementation name="IM_rotate2d_vector2_genglsl" nodedef="ND_rotate2d_vector2" file="mx_rotate_vector2.glsl" function="mx_rotate_vector2" target="genglsl" />

  <!-- <rotate3d> -->
  <implementation name="IM_rotate3d_vector3_genglsl" nodedef="ND_rotate3d_vector3" file="mx_rotate_vector3.glsl" function="mx_rotate_vector3" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Adjustment nodes                                                         -->
  <!-- ======================================================================== -->

  <!-- <contrast> -->

  <!-- <remap> -->
  <implementation name="IM_remap_float_genglsl" nodedef="ND_remap_float" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_color3_genglsl" nodedef="ND_remap_color3" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_color3FA_genglsl" nodedef="ND_remap_color3FA" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_color4_genglsl" nodedef="ND_remap_color4" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_color4FA_genglsl" nodedef="ND_remap_color4FA" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_vector2_genglsl" nodedef="ND_remap_vector2" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_vector2FA_genglsl" nodedef="ND_remap_vector2FA" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_vector3_genglsl" nodedef="ND_remap_vector3" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_vector3FA_genglsl" nodedef="ND_remap_vector3FA" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_vector4_genglsl" nodedef="ND_remap_vector4" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />
  <implementation name="IM_remap_vector4FA_genglsl" nodedef="ND_remap_vector4FA" target="genglsl" sourcecode="{{outlow}} + ({{in}} - {{inlow}}) * ({{outhigh}} - {{outlow}}) / ({{inhigh}} - {{inlow}})" />

  <!-- <smoothstep> -->
  <implementation name="IM_smoothstep_float_genglsl" nodedef="ND_smoothstep_float" file="mx_smoothstep_float.glsl" function="mx_smoothstep_float" target="genglsl" />

  <!-- <luminance> -->
  <implementation name="IM_luminance_color3_genglsl" nodedef="ND_luminance_color3" file="mx_luminance_color3.glsl" function="mx_luminance_color3" target="genglsl" />
  <implementation name="IM_luminance_color4_genglsl" nodedef="ND_luminance_color4" file="mx_luminance_color4.glsl" function="mx_luminance_color4" target="genglsl" />

  <!-- <rgbtohsv> -->
  <implementation name="IM_rgbtohsv_color3_genglsl" nodedef="ND_rgbtohsv_color3" file="mx_rgbtohsv_color3.glsl" function="mx_rgbtohsv_color3" target="genglsl" />
  <implementation name="IM_rgbtohsv_color4_genglsl" nodedef="ND_rgbtohsv_color4" file="mx_rgbtohsv_color4.glsl" function="mx_rgbtohsv_color4" target="genglsl" />

  <!-- <hsvtorgb> -->
  <implementation name="IM_hsvtorgb_color3_genglsl" nodedef="ND_hsvtorgb_color3" file="mx_hsvtorgb_color3.glsl" function="mx_hsvtorgb_color3" target="genglsl" />
  <implementation name="IM_hsvtorgb_color4_genglsl" nodedef="ND_hsvtorgb_color4" file="mx_hsvtorgb_color4.glsl" function="mx_hsvtorgb_color4" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Compositing nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <premult> -->
  <implementation name="IM_premult_color4_genglsl" nodedef="ND_premult_color4" file="mx_premult_color4.glsl" function="mx_premult_color4" target="genglsl" />

  <!-- <unpremult> -->
  <implementation name="IM_unpremult_color4_genglsl" nodedef="ND_unpremult_color4" file="mx_unpremult_color4.glsl" function="mx_unpremult_color4" target="genglsl" />

  <!-- <plus> -->
  <implementation name="IM_plus_float_genglsl" nodedef="ND_plus_float" target="genglsl" sourcecode="({{mix}}*({{bg}} + {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_plus_color3_genglsl" nodedef="ND_plus_color3" target="genglsl" sourcecode="({{mix}}*({{bg}} + {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_plus_color4_genglsl" nodedef="ND_plus_color4" target="genglsl" sourcecode="({{mix}}*({{bg}} + {{fg}})) + ((1.0-{{mix}})*{{bg}})" />

  <!-- <minus> -->
  <implementation name="IM_minus_float_genglsl" nodedef="ND_minus_float" target="genglsl" sourcecode="({{mix}}*({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_minus_color3_genglsl" nodedef="ND_minus_color3" target="genglsl" sourcecode="({{mix}}*({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_minus_color4_genglsl" nodedef="ND_minus_color4" target="genglsl" sourcecode="({{mix}}*({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />

  <!-- <difference> -->
  <implementation name="IM_difference_float_genglsl" nodedef="ND_difference_float" target="genglsl" sourcecode="({{mix}}*abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_difference_color3_genglsl" nodedef="ND_difference_color3" target="genglsl" sourcecode="({{mix}}*abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_difference_color4_genglsl" nodedef="ND_difference_color4" target="genglsl" sourcecode="({{mix}}*abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />

  <!-- <burn> -->
  <implementation name="IM_burn_float_genglsl" nodedef="ND_burn_float" file="mx_burn_float.glsl" function="mx_burn_float" target="genglsl" />
  <implementation name="IM_burn_color3_genglsl" nodedef="ND_burn_color3" file="mx_burn_color3.glsl" function="mx_burn_color3" target="genglsl" />
  <implementation name="IM_burn_color4_genglsl" nodedef="ND_burn_color4" file="mx_burn_color4.glsl" function="mx_burn_color4" target="genglsl" />

  <!-- <dodge> -->
  <implementation name="IM_dodge_float_genglsl" nodedef="ND_dodge_float" file="mx_dodge_float.glsl" function="mx_dodge_float" target="genglsl" />
  <implementation name="IM_dodge_color3_genglsl" nodedef="ND_dodge_color3" file="mx_dodge_color3.glsl" function="mx_dodge_color3" target="genglsl" />
  <implementation name="IM_dodge_color4_genglsl" nodedef="ND_dodge_color4" file="mx_dodge_color4.glsl" function="mx_dodge_color4" target="genglsl" />

  <!-- <screen> -->
  <implementation name="IM_screen_float_genglsl" nodedef="ND_screen_float" target="genglsl" sourcecode="({{mix}}*((1.0 - (1.0 - {{fg}}) * (1.0 - {{bg}})))) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_screen_color3_genglsl" nodedef="ND_screen_color3" target="genglsl" sourcecode="({{mix}}*((1.0 - (1.0 - {{fg}}) * (1.0 - {{bg}})))) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_screen_color4_genglsl" nodedef="ND_screen_color4" target="genglsl" sourcecode="({{mix}}*((1.0 - (1.0 - {{fg}}) * (1.0 - {{bg}})))) + ((1.0-{{mix}})*{{bg}})" />

  <!-- <disjointover> -->
  <implementation name="IM_disjointover_color4_genglsl" nodedef="ND_disjointover_color4" file="mx_disjointover_color4.glsl" function="mx_disjointover_color4" target="genglsl" />

  <!-- <in> -->
  <implementation name="IM_in_color4_genglsl" nodedef="ND_in_color4" target="genglsl" sourcecode="({{fg}}*{{bg}}.a  * {{mix}}) + ({{bg}} * (1.0-{{mix}}));" />

  <!-- <mask> -->
  <implementation name="IM_mask_color4_genglsl" nodedef="ND_mask_color4" target="genglsl" sourcecode="({{bg}}*{{fg}}.a  * {{mix}}) + ({{bg}} * (1.0-{{mix}}));" />

  <!-- <matte> -->
  <implementation name="IM_matte_color4_genglsl" nodedef="ND_matte_color4" target="genglsl" sourcecode="vec4( {{fg}}.xyz*{{fg}}.w + {{bg}}.xyz*(1.0-{{fg}}.w), {{fg}}.w + ({{bg}}.w*(1.0-{{fg}}.w)) ) * {{mix}} + ({{bg}} * (1.0-{{mix}}));" />

  <!-- <out> -->
  <implementation name="IM_out_color4_genglsl" nodedef="ND_out_color4" target="genglsl" sourcecode="({{fg}}*(1.0-{{bg}}.a)  * {{mix}}) + ({{bg}} * (1.0-{{mix}}));" />

  <!-- <over> -->
  <implementation name="IM_over_color4_genglsl" nodedef="ND_over_color4" target="genglsl" sourcecode="({{fg}} + ({{bg}}*(1.0-{{fg}}[3]))) * {{mix}} + {{bg}} * (1.0-{{mix}})" />

  <!-- <inside> -->
  <implementation name="IM_inside_float_genglsl" nodedef="ND_inside_float" target="genglsl" sourcecode="{{in}} * {{mask}}" />
  <implementation name="IM_inside_color3_genglsl" nodedef="ND_inside_color3" target="genglsl" sourcecode="{{in}} * {{mask}}" />
  <implementation name="IM_inside_color4_genglsl" nodedef="ND_inside_color4" target="genglsl" sourcecode="{{in}} * {{mask}}" />

  <!-- <outside> -->
  <implementation name="IM_outside_float_genglsl" nodedef="ND_outside_float" target="genglsl" sourcecode="{{in}} * (1.0 - {{mask}})" />
  <implementation name="IM_outside_color3_genglsl" nodedef="ND_outside_color3" target="genglsl" sourcecode="{{in}} * (1.0 - {{mask}})" />
  <implementation name="IM_outside_color4_genglsl" nodedef="ND_outside_color4" target="genglsl" sourcecode="{{in}} * (1.0 - {{mask}})" />

  <!-- <mix> -->
  <implementation name="IM_mix_float_genglsl" nodedef="ND_mix_float" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_color3_genglsl" nodedef="ND_mix_color3" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_color3_color3_genglsl" nodedef="ND_mix_color3_color3" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_color4_genglsl" nodedef="ND_mix_color4" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_color4_color4_genglsl" nodedef="ND_mix_color4_color4" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector2_genglsl" nodedef="ND_mix_vector2" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector2_vector2_genglsl" nodedef="ND_mix_vector2_vector2" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector3_genglsl" nodedef="ND_mix_vector3" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector3_vector3_genglsl" nodedef="ND_mix_vector3_vector3" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector4_genglsl" nodedef="ND_mix_vector4" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector4_vector4_genglsl" nodedef="ND_mix_vector4_vector4" target="genglsl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_surfaceshader_genglsl" nodedef="ND_mix_surfaceshader" function="mx_mix_surfaceshader" file="mx_mix_surfaceshader.glsl" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Conditional nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <ifgreater -->
  <implementation name="IM_ifgreater_float_genglsl" nodedef="ND_ifgreater_float" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_integer_genglsl" nodedef="ND_ifgreater_integer" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_color3_genglsl" nodedef="ND_ifgreater_color3" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_color4_genglsl" nodedef="ND_ifgreater_color4" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_vector2_genglsl" nodedef="ND_ifgreater_vector2" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_vector3_genglsl" nodedef="ND_ifgreater_vector3" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_vector4_genglsl" nodedef="ND_ifgreater_vector4" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_matrix33_genglsl" nodedef="ND_ifgreater_matrix33" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_matrix44_genglsl" nodedef="ND_ifgreater_matrix44" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_boolean_genglsl" nodedef="ND_ifgreater_boolean" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? true : false" />
  <implementation name="IM_ifgreater_floatI_genglsl" nodedef="ND_ifgreater_floatI" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_integerI_genglsl" nodedef="ND_ifgreater_integerI" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_color3I_genglsl" nodedef="ND_ifgreater_color3I" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_color4I_genglsl" nodedef="ND_ifgreater_color4I" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_vector2I_genglsl" nodedef="ND_ifgreater_vector2I" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_vector3I_genglsl" nodedef="ND_ifgreater_vector3I" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_vector4I_genglsl" nodedef="ND_ifgreater_vector4I" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_matrix33I_genglsl" nodedef="ND_ifgreater_matrix33I" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_matrix44I_genglsl" nodedef="ND_ifgreater_matrix44I" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreater_booleanI_genglsl" nodedef="ND_ifgreater_booleanI" target="genglsl" sourcecode="({{value1}} > {{value2}}) ? true : false" />

  <!-- <ifgreatereq -->
  <implementation name="IM_ifgreatereq_float_genglsl" nodedef="ND_ifgreatereq_float" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_integer_genglsl" nodedef="ND_ifgreatereq_integer" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_color3_genglsl" nodedef="ND_ifgreatereq_color3" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_color4_genglsl" nodedef="ND_ifgreatereq_color4" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_vector2_genglsl" nodedef="ND_ifgreatereq_vector2" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_vector3_genglsl" nodedef="ND_ifgreatereq_vector3" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_vector4_genglsl" nodedef="ND_ifgreatereq_vector4" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_matrix33_genglsl" nodedef="ND_ifgreatereq_matrix33" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_matrix44_genglsl" nodedef="ND_ifgreatereq_matrix44" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_boolean_genglsl" nodedef="ND_ifgreatereq_boolean" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? true : false" />
  <implementation name="IM_ifgreatereq_floatI_genglsl" nodedef="ND_ifgreatereq_floatI" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_integerI_genglsl" nodedef="ND_ifgreatereq_integerI" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_color3I_genglsl" nodedef="ND_ifgreatereq_color3I" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_color4I_genglsl" nodedef="ND_ifgreatereq_color4I" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_vector2I_genglsl" nodedef="ND_ifgreatereq_vector2I" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_vector3I_genglsl" nodedef="ND_ifgreatereq_vector3I" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_vector4I_genglsl" nodedef="ND_ifgreatereq_vector4I" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_matrix33I_genglsl" nodedef="ND_ifgreatereq_matrix33I" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_matrix44I_genglsl" nodedef="ND_ifgreatereq_matrix44I" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifgreatereq_booleanI_genglsl" nodedef="ND_ifgreatereq_booleanI" target="genglsl" sourcecode="({{value1}} >= {{value2}}) ? true : false" />

  <!-- <ifequal -->
  <implementation name="IM_ifequal_float_genglsl" nodedef="ND_ifequal_float" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_integer_genglsl" nodedef="ND_ifequal_integer" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_color3_genglsl" nodedef="ND_ifequal_color3" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_color4_genglsl" nodedef="ND_ifequal_color4" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector2_genglsl" nodedef="ND_ifequal_vector2" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector3_genglsl" nodedef="ND_ifequal_vector3" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector4_genglsl" nodedef="ND_ifequal_vector4" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_matrix33_genglsl" nodedef="ND_ifequal_matrix33" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_matrix44_genglsl" nodedef="ND_ifequal_matrix44" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_boolean_genglsl" nodedef="ND_ifequal_boolean" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? true : false" />
  <implementation name="IM_ifequal_floatI_genglsl" nodedef="ND_ifequal_floatI" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_integerI_genglsl" nodedef="ND_ifequal_integerI" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_color3I_genglsl" nodedef="ND_ifequal_color3I" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_color4I_genglsl" nodedef="ND_ifequal_color4I" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector2I_genglsl" nodedef="ND_ifequal_vector2I" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector3I_genglsl" nodedef="ND_ifequal_vector3I" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector4I_genglsl" nodedef="ND_ifequal_vector4I" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_matrix33I_genglsl" nodedef="ND_ifequal_matrix33I" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_matrix44I_genglsl" nodedef="ND_ifequal_matrix44I" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_booleanI_genglsl" nodedef="ND_ifequal_booleanI" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? true : false" />
  <implementation name="IM_ifequal_floatB_genglsl" nodedef="ND_ifequal_floatB" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_integerB_genglsl" nodedef="ND_ifequal_integerB" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_color3B_genglsl" nodedef="ND_ifequal_color3B" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_color4B_genglsl" nodedef="ND_ifequal_color4B" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector2B_genglsl" nodedef="ND_ifequal_vector2B" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector3B_genglsl" nodedef="ND_ifequal_vector3B" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_vector4B_genglsl" nodedef="ND_ifequal_vector4B" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_matrix33B_genglsl" nodedef="ND_ifequal_matrix33B" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_matrix44B_genglsl" nodedef="ND_ifequal_matrix44B" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? {{in1}} : {{in2}}" />
  <implementation name="IM_ifequal_booleanB_genglsl" nodedef="ND_ifequal_booleanB" target="genglsl" sourcecode="({{value1}} == {{value2}}) ? true : false" />

  <!-- ======================================================================== -->
  <!-- Channel nodes                                                            -->
  <!-- ======================================================================== -->

  <!-- <convert> -->
  <implementation name="IM_convert_boolean_float_genglsl" nodedef="ND_convert_boolean_float" target="genglsl" sourcecode="float({{in}})" />
  <implementation name="IM_convert_integer_float_genglsl" nodedef="ND_convert_integer_float" target="genglsl" sourcecode="float({{in}})" />

  <!-- <combine2> -->
  <implementation name="IM_combine2_vector2_genglsl" nodedef="ND_combine2_vector2" target="genglsl" sourcecode="vec2({{in1}},{{in2}})" />
  <implementation name="IM_combine2_color4CF_genglsl" nodedef="ND_combine2_color4CF" target="genglsl" sourcecode="vec4({{in1}}[0],{{in1}}[1],{{in1}}[2],{{in2}})" />
  <implementation name="IM_combine2_vector4VF_genglsl" nodedef="ND_combine2_vector4VF" target="genglsl" sourcecode="vec4({{in1}}[0],{{in1}}[1],{{in1}}[2],{{in2}})" />
  <implementation name="IM_combine2_vector4VV_genglsl" nodedef="ND_combine2_vector4VV" target="genglsl" sourcecode="vec4({{in1}}[0],{{in1}}[1],{{in2}}[0],{{in2}}[1])" />

  <!-- <combine3> -->
  <implementation name="IM_combine3_color3_genglsl" nodedef="ND_combine3_color3" target="genglsl" sourcecode="vec3({{in1}},{{in2}},{{in3}})" />
  <implementation name="IM_combine3_vector3_genglsl" nodedef="ND_combine3_vector3" target="genglsl" sourcecode="vec3({{in1}},{{in2}},{{in3}})" />

  <!-- <combine4> -->
  <implementation name="IM_combine4_color4_genglsl" nodedef="ND_combine4_color4" target="genglsl" sourcecode="vec4({{in1}},{{in2}},{{in3}},{{in4}})" />
  <implementation name="IM_combine4_vector4_genglsl" nodedef="ND_combine4_vector4" target="genglsl" sourcecode="vec4({{in1}},{{in2}},{{in3}},{{in4}})" />

  <!-- <creatematrix> -->
  <implementation name="IM_creatematrix_vector3_matrix33_genglsl" nodedef="ND_creatematrix_vector3_matrix33" file="mx_creatematrix_vector3_matrix33.glsl" function="mx_creatematrix_vector3_matrix33" target="genglsl" />
  <implementation name="IM_creatematrix_vector3_matrix44_genglsl" nodedef="ND_creatematrix_vector3_matrix44" file="mx_creatematrix_vector3_matrix44.glsl" function="mx_creatematrix_vector3_matrix44" target="genglsl" />
  <implementation name="IM_creatematrix_vector4_matrix44_genglsl" nodedef="ND_creatematrix_vector4_matrix44" file="mx_creatematrix_vector4_matrix44.glsl" function="mx_creatematrix_vector4_matrix44" target="genglsl" />

  <!-- <extract> -->
  <implementation name="IM_extract_color3_genglsl" nodedef="ND_extract_color3" sourcecode="{{in}}[{{index}}]" target="genglsl" />
  <implementation name="IM_extract_color4_genglsl" nodedef="ND_extract_color4" sourcecode="{{in}}[{{index}}]" target="genglsl" />
  <implementation name="IM_extract_vector2_genglsl" nodedef="ND_extract_vector2" sourcecode="{{in}}[{{index}}]" target="genglsl" />
  <implementation name="IM_extract_vector3_genglsl" nodedef="ND_extract_vector3" sourcecode="{{in}}[{{index}}]" target="genglsl" />
  <implementation name="IM_extract_vector4_genglsl" nodedef="ND_extract_vector4" sourcecode="{{in}}[{{index}}]" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Convolution nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <blur> -->
  <implementation name="IM_blur_float_genglsl" nodedef="ND_blur_float" target="genglsl" />
  <implementation name="IM_blur_color3_genglsl" nodedef="ND_blur_color3" target="genglsl" />
  <implementation name="IM_blur_color4_genglsl" nodedef="ND_blur_color4" target="genglsl" />
  <implementation name="IM_blur_vector2_genglsl" nodedef="ND_blur_vector2" target="genglsl" />
  <implementation name="IM_blur_vector3_genglsl" nodedef="ND_blur_vector3" target="genglsl" />
  <implementation name="IM_blur_vector4_genglsl" nodedef="ND_blur_vector4" target="genglsl" />

  <!-- <heighttonormal> -->
  <implementation name="IM_heighttonormal_vector3_genglsl" nodedef="ND_heighttonormal_vector3" file="mx_heighttonormal_vector3.glsl" function="mx_heighttonormal_vector3" target="genglsl" />

  <!-- ======================================================================== -->
  <!-- Logical operator nodes                                                   -->
  <!-- ======================================================================== -->

  <implementation name="IM_logical_and_genglsl" nodedef="ND_logical_and" target="genglsl" sourcecode="{{in1}} && {{in2}}"/>
  <implementation name="IM_logical_or_genglsl" nodedef="ND_logical_or" target="genglsl" sourcecode="{{in1}} || {{in2}}"/>
  <implementation name="IM_logical_not_genglsl" nodedef="ND_logical_not" target="genglsl" sourcecode="!{{in}}"/>

  <!-- ======================================================================== -->
  <!-- Organization nodes                                                       -->
  <!-- ======================================================================== -->

  <!-- <dot> -->
  <implementation name="IM_dot_float_genglsl" nodedef="ND_dot_float" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_color3_genglsl" nodedef="ND_dot_color3" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_color4_genglsl" nodedef="ND_dot_color4" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_vector2_genglsl" nodedef="ND_dot_vector2" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_vector3_genglsl" nodedef="ND_dot_vector3" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_vector4_genglsl" nodedef="ND_dot_vector4" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_integer_genglsl" nodedef="ND_dot_integer" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_boolean_genglsl" nodedef="ND_dot_boolean" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_matrix33_genglsl" nodedef="ND_dot_matrix33" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_matrix44_genglsl" nodedef="ND_dot_matrix44" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_string_genglsl" nodedef="ND_dot_string" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_filename_genglsl" nodedef="ND_dot_filename" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_surfaceshader_genglsl" nodedef="ND_dot_surfaceshader" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_displacementshader_genglsl" nodedef="ND_dot_displacementshader" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_volumeshader_genglsl" nodedef="ND_dot_volumeshader" target="genglsl" sourcecode="{{in}}" />
  <implementation name="IM_dot_lightshader_genglsl" nodedef="ND_dot_lightshader" target="genglsl" sourcecode="{{in}}" />
</materialx>
void mx_transformmatrix_vector3M4(vec3 val, mat4 transform, out vec3 result)
{
  vec4 res = transform * vec4(val, 1.0);
  result = res.xyz;
}
#include "lib/mx_noise.glsl"

void mx_noise3d_vector3(vec3 amplitude, float pivot, vec3 position, out vec3 result)
{
    vec3 value = mx_perlin_noise_vec3(position);
    result = value * amplitude + pivot;
}
#include "mx_aastep.glsl"

void mx_splitlr_vector3(vec3 valuel, vec3 valuer, float center, vec2 texcoord, out vec3 result)
{
    result = mix(valuel, valuer, mx_aastep(center, texcoord.x));
}
void mx_ramplr_vector2(vec2 valuel, vec2 valuer, vec2 texcoord, out vec2 result)
{
    result = mix (valuel, valuer, clamp(texcoord.x, 0.0, 1.0) );
}
#include "lib/mx_noise.glsl"

void mx_noise2d_vector2(vec2 amplitude, float pivot, vec2 texcoord, out vec2 result)
{
    vec3 value = mx_perlin_noise_vec3(texcoord);
    result = value.xy * amplitude + pivot;
}
#include "lib/mx_noise.glsl"

void mx_fractal3d_vector4(vec4 amplitude, int octaves, float lacunarity, float diminish, vec3 position, out vec4 result)
{
    vec4 value = mx_fractal3d_noise_vec4(position, octaves, lacunarity, diminish);
    result = value * amplitude;
}
#include "lib/$fileTransformUv"

#ifdef HW_SEPARATE_SAMPLERS
void mx_image_float(texture2D tex_texture, sampler tex_sampler, int layer, float defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out float result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(sampler2D(tex_texture, tex_sampler), uv).r;
}
#else
void mx_image_float(sampler2D tex_sampler, int layer, float defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out float result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(tex_sampler, uv).r;
}
#endif
void mx_ramptb_vector3(vec3 valuet, vec3 valueb, vec2 texcoord, out vec3 result)
{
    result = mix (valuet, valueb, clamp(texcoord.y, 0.0, 1.0) );
}
#include "lib/mx_hsv.glsl"

void mx_rgbtohsv_color3(vec3 _in, out vec3 result)
{
    result = mx_rgbtohsv(_in);
}
void mx_ramptb_vector2(vec2 valuet, vec2 valueb, vec2 texcoord, out vec2 result)
{
    result = mix (valuet, valueb, clamp(texcoord.y, 0.0, 1.0) );
}
#include "lib/mx_noise.glsl"

void mx_noise2d_vector3(vec3 amplitude, float pivot, vec2 texcoord, out vec3 result)
{
    vec3 value = mx_perlin_noise_vec3(texcoord);
    result = value * amplitude + pivot;
}
void mx_creatematrix_vector3_matrix33(vec3 in1, vec3 in2, vec3 in3, out mat3 result)
{
    result = mat3(in1.x, in1.y, in1.z,
                  in2.x, in2.y, in2.z,
                  in3.x, in3.y, in3.z);
}
mat4 mx_rotationMatrix(vec3 axis, float angle)
{
    axis = normalize(axis);
    float s = mx_sin(angle);
    float c = mx_cos(angle);
    float oc = 1.0 - c;

    return mat4(oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,  0.0,
                oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,  0.0,
                oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c,           0.0,
                0.0,                                0.0,                                0.0,                                1.0);
}

void mx_rotate_vector3(vec3 _in, float amount, vec3 axis, out vec3 result)
{
    float rotationRadians = mx_radians(amount);
    mat4 m = mx_rotationMatrix(axis, rotationRadians);
    result = (m * vec4(_in, 1.0)).xyz;
}
void mx_ramplr_vector3(vec3 valuel, vec3 valuer, vec2 texcoord, out vec3 result)
{
    result = mix (valuel, valuer, clamp(texcoord.x, 0.0, 1.0) );
}
#include "lib/$fileTransformUv"
#include "lib/mx_hextile.glsl"
#include "lib/mx_geometry.glsl"

// Morten S. Mikkelsen, Practical Real-Time Hex-Tiling, Journal of Computer Graphics
// Techniques (JCGT), vol. 11, no. 2, 77-94, 2022
// http://jcgt.org/published/0011/03/05/
void mx_hextilednormalmap_vector3(
#ifdef HW_SEPARATE_SAMPLERS
    texture2D tex_texture,
    sampler   tex_sampler,
#else
    sampler2D tex_sampler,
#endif
    vec3 default_value,
    vec2 tex_coord,
    vec2 tiling,
    float rotation,
    vec2 rotation_range,
    float scale,
    vec2 scale_range,
    float offset,
    vec2 offset_range,
    float falloff,
    float strength,
    bool flip_g,
    vec3 N,
    vec3 T,
    vec3 B,
    out vec3 result
)
{
    vec2 coord = mx_transform_uv(tex_coord, tiling, vec2(0.0));

    HextileData tile_data = mx_hextile_coord(coord, rotation, rotation_range, scale, scale_range, offset, offset_range);

#ifdef HW_SEPARATE_SAMPLERS
    vec3 nm1 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord1, tile_data.ddx1, tile_data.ddy1).xyz;
    vec3 nm2 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord2, tile_data.ddx2, tile_data.ddy2).xyz;
    vec3 nm3 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord3, tile_data.ddx3, tile_data.ddy3).xyz;
#else
    vec3 nm1 = textureGrad(tex_sampler, tile_data.coord1, tile_data.ddx1, tile_data.ddy1).xyz;
    vec3 nm2 = textureGrad(tex_sampler, tile_data.coord2, tile_data.ddx2, tile_data.ddy2).xyz;
    vec3 nm3 = textureGrad(tex_sampler, tile_data.coord3, tile_data.ddx3, tile_data.ddy3).xyz;
#endif
    
    nm1.y = flip_g ? 1.0 - nm1.y : nm1.y;
    nm2.y = flip_g ? 1.0 - nm2.y : nm2.y;
    nm3.y = flip_g ? 1.0 - nm3.y : nm3.y;

    // normalmap to shading normal
    nm1 = 2.0 * nm1 - 1.0;
    nm2 = 2.0 * nm2 - 1.0;
    nm3 = 2.0 * nm3 - 1.0;
    mat3 tangent_rot_mat1 = mx_axis_rotation_matrix(N, -tile_data.rot_radian1);
    mat3 tangent_rot_mat2 = mx_axis_rotation_matrix(N, -tile_data.rot_radian2);
    mat3 tangent_rot_mat3 = mx_axis_rotation_matrix(N, -tile_data.rot_radian3);
    vec3 T1 = tangent_rot_mat1 * T * strength;
    vec3 T2 = tangent_rot_mat2 * T * strength;
    vec3 T3 = tangent_rot_mat3 * T * strength;
    vec3 B1 = tangent_rot_mat1 * B * strength;
    vec3 B2 = tangent_rot_mat2 * B * strength;
    vec3 B3 = tangent_rot_mat3 * B * strength;
    vec3 N1 = normalize(T1 * nm1.x + B1 * nm1.y + N * nm1.z);
    vec3 N2 = normalize(T2 * nm2.x + B2 * nm2.y + N * nm2.z);
    vec3 N3 = normalize(T3 * nm3.x + B3 * nm3.y + N * nm3.z);

    // blend weights
    vec3 w = pow(tile_data.weights, vec3(7.0));
    w /= (w.x + w.y + w.z);

    // apply s-curve gain
    if (falloff != 0.5)
    {
        w.x = mx_schlick_gain(w.x, falloff);
        w.y = mx_schlick_gain(w.y, falloff);
        w.z = mx_schlick_gain(w.z, falloff);
        w /= (w.x + w.y + w.z);
    }

    // blend
    result = mx_gradient_blend_3_normals(N, N1, w.x, N2, w.y, N3, w.z);
}
void mx_luminance_color3(vec3 _in, vec3 lumacoeffs, out vec3 result)
{
    result = vec3(dot(_in, lumacoeffs));
}
#include "lib/mx_hsv.glsl"

void mx_hsvtorgb_color4(vec4 _in, out vec4 result)
{
    result = vec4(mx_hsvtorgb(_in.rgb), 1.0);
}
#include "lib/mx_noise.glsl"

void mx_worleynoise3d_vector2(vec3 position, float jitter, int style, out vec2 result)
{
    result = mx_worley_noise_vec2(position, jitter, style, 0);
}
#include "lib/$fileTransformUv"

#ifdef HW_SEPARATE_SAMPLERS
void mx_image_color4(texture2D tex_texture, sampler tex_sampler, int layer, vec4 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec4 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(sampler2D(tex_texture, tex_sampler), uv);
}
#else
void mx_image_color4(sampler2D tex_sampler, int layer, vec4 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec4 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(tex_sampler, uv);
}
#endif
#include "lib/mx_noise.glsl"

void mx_worleynoise2d_vector3(vec2 texcoord, float jitter, int style, out vec3 result)
{
    result = mx_worley_noise_vec3(texcoord, jitter, style, 0);
}
#include "lib/mx_noise.glsl"

void mx_noise3d_vector4(vec4 amplitude, float pivot, vec3 position, out vec4 result)
{
    vec3 xyz = mx_perlin_noise_vec3(position);
    float w = mx_perlin_noise_float(position + vec3(19, 73, 29));
    result = vec4(xyz, w) * amplitude + pivot;
}
#include "lib/$fileTransformUv"

#ifdef HW_SEPARATE_SAMPLERS
void mx_image_color3(texture2D tex_texture, sampler tex_sampler, int layer, vec3 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec3 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(sampler2D(tex_texture, tex_sampler), uv).rgb;
}
#else
void mx_image_color3(sampler2D tex_sampler, int layer, vec3 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec3 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(tex_sampler, uv).rgb;
}
#endif
void mx_burn_float(float fg, float bg, float mixval, out float result)
{
    if (abs(fg) < M_FLOAT_EPS)
    {
        result = 0.0;
        return;
    }
    result = mixval*(1.0 - ((1.0 - bg) / fg)) + ((1.0-mixval)*bg);
}
#include "lib/mx_noise.glsl"

void mx_cellnoise2d_float(vec2 texcoord, out float result)
{
    result = mx_cell_noise_float(texcoord);
}
#include "lib/mx_noise.glsl"

void mx_worleynoise3d_float(vec3 position, float jitter, int style, out float result)
{
    result = mx_worley_noise_float(position, jitter, style, 0);
}
#include "lib/$fileTransformUv"

#ifdef HW_SEPARATE_SAMPLERS
void mx_image_vector2(texture2D tex_texture, sampler tex_sampler, int layer, vec2 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec2 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(sampler2D(tex_texture, tex_sampler), uv).rg;
}
#else
void mx_image_vector2(sampler2D tex_sampler, int layer, vec2 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec2 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(tex_sampler, uv).rg;
}
#endif
#include "lib/$fileTransformUv"
#include "lib/mx_hextile.glsl"

// Morten S. Mikkelsen, Practical Real-Time Hex-Tiling, Journal of Computer Graphics
// Techniques (JCGT), vol. 11, no. 2, 77-94, 2022
// http://jcgt.org/published/0011/03/05/
void mx_hextiledimage_color3(
#ifdef HW_SEPARATE_SAMPLERS
    texture2D tex_texture,
    sampler   tex_sampler,
#else
    sampler2D tex_sampler,
#endif
    vec3 default_value,
    vec2 tex_coord,
    vec2 tiling,
    float rotation,
    vec2 rotation_range,
    float scale,
    vec2 scale_range,
    float offset,
    vec2 offset_range,
    float falloff,
    float falloff_contrast,
    vec3 lumacoeffs,
    out vec3 result
)
{
    vec2 coord = mx_transform_uv(tex_coord, tiling, vec2(0.0));

    HextileData tile_data = mx_hextile_coord(coord, rotation, rotation_range, scale, scale_range, offset, offset_range);

#ifdef HW_SEPARATE_SAMPLERS
    vec3 c1 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord1, tile_data.ddx1, tile_data.ddy1).rgb;
    vec3 c2 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord2, tile_data.ddx2, tile_data.ddy2).rgb;
    vec3 c3 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord3, tile_data.ddx3, tile_data.ddy3).rgb;
#else
    vec3 c1 = textureGrad(tex_sampler, tile_data.coord1, tile_data.ddx1, tile_data.ddy1).rgb;
    vec3 c2 = textureGrad(tex_sampler, tile_data.coord2, tile_data.ddx2, tile_data.ddy2).rgb;
    vec3 c3 = textureGrad(tex_sampler, tile_data.coord3, tile_data.ddx3, tile_data.ddy3).rgb;
#endif

    // luminance as weights
    vec3 cw = vec3(dot(c1, lumacoeffs), dot(c2, lumacoeffs), dot(c3, lumacoeffs));
    cw = mix(vec3(1.0), cw, vec3(falloff_contrast));

    // blend weights
    vec3 w = cw * pow(tile_data.weights, vec3(7.0));
    w /= (w.x + w.y + w.z);

    // apply s-curve gain
    if (falloff != 0.5)
    {
        w.x = mx_schlick_gain(w.x, falloff);
        w.y = mx_schlick_gain(w.y, falloff);
        w.z = mx_schlick_gain(w.z, falloff);
        w /= (w.x + w.y + w.z);
    }

    // blend
    result = vec3(w.x * c1 + w.y * c2 + w.z * c3);
}

void mx_hextiledimage_color4(
#ifdef HW_SEPARATE_SAMPLERS
    texture2D tex_texture,
    sampler   tex_sampler,
#else
    sampler2D tex_sampler,
#endif
    vec4 default_value,
    vec2 tex_coord,
    vec2 tiling,
    float rotation,
    vec2 rotation_range,
    float scale,
    vec2 scale_range,
    float offset,
    vec2 offset_range,
    float falloff,
    float falloff_contrast,
    vec3 lumacoeffs,
    out vec4 result
)
{
    vec2 coord = mx_transform_uv(tex_coord, tiling, vec2(0.0));

    HextileData tile_data = mx_hextile_coord(coord, rotation, rotation_range, scale, scale_range, offset, offset_range);

#ifdef HW_SEPARATE_SAMPLERS
    vec4 c1 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord1, tile_data.ddx1, tile_data.ddy1);
    vec4 c2 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord2, tile_data.ddx2, tile_data.ddy2);
    vec4 c3 = textureGrad(sampler2D(tex_texture, tex_sampler), tile_data.coord3, tile_data.ddx3, tile_data.ddy3);
#else
    vec4 c1 = textureGrad(tex_sampler, tile_data.coord1, tile_data.ddx1, tile_data.ddy1);
    vec4 c2 = textureGrad(tex_sampler, tile_data.coord2, tile_data.ddx2, tile_data.ddy2);
    vec4 c3 = textureGrad(tex_sampler, tile_data.coord3, tile_data.ddx3, tile_data.ddy3);
#endif

    // luminance as weights
    vec3 cw = vec3(dot(c1.rgb, lumacoeffs), dot(c2.rgb, lumacoeffs), dot(c3.rgb, lumacoeffs));
    cw = mix(vec3(1.0), cw, vec3(falloff_contrast));

    // blend weights
    vec3 w = cw * pow(tile_data.weights, vec3(7.0));
    w /= (w.x + w.y + w.z);

    // alpha
    float a = (c1.a + c2.a + c3.a) / 3.0;

    // apply s-curve gain
    if (falloff != 0.5)
    {
        w.x = mx_schlick_gain(w.x, falloff);
        w.y = mx_schlick_gain(w.y, falloff);
        w.z = mx_schlick_gain(w.z, falloff);
        w /= (w.x + w.y + w.z);
        a = mx_schlick_gain(a, falloff);
    }

    // blend
    result.rgb = vec3(w.x * c1 + w.y * c2 + w.z * c3);
    result.a = a;
}
#include "lib/mx_noise.glsl"

void mx_noise2d_float(float amplitude, float pivot, vec2 texcoord, out float result)
{
    float value = mx_perlin_noise_float(texcoord);
    result = value * amplitude + pivot;
}
#include "mx_dodge_float.glsl"

void mx_dodge_color4(vec4 fg , vec4 bg , float mixval, out vec4 result)
{
    float f;
    mx_dodge_float(fg.x, bg.x, mixval, f); result.x = f;
    mx_dodge_float(fg.y, bg.y, mixval, f); result.y = f;
    mx_dodge_float(fg.z, bg.z, mixval, f); result.z = f;
    mx_dodge_float(fg.w, bg.w, mixval, f); result.w = f;
}
void mx_ramptb_vector4(vec4 valuet, vec4 valueb, vec2 texcoord, out vec4 result)
{
    result = mix (valuet, valueb, clamp(texcoord.y, 0.0, 1.0) );
}
#include "mx_aastep.glsl"

void mx_splittb_vector2(vec2 valuet, vec2 valueb, float center, vec2 texcoord, out vec2 result)
{
    result = mix(valuet, valueb, mx_aastep(center, texcoord.y));
}
#include "mx_aastep.glsl"

void mx_splitlr_vector4(vec4 valuel, vec4 valuer, float center, vec2 texcoord, out vec4 result)
{
    result = mix(valuel, valuer, mx_aastep(center, texcoord.x));
}
void mx_ramptb_float(float valuet, float valueb, vec2 texcoord, out float result)
{
    result = mix (valuet, valueb, clamp(texcoord.y, 0.0, 1.0) );
}
#include "lib/mx_hsv.glsl"

void mx_hsvtorgb_color3(vec3 _in, out vec3 result)
{
    result = mx_hsvtorgb(_in);
}
void mx_transformmatrix_vector2M3(vec2 val, mat3 transform, out vec2 result)
{
  vec3 res = transform * vec3(val, 1.0);
  result = res.xy;
}
#include "mx_aastep.glsl"

void mx_splitlr_float(float valuel, float valuer, float center, vec2 texcoord, out float result)
{
    result = mix(valuel, valuer, mx_aastep(center, texcoord.x));
}
#include "lib/$fileTransformUv"

#ifdef HW_SEPARATE_SAMPLERS
void mx_image_vector4(texture2D tex_texture, sampler tex_sampler, int layer, vec4 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec4 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(sampler2D(tex_texture, tex_sampler), uv);
}
#else
void mx_image_vector4(sampler2D tex_sampler, int layer, vec4 defaultval, vec2 texcoord, int uaddressmode, int vaddressmode, int filtertype, int framerange, int frameoffset, int frameendaction, vec2 uv_scale, vec2 uv_offset, out vec4 result)
{
    vec2 uv = mx_transform_uv(texcoord, uv_scale, uv_offset);
    result = texture(tex_sampler, uv);
}
#endif
#include "lib/mx_noise.glsl"

void mx_fractal2d_vector3(vec3 amplitude, int octaves, float lacunarity, float diminish, vec2 texcoord, out vec3 result)
{
    vec3 value = mx_fractal2d_noise_vec3(texcoord, octaves, lacunarity, diminish);
    result = value * amplitude;
}
#include "lib/mx_noise.glsl"

void mx_worleynoise2d_float(vec2 texcoord, float jitter, int style, out float result)
{
    result = mx_worley_noise_float(texcoord, jitter, style, 0);
}
#include "lib/mx_noise.glsl"

void mx_fractal3d_vector2(vec2 amplitude, int octaves, float lacunarity, float diminish, vec3 position, out vec2 result)
{
    vec2 value = mx_fractal3d_noise_vec2(position, octaves, lacunarity, diminish);
    result = value * amplitude;
}
void mx_luminance_color4(vec4 _in, vec3 lumacoeffs, out vec4 result)
{
    result = vec4(vec3(dot(_in.rgb, lumacoeffs)), _in.a);
}
#include "lib/mx_hsv.glsl"

void mx_rgbtohsv_color4(vec4 _in, out vec4 result)
{
    result = vec4(mx_rgbtohsv(_in.rgb), 1.0);
}
void mx_unpremult_color4(vec4 _in, out vec4 result)
{
    result = vec4(_in.rgb / _in.a, _in.a);
}
#include "lib/mx_noise.glsl"

void mx_fractal3d_vector3(vec3 amplitude, int octaves, float lacunarity, float diminish, vec3 position, out vec3 result)
{
    vec3 value = mx_fractal3d_noise_vec3(position, octaves, lacunarity, diminish);
    result = value * amplitude;
}
float mx_aastep(float threshold, float value)
{
    float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
    return smoothstep(threshold-afwidth, threshold+afwidth, value);
}
#include "mx_aastep.glsl"

void mx_splittb_vector4(vec4 valuet, vec4 valueb, float center, vec2 texcoord, out vec4 result)
{
    result = mix(valuet, valueb, mx_aastep(center, texcoord.y));
}
#include "lib/mx_noise.glsl"

void mx_worleynoise2d_vector2(vec2 texcoord, float jitter, int style, out vec2 result)
{
    result = mx_worley_noise_vec2(texcoord, jitter, style, 0);
}
void mx_ramplr_float(float valuel, float valuer, vec2 texcoord, out float result)
{
    result = mix (valuel, valuer, clamp(texcoord.x, 0.0, 1.0) );
}
#include "lib/mx_noise.glsl"

void mx_fractal3d_float(float amplitude, int octaves, float lacunarity, float diminish, vec3 position, out float result)
{
    float value = mx_fractal3d_noise_float(position, octaves, lacunarity, diminish);
    result = value * amplitude;
}
void mx_ramplr_vector4(vec4 valuel, vec4 valuer, vec2 texcoord, out vec4 result)
{
    result = mix (valuel, valuer, clamp(texcoord.x, 0.0, 1.0) );
}
#include "mx_burn_float.glsl"

void mx_burn_color4(vec4 fg, vec4 bg, float mixval, out vec4 result)
{
    float f;
    mx_burn_float(fg.x, bg.x, mixval, f); result.x = f;
    mx_burn_float(fg.y, bg.y, mixval, f); result.y = f;
    mx_burn_float(fg.z, bg.z, mixval, f); result.z = f;
    mx_burn_float(fg.w, bg.w, mixval, f); result.w = f;
}
void mx_mix_surfaceshader(surfaceshader fg, surfaceshader bg, float w, out surfaceshader returnshader)
{
    returnshader.color = mix(bg.color, fg.color, w);
    returnshader.transparency = mix(bg.transparency, fg.transparency, w);
}
#include "mx_dodge_float.glsl"

void mx_dodge_color3(vec3 fg, vec3 bg, float mixval, out vec3 result)
{
    float f;
    mx_dodge_float(fg.x, bg.x, mixval, f); result.x = f;
    mx_dodge_float(fg.y, bg.y, mixval, f); result.y = f;
    mx_dodge_float(fg.z, bg.z, mixval, f); result.z = f;
}
void mx_heighttonormal_vector3(float height, float scale, vec2 texcoord, out vec3 result)
{
    // Scale factor for parity with traditional Sobel filtering.
    const float SOBEL_SCALE_FACTOR = 1.0 / 16.0;

    // Compute screen-space gradients of the heightfield and texture coordinates.
    vec2 dHdS = vec2(dFdx(height), dFdy(height)) * scale * SOBEL_SCALE_FACTOR;
    vec2 dUdS = vec2(dFdx(texcoord.x), dFdy(texcoord.x));
    vec2 dVdS = vec2(dFdx(texcoord.y), dFdy(texcoord.y));

    // Construct a screen-space tangent frame.
    vec3 tangent = vec3(dUdS.x, dVdS.x, dHdS.x);
    vec3 bitangent = vec3(dUdS.y, dVdS.y, dHdS.y);
    vec3 n = cross(tangent, bitangent);

    // Handle invalid and mirrored texture coordinates.
    if (dot(n, n) < M_FLOAT_EPS * M_FLOAT_EPS)
    {
        n = vec3(0, 0, 1);
    }
    else if (n.z < 0.0)
    {
        n *= -1.0;
    }

    // Normalize and encode the results.
    result = normalize(n) * 0.5 + 0.5;
}
#include "lib/mx_noise.glsl"

void mx_fractal2d_float(float amplitude, int octaves, float lacunarity, float diminish, vec2 texcoord, out float result)
{
    float value = mx_fractal2d_noise_float(texcoord, octaves, lacunarity, diminish);
    result = value * amplitude;
}
#include "lib/mx_noise.glsl"

void mx_worleynoise3d_vector3(vec3 position, float jitter, int style, out vec3 result)
{
    result = mx_worley_noise_vec3(position, jitter, style, 0);
}
void mx_creatematrix_vector3_matrix44(vec3 in1, vec3 in2, vec3 in3, vec3 in4, out mat4 result)
{
    result = mat4(in1.x, in1.y, in1.z, 0.0,
                  in2.x, in2.y, in2.z, 0.0,
                  in3.x, in3.y, in3.z, 0.0,
                  in4.x, in4.y, in4.z, 1.0);
}
#include "lib/mx_noise.glsl"

void mx_noise2d_vector4(vec4 amplitude, float pivot, vec2 texcoord, out vec4 result)
{
    vec3 xyz = mx_perlin_noise_vec3(texcoord);
    float w = mx_perlin_noise_float(texcoord + vec2(19, 73));
    result = vec4(xyz, w) * amplitude + pivot;
}
void mx_rotate_vector2(vec2 _in, float amount, out vec2 result)
{
    float rotationRadians = mx_radians(amount);
    float sa = mx_sin(rotationRadians);
    float ca = mx_cos(rotationRadians);
    result = vec2(ca*_in.x + sa*_in.y, -sa*_in.x + ca*_in.y);
}

void mx_surface_unlit(float emission, vec3 emission_color, float transmission, vec3 transmission_color, float opacity, out surfaceshader result)
{
    result.color = emission * emission_color * opacity;
    result.transparency = mix(vec3(1.0), transmission * transmission_color, opacity);
}
// Restrict to 7x7 kernel size for performance reasons
#define MX_MAX_SAMPLE_COUNT 49
// Size of all weights for all levels (including level 1)
#define MX_WEIGHT_ARRAY_SIZE 84

//
// Function to compute the sample size relative to a texture coordinate
//
vec2 mx_compute_sample_size_uv(vec2 uv, float filterSize, float filterOffset)
{
   vec2 derivUVx = dFdx(uv) * 0.5f;
   vec2 derivUVy = dFdy(uv) * 0.5f;
   float derivX = abs(derivUVx.x) + abs(derivUVy.x);
   float derivY = abs(derivUVx.y) + abs(derivUVy.y);
   float sampleSizeU = 2.0f * filterSize * derivX + filterOffset;
   if (sampleSizeU < 1.0E-05f)
       sampleSizeU = 1.0E-05f;
   float sampleSizeV = 2.0f * filterSize * derivY + filterOffset;
   if (sampleSizeV < 1.0E-05f)
       sampleSizeV = 1.0E-05f;
   return vec2(sampleSizeU, sampleSizeV);
}

//
// Apply filter for float samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
float mx_convolution_float(float S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    float result = 0.0;
    for (int i = 0;  i < sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vec2 samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vec2 mx_convolution_vec2(vec2 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vec2 result = vec2(0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vec3 samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vec3 mx_convolution_vec3(vec3 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vec3 result = vec3(0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vec4 samples S, using weights W.
// sampleCount should be a square of a odd number { 1, 3, 5, 7 }
//
vec4 mx_convolution_vec4(vec4 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vec4 result = vec4(0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}
vec2 mx_transform_uv(vec2 uv, vec2 uv_scale, vec2 uv_offset)
{
    uv = uv * uv_scale + uv_offset;
    return vec2(uv.x, 1.0 - uv.y);
}
#define M_FLOAT_EPS 1e-8

#define mx_mod mod
#define mx_inverse inverse
#define mx_inversesqrt inversesqrt
#define mx_sin sin
#define mx_cos cos
#define mx_tan tan
#define mx_asin asin
#define mx_acos acos
#define mx_atan atan
#define mx_radians radians

float mx_square(float x)
{
    return x*x;
}

vec2 mx_square(vec2 x)
{
    return x*x;
}

vec3 mx_square(vec3 x)
{
    return x*x;
}

vec3 mx_srgb_encode(vec3 color)
{
    bvec3 isAbove = greaterThan(color, vec3(0.0031308));
    vec3 linSeg = color * 12.92;
    vec3 powSeg = 1.055 * pow(max(color, vec3(0.0)), vec3(1.0 / 2.4)) - 0.055;
    return mix(linSeg, powSeg, isAbove);
}
/*
Noise Library.

This library is a modified version of the noise library found in
Open Shading Language:
github.com/imageworks/OpenShadingLanguage/blob/master/src/include/OSL/oslnoise.h

It contains the subset of noise types needed to implement the MaterialX
standard library. The modifications are mainly conversions from C++ to GLSL.
Produced results should be identical to the OSL noise functions.

Original copyright notice:
------------------------------------------------------------------------
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.
* Neither the name of Sony Pictures Imageworks nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------
*/

float mx_select(bool b, float t, float f)
{
    return b ? t : f;
}

float mx_negate_if(float val, bool b)
{
    return b ? -val : val;
}

int mx_floor(float x)
{
    return int(floor(x));
}

// return mx_floor as well as the fractional remainder
float mx_floorfrac(float x, out int i)
{
    i = mx_floor(x);
    return x - float(i);
}

float mx_bilerp(float v0, float v1, float v2, float v3, float s, float t)
{
    float s1 = 1.0 - s;
    return (1.0 - t) * (v0*s1 + v1*s) + t * (v2*s1 + v3*s);
}
vec3 mx_bilerp(vec3 v0, vec3 v1, vec3 v2, vec3 v3, float s, float t)
{
    float s1 = 1.0 - s;
    return (1.0 - t) * (v0*s1 + v1*s) + t * (v2*s1 + v3*s);
}
float mx_trilerp(float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float s, float t, float r)
{
    float s1 = 1.0 - s;
    float t1 = 1.0 - t;
    float r1 = 1.0 - r;
    return (r1*(t1*(v0*s1 + v1*s) + t*(v2*s1 + v3*s)) +
            r*(t1*(v4*s1 + v5*s) + t*(v6*s1 + v7*s)));
}
vec3 mx_trilerp(vec3 v0, vec3 v1, vec3 v2, vec3 v3, vec3 v4, vec3 v5, vec3 v6, vec3 v7, float s, float t, float r)
{
    float s1 = 1.0 - s;
    float t1 = 1.0 - t;
    float r1 = 1.0 - r;
    return (r1*(t1*(v0*s1 + v1*s) + t*(v2*s1 + v3*s)) +
            r*(t1*(v4*s1 + v5*s) + t*(v6*s1 + v7*s)));
}

// 2 and 3 dimensional gradient functions - perform a dot product against a
// randomly chosen vector. Note that the gradient vector is not normalized, but
// this only affects the overall "scale" of the result, so we simply account for
// the scale by multiplying in the corresponding "perlin" function.
float mx_gradient_float(uint hash, float x, float y)
{
    // 8 possible directions (+-1,+-2) and (+-2,+-1)
    uint h = hash & 7u;
    float u = mx_select(h<4u, x, y);
    float v = 2.0 * mx_select(h<4u, y, x);
    // compute the dot product with (x,y).
    return mx_negate_if(u, bool(h&1u)) + mx_negate_if(v, bool(h&2u));
}
float mx_gradient_float(uint hash, float x, float y, float z)
{
    // use vectors pointing to the edges of the cube
    uint h = hash & 15u;
    float u = mx_select(h<8u, x, y);
    float v = mx_select(h<4u, y, mx_select((h==12u)||(h==14u), x, z));
    return mx_negate_if(u, bool(h&1u)) + mx_negate_if(v, bool(h&2u));
}
vec3 mx_gradient_vec3(uvec3 hash, float x, float y)
{
    return vec3(mx_gradient_float(hash.x, x, y), mx_gradient_float(hash.y, x, y), mx_gradient_float(hash.z, x, y));
}
vec3 mx_gradient_vec3(uvec3 hash, float x, float y, float z)
{
    return vec3(mx_gradient_float(hash.x, x, y, z), mx_gradient_float(hash.y, x, y, z), mx_gradient_float(hash.z, x, y, z));
}
// Scaling factors to normalize the result of gradients above.
// These factors were experimentally calculated to be:
//    2D:   0.6616
//    3D:   0.9820
float mx_gradient_scale2d(float v) { return 0.6616 * v; }
float mx_gradient_scale3d(float v) { return 0.9820 * v; }
vec3 mx_gradient_scale2d(vec3 v) { return 0.6616 * v; }
vec3 mx_gradient_scale3d(vec3 v) { return 0.9820 * v; }

/// Bitwise circular rotation left by k bits (for 32 bit unsigned integers)
uint mx_rotl32(uint x, int k)
{
    return (x<<k) | (x>>(32-k));
}

void mx_bjmix(inout uint a, inout uint b, inout uint c)
{
    a -= c; a ^= mx_rotl32(c, 4); c += b;
    b -= a; b ^= mx_rotl32(a, 6); a += c;
    c -= b; c ^= mx_rotl32(b, 8); b += a;
    a -= c; a ^= mx_rotl32(c,16); c += b;
    b -= a; b ^= mx_rotl32(a,19); a += c;
    c -= b; c ^= mx_rotl32(b, 4); b += a;
}

// Mix up and combine the bits of a, b, and c (doesn't change them, but
// returns a hash of those three original values).
uint mx_bjfinal(uint a, uint b, uint c)
{
    c ^= b; c -= mx_rotl32(b,14);
    a ^= c; a -= mx_rotl32(c,11);
    b ^= a; b -= mx_rotl32(a,25);
    c ^= b; c -= mx_rotl32(b,16);
    a ^= c; a -= mx_rotl32(c,4);
    b ^= a; b -= mx_rotl32(a,14);
    c ^= b; c -= mx_rotl32(b,24);
    return c;
}

// Convert a 32 bit integer into a floating point number in [0,1]
float mx_bits_to_01(uint bits)
{
    return float(bits) / float(uint(0xffffffff));
}

float mx_fade(float t)
{
   return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
}

uint mx_hash_int(int x)
{
    uint len = 1u;
    uint seed = uint(0xdeadbeef) + (len << 2u) + 13u;
    return mx_bjfinal(seed+uint(x), seed, seed);
}

uint mx_hash_int(int x, int y)
{
    uint len = 2u;
    uint a, b, c;
    a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u;
    a += uint(x);
    b += uint(y);
    return mx_bjfinal(a, b, c);
}

uint mx_hash_int(int x, int y, int z)
{
    uint len = 3u;
    uint a, b, c;
    a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u;
    a += uint(x);
    b += uint(y);
    c += uint(z);
    return mx_bjfinal(a, b, c);
}

uint mx_hash_int(int x, int y, int z, int xx)
{
    uint len = 4u;
    uint a, b, c;
    a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u;
    a += uint(x);
    b += uint(y);
    c += uint(z);
    mx_bjmix(a, b, c);
    a += uint(xx);
    return mx_bjfinal(a, b, c);
}

uint mx_hash_int(int x, int y, int z, int xx, int yy)
{
    uint len = 5u;
    uint a, b, c;
    a = b = c = uint(0xdeadbeef) + (len << 2u) + 13u;
    a += uint(x);
    b += uint(y);
    c += uint(z);
    mx_bjmix(a, b, c);
    a += uint(xx);
    b += uint(yy);
    return mx_bjfinal(a, b, c);
}

uvec3 mx_hash_vec3(int x, int y)
{
    uint h = mx_hash_int(x, y);
    // we only need the low-order bits to be random, so split out
    // the 32 bit result into 3 parts for each channel
    uvec3 result;
    result.x = (h      ) & 0xFFu;
    result.y = (h >> 8 ) & 0xFFu;
    result.z = (h >> 16) & 0xFFu;
    return result;
}

uvec3 mx_hash_vec3(int x, int y, int z)
{
    uint h = mx_hash_int(x, y, z);
    // we only need the low-order bits to be random, so split out
    // the 32 bit result into 3 parts for each channel
    uvec3 result;
    result.x = (h      ) & 0xFFu;
    result.y = (h >> 8 ) & 0xFFu;
    result.z = (h >> 16) & 0xFFu;
    return result;
}

float mx_perlin_noise_float(vec2 p)
{
    int X, Y;
    float fx = mx_floorfrac(p.x, X);
    float fy = mx_floorfrac(p.y, Y);
    float u = mx_fade(fx);
    float v = mx_fade(fy);
    float result = mx_bilerp(
        mx_gradient_float(mx_hash_int(X  , Y  ), fx    , fy     ),
        mx_gradient_float(mx_hash_int(X+1, Y  ), fx-1.0, fy     ),
        mx_gradient_float(mx_hash_int(X  , Y+1), fx    , fy-1.0),
        mx_gradient_float(mx_hash_int(X+1, Y+1), fx-1.0, fy-1.0),
        u, v);
    return mx_gradient_scale2d(result);
}

float mx_perlin_noise_float(vec3 p)
{
    int X, Y, Z;
    float fx = mx_floorfrac(p.x, X);
    float fy = mx_floorfrac(p.y, Y);
    float fz = mx_floorfrac(p.z, Z);
    float u = mx_fade(fx);
    float v = mx_fade(fy);
    float w = mx_fade(fz);
    float result = mx_trilerp(
        mx_gradient_float(mx_hash_int(X  , Y  , Z  ), fx    , fy    , fz     ),
        mx_gradient_float(mx_hash_int(X+1, Y  , Z  ), fx-1.0, fy    , fz     ),
        mx_gradient_float(mx_hash_int(X  , Y+1, Z  ), fx    , fy-1.0, fz     ),
        mx_gradient_float(mx_hash_int(X+1, Y+1, Z  ), fx-1.0, fy-1.0, fz     ),
        mx_gradient_float(mx_hash_int(X  , Y  , Z+1), fx    , fy    , fz-1.0),
        mx_gradient_float(mx_hash_int(X+1, Y  , Z+1), fx-1.0, fy    , fz-1.0),
        mx_gradient_float(mx_hash_int(X  , Y+1, Z+1), fx    , fy-1.0, fz-1.0),
        mx_gradient_float(mx_hash_int(X+1, Y+1, Z+1), fx-1.0, fy-1.0, fz-1.0),
        u, v, w);
    return mx_gradient_scale3d(result);
}

vec3 mx_perlin_noise_vec3(vec2 p)
{
    int X, Y;
    float fx = mx_floorfrac(p.x, X);
    float fy = mx_floorfrac(p.y, Y);
    float u = mx_fade(fx);
    float v = mx_fade(fy);
    vec3 result = mx_bilerp(
        mx_gradient_vec3(mx_hash_vec3(X  , Y  ), fx    , fy     ),
        mx_gradient_vec3(mx_hash_vec3(X+1, Y  ), fx-1.0, fy     ),
        mx_gradient_vec3(mx_hash_vec3(X  , Y+1), fx    , fy-1.0),
        mx_gradient_vec3(mx_hash_vec3(X+1, Y+1), fx-1.0, fy-1.0),
        u, v);
    return mx_gradient_scale2d(result);
}

vec3 mx_perlin_noise_vec3(vec3 p)
{
    int X, Y, Z;
    float fx = mx_floorfrac(p.x, X);
    float fy = mx_floorfrac(p.y, Y);
    float fz = mx_floorfrac(p.z, Z);
    float u = mx_fade(fx);
    float v = mx_fade(fy);
    float w = mx_fade(fz);
    vec3 result = mx_trilerp(
        mx_gradient_vec3(mx_hash_vec3(X  , Y  , Z  ), fx    , fy    , fz     ),
        mx_gradient_vec3(mx_hash_vec3(X+1, Y  , Z  ), fx-1.0, fy    , fz     ),
        mx_gradient_vec3(mx_hash_vec3(X  , Y+1, Z  ), fx    , fy-1.0, fz     ),
        mx_gradient_vec3(mx_hash_vec3(X+1, Y+1, Z  ), fx-1.0, fy-1.0, fz     ),
        mx_gradient_vec3(mx_hash_vec3(X  , Y  , Z+1), fx    , fy    , fz-1.0),
        mx_gradient_vec3(mx_hash_vec3(X+1, Y  , Z+1), fx-1.0, fy    , fz-1.0),
        mx_gradient_vec3(mx_hash_vec3(X  , Y+1, Z+1), fx    , fy-1.0, fz-1.0),
        mx_gradient_vec3(mx_hash_vec3(X+1, Y+1, Z+1), fx-1.0, fy-1.0, fz-1.0),
        u, v, w);
    return mx_gradient_scale3d(result);
}

float mx_cell_noise_float(float p)
{
    int ix = mx_floor(p);
    return mx_bits_to_01(mx_hash_int(ix));
}

float mx_cell_noise_float(vec2 p)
{
    int ix = mx_floor(p.x);
    int iy = mx_floor(p.y);
    return mx_bits_to_01(mx_hash_int(ix, iy));
}

float mx_cell_noise_float(vec3 p)
{
    int ix = mx_floor(p.x);
    int iy = mx_floor(p.y);
    int iz = mx_floor(p.z);
    return mx_bits_to_01(mx_hash_int(ix, iy, iz));
}

float mx_cell_noise_float(vec4 p)
{
    int ix = mx_floor(p.x);
    int iy = mx_floor(p.y);
    int iz = mx_floor(p.z);
    int iw = mx_floor(p.w);
    return mx_bits_to_01(mx_hash_int(ix, iy, iz, iw));
}

vec3 mx_cell_noise_vec3(float p)
{
    int ix = mx_floor(p);
    return vec3(
            mx_bits_to_01(mx_hash_int(ix, 0)),
            mx_bits_to_01(mx_hash_int(ix, 1)),
            mx_bits_to_01(mx_hash_int(ix, 2))
    );
}

vec3 mx_cell_noise_vec3(vec2 p)
{
    int ix = mx_floor(p.x);
    int iy = mx_floor(p.y);
    return vec3(
            mx_bits_to_01(mx_hash_int(ix, iy, 0)),
            mx_bits_to_01(mx_hash_int(ix, iy, 1)),
            mx_bits_to_01(mx_hash_int(ix, iy, 2))
    );
}

vec3 mx_cell_noise_vec3(vec3 p)
{
    int ix = mx_floor(p.x);
    int iy = mx_floor(p.y);
    int iz = mx_floor(p.z);
    return vec3(
            mx_bits_to_01(mx_hash_int(ix, iy, iz, 0)),
            mx_bits_to_01(mx_hash_int(ix, iy, iz, 1)),
            mx_bits_to_01(mx_hash_int(ix, iy, iz, 2))
    );
}

vec3 mx_cell_noise_vec3(vec4 p)
{
    int ix = mx_floor(p.x);
    int iy = mx_floor(p.y);
    int iz = mx_floor(p.z);
    int iw = mx_floor(p.w);
    return vec3(
            mx_bits_to_01(mx_hash_int(ix, iy, iz, iw, 0)),
            mx_bits_to_01(mx_hash_int(ix, iy, iz, iw, 1)),
            mx_bits_to_01(mx_hash_int(ix, iy, iz, iw, 2))
    );
}

float mx_fractal2d_noise_float(vec2 p, int octaves, float lacunarity, float diminish)
{
    float result = 0.0;
    float amplitude = 1.0;
    for (int i = 0;  i < octaves; ++i)
    {
        result += amplitude * mx_perlin_noise_float(p);
        amplitude *= diminish;
        p *= lacunarity;
    }
    return result;
}

vec3 mx_fractal2d_noise_vec3(vec2 p, int octaves, float lacunarity, float diminish)
{
    vec3 result = vec3(0.0);
    float amplitude = 1.0;
    for (int i = 0;  i < octaves; ++i)
    {
        result += amplitude * mx_perlin_noise_vec3(p);
        amplitude *= diminish;
        p *= lacunarity;
    }
    return result;
}

vec2 mx_fractal2d_noise_vec2(vec2 p, int octaves, float lacunarity, float diminish)
{
    return vec2(mx_fractal2d_noise_float(p, octaves, lacunarity, diminish),
                mx_fractal2d_noise_float(p+vec2(19, 193), octaves, lacunarity, diminish));
}

vec4 mx_fractal2d_noise_vec4(vec2 p, int octaves, float lacunarity, float diminish)
{
    vec3  c = mx_fractal2d_noise_vec3(p, octaves, lacunarity, diminish);
    float f = mx_fractal2d_noise_float(p+vec2(19, 193), octaves, lacunarity, diminish);
    return vec4(c, f);
}

float mx_fractal3d_noise_float(vec3 p, int octaves, float lacunarity, float diminish)
{
    float result = 0.0;
    float amplitude = 1.0;
    for (int i = 0;  i < octaves; ++i)
    {
        result += amplitude * mx_perlin_noise_float(p);
        amplitude *= diminish;
        p *= lacunarity;
    }
    return result;
}

vec3 mx_fractal3d_noise_vec3(vec3 p, int octaves, float lacunarity, float diminish)
{
    vec3 result = vec3(0.0);
    float amplitude = 1.0;
    for (int i = 0;  i < octaves; ++i)
    {
        result += amplitude * mx_perlin_noise_vec3(p);
        amplitude *= diminish;
        p *= lacunarity;
    }
    return result;
}

vec2 mx_fractal3d_noise_vec2(vec3 p, int octaves, float lacunarity, float diminish)
{
    return vec2(mx_fractal3d_noise_float(p, octaves, lacunarity, diminish),
                mx_fractal3d_noise_float(p+vec3(19, 193, 17), octaves, lacunarity, diminish));
}

vec4 mx_fractal3d_noise_vec4(vec3 p, int octaves, float lacunarity, float diminish)
{
    vec3  c = mx_fractal3d_noise_vec3(p, octaves, lacunarity, diminish);
    float f = mx_fractal3d_noise_float(p+vec3(19, 193, 17), octaves, lacunarity, diminish);
    return vec4(c, f);
}

vec2 mx_worley_cell_position(int x, int y, int xoff, int yoff, float jitter)
{
    vec3  tmp = mx_cell_noise_vec3(vec2(x+xoff, y+yoff));
    vec2  off = vec2(tmp.x, tmp.y);

    off -= 0.5f;
    off *= jitter;
    off += 0.5f;
    
    return vec2(float(x), float(y)) + off;
}

vec3 mx_worley_cell_position(int x, int y, int z, int xoff, int yoff, int zoff, float jitter)
{
    vec3  off = mx_cell_noise_vec3(vec3(x+xoff, y+yoff, z+zoff));

    off -= 0.5f;
    off *= jitter;
    off += 0.5f;
    
    return vec3(float(x), float(y), float(z)) + off;
}

float mx_worley_distance(vec2 p, int x, int y, int xoff, int yoff, float jitter, int metric)
{
    vec2 cellpos = mx_worley_cell_position(x, y, xoff, yoff, jitter);
    vec2 diff = cellpos - p;
    if (metric == 2)
        return abs(diff.x) + abs(diff.y);       // Manhattan distance
    if (metric == 3)
        return max(abs(diff.x), abs(diff.y));   // Chebyshev distance
    // Either Euclidean or Distance^2
    return dot(diff, diff);
}

float mx_worley_distance(vec3 p, int x, int y, int z, int xoff, int yoff, int zoff, float jitter, int metric)
{
    vec3 cellpos = mx_worley_cell_position(x, y, z, xoff, yoff, zoff, jitter);
    vec3 diff = cellpos - p;
    if (metric == 2)
        return abs(diff.x) + abs(diff.y) + abs(diff.z); // Manhattan distance
    if (metric == 3)
        return max(max(abs(diff.x), abs(diff.y)), abs(diff.z)); // Chebyshev distance
    // Either Euclidean or Distance^2
    return dot(diff, diff);
}

float mx_worley_noise_float(vec2 p, float jitter, int style, int metric)
{
    int X, Y;
    float dist;
    vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y));
    float sqdist = 1e6f;        // Some big number for jitter > 1 (not all GPUs may be IEEE)
    vec2 minpos = vec2(0,0);
    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric);
            vec2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos;
            if(dist < sqdist)
            {
                sqdist = dist;
                minpos = cellpos;
            }
        }
    }
    if (style == 1)
        return mx_cell_noise_float(minpos + p);
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

vec2 mx_worley_noise_vec2(vec2 p, float jitter, int style, int metric)
{
    int X, Y;
    vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y));
    vec2 sqdist = vec2(1e6f, 1e6f);
    vec2 minpos = vec2(0,0);
    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric);
            vec2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos;
            if (dist < sqdist.x)
            {
                sqdist.y = sqdist.x;
                sqdist.x = dist;
                minpos = cellpos;
            }
            else if (dist < sqdist.y)
            {
                sqdist.y = dist;
            }
        }
    }
    if (style == 1)
    {
        vec3 tmp = mx_cell_noise_vec3(minpos + p);
        return vec2(tmp.x,tmp.y);
    }
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

vec3 mx_worley_noise_vec3(vec2 p, float jitter, int style, int metric)
{
    int X, Y;
    vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y));
    vec3 sqdist = vec3(1e6f, 1e6f, 1e6f);
    vec2 minpos = vec2(0,0);
    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric);
            vec2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos;
            if (dist < sqdist.x)
            {
                sqdist.z = sqdist.y;
                sqdist.y = sqdist.x;
                sqdist.x = dist;
                minpos = cellpos;
            }
            else if (dist < sqdist.y)
            {
                sqdist.z = sqdist.y;
                sqdist.y = dist;
            }
            else if (dist < sqdist.z)
            {
                sqdist.z = dist;
            }
        }
    }
    if (style == 1)
        return mx_cell_noise_vec3(minpos + p);
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

float mx_worley_noise_float(vec3 p, float jitter, int style, int metric)
{
    int X, Y, Z;
    vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z));
    float sqdist = 1e6f;
    vec3 minpos = vec3(0,0,0);
    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            for (int z = -1; z <= 1; ++z)
            {
                float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric);
                vec3 cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos;
                if(dist < sqdist)
                {
                    sqdist = dist;
                    minpos = cellpos;
                }
            }
        }
    }
    if (style == 1)
        return mx_cell_noise_float(minpos + p);
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

vec2 mx_worley_noise_vec2(vec3 p, float jitter, int style, int metric)
{
    int X, Y, Z;
    vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z));
    vec2 sqdist = vec2(1e6f, 1e6f);
    vec3 minpos = vec3(0,0,0);
    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            for (int z = -1; z <= 1; ++z)
            {
                float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric);
                vec3 cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos;
                if (dist < sqdist.x)
                {
                    sqdist.y = sqdist.x;
                    sqdist.x = dist;
                    minpos = cellpos;
                }
                else if (dist < sqdist.y)
                {
                    sqdist.y = dist;
                }
            }
        }
    }
    if (style == 1)
    {
        vec3 tmp = mx_cell_noise_vec3(minpos + p);
        return vec2(tmp.x,tmp.y);
    }
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

vec3 mx_worley_noise_vec3(vec3 p, float jitter, int style, int metric)
{
    int X, Y, Z;
    vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z));
    vec3 sqdist = vec3(1e6f, 1e6f, 1e6f);
    vec3 minpos = vec3(0,0,0);
    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            for (int z = -1; z <= 1; ++z)
            {
                float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric);
                vec3 cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos;
                if (dist < sqdist.x)
                {
                    sqdist.z = sqdist.y;
                    sqdist.y = sqdist.x;
                    sqdist.x = dist;
                    minpos = cellpos;
                }
                else if (dist < sqdist.y)
                {
                    sqdist.z = sqdist.y;
                    sqdist.y = dist;
                }
                else if (dist < sqdist.z)
                {
                    sqdist.z = dist;
                }
            }
        }
    }
    if (style == 1)
        return mx_cell_noise_vec3(minpos + p);
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}
vec2 mx_transform_uv(vec2 uv, vec2 uv_scale, vec2 uv_offset)
{
    uv = uv * uv_scale + uv_offset;
    return uv;
}
// https://www.shadertoy.com/view/4djSRW
vec2 mx_hextile_hash(vec2 p)
{
    vec3 p3 = fract(vec3(p.x, p.y, p.x) * vec3(0.1031, 0.1030, 0.0973));
    p3 += dot(p3, vec3(p3.y, p3.z, p3.x) + 33.33);
    return fract((vec2(p3.x, p3.x) + vec2(p3.y, p3.z)) * vec2(p3.z, p3.y));
}

// Christophe Schlick. “Fast Alternatives to Perlin’s Bias and Gain Functions”.
// In Graphics Gems IV, Morgan Kaufmann, 1994, pages 401–403.
// https://dept-info.labri.fr/~schlick/DOC/gem2.html
float mx_schlick_gain(float x, float r)
{
    float rr = clamp(r, 0.001, 0.999);  // to avoid glitch
    float a = (1.0 / rr - 2.0) * (1.0 - 2.0 * x);
    return (x < 0.5) ? x / (a + 1.0) : (a - x) / (a - 1.0);
}

struct HextileData
{
    vec2 coord1;
    vec2 coord2;
    vec2 coord3;
    vec3 weights;
    float rot_radian1;
    float rot_radian2;
    float rot_radian3;
    vec2 ddx1;
    vec2 ddx2;
    vec2 ddx3;
    vec2 ddy1;
    vec2 ddy2;
    vec2 ddy3;
};

// Morten S. Mikkelsen, Practical Real-Time Hex-Tiling, Journal of Computer Graphics
// Techniques (JCGT), vol. 11, no. 2, 77-94, 2022
// http://jcgt.org/published/0011/03/05/
HextileData mx_hextile_coord(
    vec2 coord,
    float rotation,
    vec2 rotation_range,
    float scale,
    vec2 scale_range,
    float offset,
    vec2 offset_range)
{
    float sqrt3_2 = sqrt(3.0) * 2.0;

    // scale coord to maintain the original fit
    vec2 st = coord * sqrt3_2;

    // skew input space into simplex triangle grid
    // (1, 0, -tan(30), 2*tan(30))
    mat2 to_skewed = mat2(1.0, 0.0, -0.57735027, 1.15470054);
    vec2 st_skewed = to_skewed * st;

    // barycentric weights
    vec2 st_frac = fract(st_skewed);
    vec3 temp = vec3(st_frac.x, st_frac.y, 0.0);
    temp.z = 1.0 - temp.x - temp.y;

    float s = step(0.0, -temp.z);
    float s2 = 2.0 * s - 1.0;

    float w1 = -temp.z * s2;
    float w2 = s - temp.y * s2;
    float w3 = s - temp.x * s2;

    // vertex IDs
    ivec2 base_id = ivec2(floor(st_skewed));
    int si = int(s);
    ivec2 id1 = base_id + ivec2(si, si);
    ivec2 id2 = base_id + ivec2(si, 1 - si);
    ivec2 id3 = base_id + ivec2(1 - si, si);

    // tile center
    mat2 inv_skewed = mat2(1.0, 0.0, 0.5, 1.0 / 1.15470054);
    vec2 ctr1 = inv_skewed * vec2(id1) / vec2(sqrt3_2);
    vec2 ctr2 = inv_skewed * vec2(id2) / vec2(sqrt3_2);
    vec2 ctr3 = inv_skewed * vec2(id3) / vec2(sqrt3_2);

    // reuse hash for performance
    vec2 seed_offset = vec2(0.12345);  // to avoid some zeros
    vec2 rand1 = mx_hextile_hash(vec2(id1) + seed_offset);
    vec2 rand2 = mx_hextile_hash(vec2(id2) + seed_offset);
    vec2 rand3 = mx_hextile_hash(vec2(id3) + seed_offset);

    // randomized rotation matrix
    vec2 rr = mx_radians(rotation_range);
    float rv1 = mix(rr.x, rr.y, rand1.x * rotation);
    float rv2 = mix(rr.x, rr.y, rand2.x * rotation);
    float rv3 = mix(rr.x, rr.y, rand3.x * rotation);
    float sin_r1 = sin(rv1);
    float sin_r2 = sin(rv2);
    float sin_r3 = sin(rv3);
    float cos_r1 = cos(rv1);
    float cos_r2 = cos(rv2);
    float cos_r3 = cos(rv3);
    mat2 rm1 = mat2(cos_r1, -sin_r1, sin_r1, cos_r1);
    mat2 rm2 = mat2(cos_r2, -sin_r2, sin_r2, cos_r2);
    mat2 rm3 = mat2(cos_r3, -sin_r3, sin_r3, cos_r3);

    // randomized scale
    vec2 sr = scale_range;
    vec2 scale1 = vec2(mix(1.0, mix(sr.x, sr.y, rand1.y), scale));
    vec2 scale2 = vec2(mix(1.0, mix(sr.x, sr.y, rand2.y), scale));
    vec2 scale3 = vec2(mix(1.0, mix(sr.x, sr.y, rand3.y), scale));

    // randomized offset
    vec2 offset1 = mix(vec2(offset_range.x), vec2(offset_range.y), rand1 * offset);
    vec2 offset2 = mix(vec2(offset_range.x), vec2(offset_range.y), rand2 * offset);
    vec2 offset3 = mix(vec2(offset_range.x), vec2(offset_range.y), rand3 * offset);

    HextileData tile_data;
    tile_data.weights = vec3(w1, w2, w3);
    tile_data.rot_radian1 = rv1;
    tile_data.rot_radian2 = rv2;
    tile_data.rot_radian3 = rv3;

    // get coord
    tile_data.coord1 = ((coord - ctr1) * rm1 / scale1) + ctr1 + offset1;
    tile_data.coord2 = ((coord - ctr2) * rm2 / scale2) + ctr2 + offset2;
    tile_data.coord3 = ((coord - ctr3) * rm3 / scale3) + ctr3 + offset3;

    // derivatives
    vec2 ddx = dFdx(coord);
    vec2 ddy = dFdy(coord);
    tile_data.ddx1 = ddx * rm1 / scale1;
    tile_data.ddx2 = ddx * rm2 / scale2;
    tile_data.ddx3 = ddx * rm3 / scale3;
    tile_data.ddy1 = ddy * rm1 / scale1;
    tile_data.ddy2 = ddy * rm2 / scale2;
    tile_data.ddy3 = ddy * rm3 / scale3;

    return tile_data;
}
// Blend 3 normals by blending the gradients
// Morten S. Mikkelsen, Surface Gradient–Based Bump Mapping Framework, Journal of
// Computer Graphics Techniques (JCGT), vol. 9, no. 3, 60–90, 2020
// http://jcgt.org/published/0009/03/04/
vec3 mx_normals_to_gradient(vec3 N, vec3 Np)
{
    float d = dot(N, Np);
    vec3 g = (d * N - Np) / max(M_FLOAT_EPS, abs(d));
    return g;
}

vec3 mx_gradient_blend_3_normals(vec3 N, vec3 N1, float N1_weight, vec3 N2, float N2_weight, vec3 N3, float N3_weight)
{
    float w1 = clamp(N1_weight, 0.0, 1.0);
    float w2 = clamp(N2_weight, 0.0, 1.0);
    float w3 = clamp(N3_weight, 0.0, 1.0);

    vec3 g1 = mx_normals_to_gradient(N, N1);
    vec3 g2 = mx_normals_to_gradient(N, N2);
    vec3 g3 = mx_normals_to_gradient(N, N3);

    // blend
    vec3 gg = w1 * g1 + w2 * g2 + w3 * g3;

    // gradient to normal
    return normalize(N - gg);
}

// This function should be categorized in mx_math.glsl but it causes build errors in MSL
// so adding here for a workaround
mat3 mx_axis_rotation_matrix(vec3 a, float r)
{
    float s = sin(r);
    float c = cos(r);
    float omc = 1.0 - c;
    return mat3(
        a.x*a.x*omc + c,     a.x*a.y*omc - a.z*s, a.x*a.z*omc + a.y*s,
        a.y*a.x*omc + a.z*s, a.y*a.y*omc + c,     a.y*a.z*omc - a.x*s,
        a.z*a.x*omc - a.y*s, a.z*a.y*omc + a.x*s, a.z*a.z*omc + c
    );
}
/*
Color transform functions.

These functions are modified versions of the color operators found in Open Shading Language:
github.com/imageworks/OpenShadingLanguage/blob/master/src/liboslexec/opcolor.cpp

It contains the subset of color operators needed to implement the MaterialX
standard library. The modifications are for conversions from C++ to GLSL.

Original copyright notice:
------------------------------------------------------------------------
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.
* Neither the name of Sony Pictures Imageworks nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------
*/

vec3 mx_hsvtorgb(vec3 hsv)
{
    // Reference for this technique: Foley & van Dam
    float h = hsv.x; float s = hsv.y; float v = hsv.z;
    if (s < 0.0001f) {
      return vec3 (v, v, v);
    } else {
        h = 6.0f * (h - floor(h));  // expand to [0..6)
        int hi = int(trunc(h));
        float f = h - float(hi);
        float p = v * (1.0f-s);
        float q = v * (1.0f-s*f);
        float t = v * (1.0f-s*(1.0f-f));
        if (hi == 0)
            return vec3 (v, t, p);
        else if (hi == 1)
            return vec3 (q, v, p);
        else if (hi == 2)
            return vec3 (p, v, t);
        else if (hi == 3)
            return vec3 (p, q, v);
        else if (hi == 4)
            return vec3 (t, p, v);
        return vec3 (v, p, q);
    }
}


vec3 mx_rgbtohsv(vec3 c)
{
    // See Foley & van Dam
    float r = c.x; float g = c.y; float b = c.z;
    float mincomp = min (r, min(g, b));
    float maxcomp = max (r, max(g, b));
    float delta = maxcomp - mincomp;  // chroma
    float h, s, v;
    v = maxcomp;
    if (maxcomp > 0.0f)
        s = delta / maxcomp;
    else s = 0.0f;
    if (s <= 0.0f)
        h = 0.0f;
    else {
        if      (r >= maxcomp) h = (g-b) / delta;
        else if (g >= maxcomp) h = 2.0f + (b-r) / delta;
        else                   h = 4.0f + (r-g) / delta;
        h *= (1.0f/6.0f);
        if (h < 0.0f)
            h += 1.0f;
    }
    return vec3(h, s, v);
}
void mx_worleynoise3d_vector2(vector position, float jitter, int style, output vector2 result)
{
    result = mx_worley_noise_vector2(position, jitter, style, 0);
}
void mx_geompropvalue_string(string geomprop, string defaultVal, output string out)
{
    if (getattribute(geomprop, out) == 0)
        out = defaultVal;
}
void mx_noise3d_vector3(vector amplitude, float pivot, vector position, output vector result)
{
    vector value = noise("snoise", position);
    result = value * amplitude + pivot;
}
void mx_worleynoise3d_float(vector position, float jitter, int style, output float result)
{
    result = mx_worley_noise_float(position, jitter, style, 0);
}
void mx_worleynoise2d_vector3(vector2 texcoord, float jitter, int style, output vector result)
{
    result = mx_worley_noise_vector3(texcoord, jitter, style, 0);
}
void mx_luminance_color4(color4 in, color lumacoeffs, output color4 result)
{
    result = color4(dot(in.rgb, lumacoeffs), in.a);
}
void mx_fractal3d_float(float amplitude, int octaves, float lacunarity, float diminish, vector position, output float result)
{
    float f = mx_fbm(position, octaves, lacunarity, diminish, "snoise");
    result = f * amplitude;
}
void mx_frame_float(output float result)
{
    // Use the standard default value if the attribute is not present.
    result = 1.0;
    getattribute("frame", result);
}
void mx_hsvtorgb_color3(vector _in, output vector result)
{
    result = transformc("hsv","rgb", _in);
}
void mx_geompropvalue_vector4(string geomprop, vector4 defaultVal, output vector4 out)
{
    float value[4];
    if (getattribute(geomprop, value) == 0)
    {
        out = defaultVal;
    }
    else
    {
        out.x = value[0];
        out.y = value[1];
        out.z = value[2];
        out.w = value[3];
    }
}
#include "lib/$fileTransformUv"

void mx_image_color3(textureresource file, string layer, color default_value, vector2 texcoord, string uaddressmode, string vaddressmode, string filtertype, string framerange, int frameoffset, string frameendaction, output color out)
{
    if (file.filename == "" ||
        (uaddressmode == "constant" && (texcoord.x<0.0 || texcoord.x>1.0)) ||
        (vaddressmode == "constant" && (texcoord.y<0.0 || texcoord.y>1.0)))
    {
        out = default_value;
        return;
    }

    color missingColor = default_value;
    vector2 st = mx_transform_uv(texcoord);
    out = texture(file.filename, st.x, st.y,
                  "subimage", layer, "interp", filtertype,
                  "missingcolor", missingColor,
                  "swrap", uaddressmode, "twrap", vaddressmode
#if OSL_VERSION_MAJOR >= 1 && OSL_VERSION_MINOR >= 14
                  , "colorspace", file.colorspace
#endif
                  );
}
void mx_luminance_color3(color in, color lumacoeffs, output color result)
{
    result = dot(in, lumacoeffs);
}
void mx_burn_float(float fg, float bg, float mix, output float result)
{
    if (abs(fg) < M_FLOAT_EPS)
    {
        result = 0.0;
        return;
    }
    result = mix*(1.0 - ((1.0 - bg) / fg)) + ((1.0-mix)*bg);
}
void mx_geompropvalue_boolean(string geomprop, int defaultVal, output int out)
{
    if (getattribute(geomprop, out) == 0)
        out = defaultVal;
}
void mx_fractal2d_vector2(vector2 amplitude, int octaves, float lacunarity, float diminish, vector2 texcoord, output vector2 result)
{
    vector2 f = mx_fbm(texcoord.x, texcoord.y, octaves, lacunarity, diminish, "snoise");
    result = f * amplitude;
}
void mx_fractal2d_vector3(vector amplitude, int octaves, float lacunarity, float diminish, vector2 texcoord, output vector result)
{
    vector f = mx_fbm(texcoord.x, texcoord.y, octaves, lacunarity, diminish, "snoise");
    result = f * amplitude;
}
#include "lib/$fileTransformUv"

void mx_image_vector2(textureresource file, string layer, vector2 default_value, vector2 texcoord, string uaddressmode, string vaddressmode, string filtertype, string framerange, int frameoffset, string frameendaction, output vector2 out)
{
    if (file.filename == "" ||
        (uaddressmode == "constant" && (texcoord.x<0.0 || texcoord.x>1.0)) ||
        (vaddressmode == "constant" && (texcoord.y<0.0 || texcoord.y>1.0)))
    {
        out = default_value;
        return;
    }

    color missingColor = color(default_value.x, default_value.y, 0.0);
    vector2 st = mx_transform_uv(texcoord);
    color rgb = texture(file.filename, st.x, st.y,
                        "subimage", layer, "interp", filtertype,
                        "missingcolor", missingColor,
                        "swrap", uaddressmode, "twrap", vaddressmode);
    out.x = rgb[0];
    out.y = rgb[1];
}
void mx_worleynoise2d_vector2(vector2 texcoord, float jitter, int style, output vector2 result)
{
    result = mx_worley_noise_vector2(texcoord, jitter, style, 0);
}
void mx_worleynoise3d_vector3(vector position, float jitter, int style, output vector result)
{
    result = mx_worley_noise_vector3(position, jitter, style, 0);
}
void mx_time_float(float fps, output float result)
{
    // Use the standard default value if the attribute is not present.
    result = 0.0;
    getattribute("time", result);
}
matrix rotationMatrix(vector axis, float angle)
{
    vector nAxis = normalize(axis);
    float s = sin(angle);
    float c = cos(angle);
    float oc = 1.0 - c;

    return matrix(oc * nAxis[0] * nAxis[0] + c,             oc * nAxis[0] * nAxis[1] - nAxis[2] * s,  oc * nAxis[2] * nAxis[0] + nAxis[1] * s,  0.0,
                  oc * nAxis[0] * nAxis[1] + nAxis[2] * s,  oc * nAxis[1] * nAxis[1] + c,             oc * nAxis[1] * nAxis[2] - nAxis[0] * s,  0.0,
                  oc * nAxis[2] * nAxis[0] - nAxis[1] * s,  oc * nAxis[1] * nAxis[2] + nAxis[0] * s,  oc * nAxis[2] * nAxis[2] + c,             0.0,
                  0.0,                                      0.0,                                      0.0,                                      1.0);
}

void mx_rotate_vector3(vector _in, float amount, vector axis, output vector result)
{
    float rotationRadians = radians(amount);
    matrix m = rotationMatrix(axis, rotationRadians);
    vector4 trans = transform(m, vector4(_in[0], _in[1], _in[2], 1.0));
    result = vector(trans.x, trans.y, trans.z);
}
void mx_premult_color4(color4 in, output color4 result)
{
    result = color4(in.rgb * in.a, in.a);
}
void mx_surface_unlit(float emission_weight, color emission_color, float transmission_weight, color transmission_color, float opacity, output surfaceshader result)
{
    float trans = clamp(transmission_weight, 0.0, 1.0);
    result.bsdf = trans * transmission_color * transparent();
    result.edf  = (1.0 - trans) * emission_weight * emission_color * emission();
    result.opacity = clamp(opacity, 0.0, 1.0);
}
void mx_noise2d_vector4(vector4 amplitude, float pivot, vector2 texcoord, output vector4 result)
{
    vector4 value = mx_noise("snoise", texcoord.x, texcoord.y);
    result = value * amplitude + pivot;
}
void mx_fractal2d_vector4(vector4 amplitude, int octaves, float lacunarity, float diminish, vector2 texcoord, output vector4 result)
{
    vector4 f = mx_fbm(texcoord.x, texcoord.y, octaves, lacunarity, diminish, "snoise");
    result = f * amplitude;
}
void mx_noise2d_float(float amplitude, float pivot, vector2 texcoord, output float result)
{
    float value = noise("snoise", texcoord.x, texcoord.y);
    result = value * amplitude + pivot;
}
void mx_geompropvalue_integer(string geomprop, int defaultVal, output int out)
{
    if (getattribute(geomprop, out) == 0)
        out = defaultVal;
}
void mx_cellnoise3d_float(vector position, output float result)
{
    result = cellnoise(position);
}
void mx_unpremult_color4(color4 in, output color4 result)
{
    result = color4(in.rgb / in.a, in.a);
}
void mx_rotate_vector2(vector2 _in, float amount, output vector2 result)
{
    float rotationRadians = radians(amount);
    float sa = sin(rotationRadians);
    float ca = cos(rotationRadians);
    result = vector2(ca*_in.x + sa*_in.y, -sa*_in.x + ca*_in.y);
}
void mx_fractal3d_vector3(vector amplitude, int octaves, float lacunarity, float diminish, vector position, output vector result)
{
    vector f = mx_fbm(position, octaves, lacunarity, diminish, "snoise");
    result = f * amplitude;
}
void mx_noise3d_vector4(vector4 amplitude, float pivot, vector position, output vector4 result)
{
    vector4 value = mx_noise("snoise", position);
    result = value * amplitude + pivot;
}
void mx_dodge_float(float fg, float bg, float mix, output float out)
{
    if (abs(1.0 - fg) < M_FLOAT_EPS)
    {
        out = 0.0;
        return;
    }
    out = mix*(bg / (1.0 - fg)) + ((1.0-mix)*bg);
}
void mx_fractal3d_vector2(vector2 amplitude, int octaves, float lacunarity, float diminish, vector position, output vector2 result)
{
    vector2 f = mx_fbm(position, octaves, lacunarity, diminish, "snoise");
    result = f * amplitude;
}
void mx_geompropvalue_vector(string geomprop, vector defaultVal, output vector out)
{
    if (getattribute(geomprop, out) == 0)
        out = defaultVal;
}
void mx_geompropvalue_float(string geomprop, float defaultVal, output float result)
{
    if (getattribute(geomprop, result) == 0)
    {
        result = defaultVal;
    }
}
void mx_fractal2d_float(float amplitude, int octaves, float lacunarity, float diminish, vector2 texcoord, output float result)
{
    float f = mx_fbm(texcoord.x, texcoord.y, octaves, lacunarity, diminish, "snoise");
    result = f * amplitude;
}
void mx_geompropvalue_color(string geomprop, color defaultVal, output color out)
{
    if (getattribute(geomprop, out) == 0)
        out = defaultVal;
}
void mx_noise3d_vector2(vector2 amplitude, float pivot, vector position, output vector2 result)
{
    vector2 value = mx_noise("snoise", position);
    result = value * amplitude + pivot;
}
#include "mx_dodge_float.osl"

void mx_dodge_color3(color fg, color bg, float mix, output color result)
{
    mx_dodge_float(fg[0], bg[0], mix, result[0]);
    mx_dodge_float(fg[1], bg[1], mix, result[1]);
    mx_dodge_float(fg[2], bg[2], mix, result[2]);
}
void mx_rgbtohsv_color3(vector _in, output vector result)
{
    result = transformc("rgb","hsv", _in);
}
void mx_worleynoise2d_float(vector2 texcoord, float jitter, int style, output float result)
{
    result = mx_worley_noise_float(texcoord, jitter, style, 0);
}
void mx_noise3d_float(float amplitude, float pivot, vector position, output float result)
{
    float value = noise("snoise", position);
    result = value * amplitude + pivot;
}
void mx_geompropvalue_vector2(string geomprop, vector2 defaultVal, output vector2 out)
{
    float value[2];
    if (getattribute(geomprop, value) == 0)
    {
        out = defaultVal;
    }
    else
    {
        out.x = value[0];
        out.y = value[1];
    }
}
void mx_transformmatrix_vector2M3(vector2 val, matrix m, output vector2 result)
{
    point res = transform(m, point(val.x, val.y, 1.0));
    result.x = res[0];
    result.y = res[1];
}
void mx_geompropvalue_color4(string geomprop, color4 defaultVal, output color4 out)
{
    float value[4];
    if (getattribute(geomprop, value) == 0)
    {
        out.rgb = defaultVal.rgb;
        out.a = defaultVal.a;
    }
    else
    {
        out.rgb[0] = value[0];
        out.rgb[1] = value[1];
        out.rgb[2] = value[2];
        out.a = value[3];
    }
}
void mx_noise2d_vector3(vector amplitude, float pivot, vector2 texcoord, output vector result)
{
    vector value = noise("snoise", texcoord.x, texcoord.y);
    result = value * amplitude + pivot;
}
#include "mx_dodge_float.osl"

void mx_dodge_color4(color4 fg , color4 bg , float mix , output color4 result)
{
    mx_dodge_float(fg.rgb[0], bg.rgb[0], mix, result.rgb[0]);
    mx_dodge_float(fg.rgb[1], bg.rgb[1], mix, result.rgb[1]);
    mx_dodge_float(fg.rgb[2], bg.rgb[2], mix, result.rgb[2]);
    mx_dodge_float(fg.a, bg.a, mix, result.a);
}
#include "lib/$fileTransformUv"

void mx_image_color4(textureresource file, string layer, color4 default_value, vector2 texcoord, string uaddressmode, string vaddressmode, string filtertype, string framerange, int frameoffset, string frameendaction, output color4 out)
{
    if (file.filename == "" ||
        (uaddressmode == "constant" && (texcoord.x<0.0 || texcoord.x>1.0)) ||
        (vaddressmode == "constant" && (texcoord.y<0.0 || texcoord.y>1.0)))
    {
        out = default_value;
        return;
    }

    color missingColor = default_value.rgb;
    float missingAlpha = default_value.a;
    vector2 st = mx_transform_uv(texcoord);
    float alpha;
    color rgb = texture(file.filename, st.x, st.y, "alpha", alpha,
                        "subimage", layer, "interp", filtertype,
                        "missingcolor", missingColor, "missingalpha", missingAlpha,
                        "swrap", uaddressmode, "twrap", vaddressmode
#if OSL_VERSION_MAJOR >= 1 && OSL_VERSION_MINOR >= 14
                        , "colorspace", file.colorspace
#endif
                        );

    out = color4(rgb, alpha);
}
#include "mx_burn_float.osl"

void mx_burn_color3(color fg, color bg, float mix, output color result)
{
    mx_burn_float(fg[0], bg[0], mix, result[0]);
    mx_burn_float(fg[1], bg[1], mix, result[1]);
    mx_burn_float(fg[2], bg[2], mix, result[2]);
}
void mx_creatematrix_vector3_matrix33(vector in1, vector in2, vector in3, output matrix result)
{
    result = matrix(in1.x, in1.y, in1.z,  0.0,
                    in2.x, in2.y, in2.z,  0.0,
                    in3.x, in3.y, in3.z,  0.0,
                    0.0,   0.0,   0.0,    1.0);
}

void mx_creatematrix_vector3_matrix44(vector in1, vector in2, vector in3, vector in4, output matrix result)
{
    result = matrix(in1.x, in1.y, in1.z,  0.0,
                    in2.x, in2.y, in2.z,  0.0,
                    in3.x, in3.y, in3.z,  0.0,
                    in4.x, in4.y, in4.z,  1.0);
}

void mx_creatematrix_vector4_matrix44(vector4 in1, vector4 in2, vector4 in3, vector4 in4, output matrix result)
{
    result = matrix(in1.x, in1.y, in1.z,  in1.w,
                    in2.x, in2.y, in2.z,  in2.w,
                    in3.x, in3.y, in3.z,  in3.w,
                    in4.x, in4.y, in4.z,  in4.w);
}
void mx_geomcolor_color4(int index, output color4 result)
{
    float value[4];
    getattribute("color", value);
    result.rgb[0] = value[0];
    result.rgb[1] = value[1];
    result.rgb[2] = value[2];
    result.a = value[3];
}
void mx_hsvtorgb_color4(color4 _in, output color4 result)
{
    result = color4(transformc("hsv","rgb", _in.rgb), 1.0);
}
#include "lib/$fileTransformUv"

void mx_image_float(textureresource file, string layer, float default_value, vector2 texcoord, string uaddressmode, string vaddressmode, string filtertype, string framerange, int frameoffset, string frameendaction, output float out)
{
    if (file.filename == "" ||
        (uaddressmode == "constant" && (texcoord.x<0.0 || texcoord.x>1.0)) ||
        (vaddressmode == "constant" && (texcoord.y<0.0 || texcoord.y>1.0)))
    {
        out = default_value;
        return;
    }

    color missingColor = color(default_value);
    vector2 st = mx_transform_uv(texcoord);
    color rgb = texture(file.filename, st.x, st.y,
                        "subimage", layer, "interp", filtertype,
                        "missingcolor", missingColor,
                        "swrap", uaddressmode, "twrap", vaddressmode);
    out = rgb[0];
}
#include "mx_burn_float.osl"

void mx_burn_color4(color4 fg, color4 bg, float mix, output color4 result)
{
    mx_burn_float(fg.rgb[0], bg.rgb[0], mix, result.rgb[0]);
    mx_burn_float(fg.rgb[1], bg.rgb[1], mix, result.rgb[1]);
    mx_burn_float(fg.rgb[2], bg.rgb[2], mix, result.rgb[2]);
    mx_burn_float(fg.a, bg.a, mix, result.a);
}
void mx_heighttonormal_vector3(float height, float scale, vector2 texcoord, output vector result)
{
    // Scale factor for parity with traditional Sobel filtering.
    float SOBEL_SCALE_FACTOR = 1.0 / 16.0;

    // Compute screen-space gradients of the heightfield and texture coordinates.
    vector2 dHdS = vector2(Dx(height), Dy(height)) * scale * SOBEL_SCALE_FACTOR;
    vector2 dUdS = vector2(Dx(texcoord.x), Dy(texcoord.x));
    vector2 dVdS = vector2(Dx(texcoord.y), Dy(texcoord.y));

    // Construct a screen-space tangent frame.
    vector tangent = vector(dUdS.x, dVdS.x, dHdS.x);
    vector bitangent = vector(dUdS.y, dVdS.y, dHdS.y);
    vector n = cross(tangent, bitangent);

    // Handle invalid and mirrored texture coordinates.
    if (dot(n, n) < M_FLOAT_EPS * M_FLOAT_EPS)
    {
        n = vector(0, 0, 1);
    }
    else if (n[2] < 0.0)
    {
        n *= -1.0;
    }

    // Normalize and encode the results.
    result = normalize(n) * 0.5 + 0.5;
}
void mx_noise2d_vector2(vector2 amplitude, float pivot, vector2 texcoord, output vector2 result)
{
    vector2 value = mx_noise("snoise", texcoord.x, texcoord.y);
    result = value * amplitude + pivot;
}
#include "lib/$fileTransformUv"

void mx_image_vector3(textureresource file, string layer, vector default_value, vector2 texcoord, string uaddressmode, string vaddressmode, string filtertype, string framerange, int frameoffset, string frameendaction, output vector out)
{
    if (file.filename == "" ||
        (uaddressmode == "constant" && (texcoord.x<0.0 || texcoord.x>1.0)) ||
        (vaddressmode == "constant" && (texcoord.y<0.0 || texcoord.y>1.0)))
    {
        out = default_value;
        return;
    }

    color missingColor = default_value;
    vector2 st = mx_transform_uv(texcoord);
    out = texture(file.filename, st.x, st.y,
                  "subimage", layer, "interp", filtertype,
                  "missingcolor", missingColor,
                  "swrap", uaddressmode, "twrap", vaddressmode);
}
void mx_rgbtohsv_color4(color4 _in, output color4 result)
{
    result = color4(transformc("rgb","hsv", _in.rgb), 1.0);
}
void mx_cellnoise2d_float(vector2 texcoord, output float result)
{
    result = cellnoise(texcoord.x, texcoord.y);
}
void mx_geomcolor_color3(int index, output color result)
{
    getattribute("color", result);
}
void mx_normalmap_vector2(vector value, vector2 normal_scale, vector N, vector T, vector B, output vector result)
{
    if (value == vector(0.0))
    {
        result = N;
    }
    else
    {
        // The OSL backend uses dPdu and dPdv for tangents and bitangents, but these vectors are not
        // guaranteed to be orthonormal.
        //
        // Orthogonalize the tangent frame using Gram-Schmidt, unlike in the other backends.
        //
        vector v = value * 2.0 - 1.0;
        vector Tn = normalize(T - dot(T, N) * N);
        vector Bn = normalize(B - dot(B, N) * N - dot(B, Tn) * Tn);
        result = normalize(Tn * v[0] * normal_scale.x + Bn * v[1] * normal_scale.y + N * v[2]);
    }
}

void mx_normalmap_float(vector value, float normal_scale, vector N, vector T, vector B, output vector result)
{
    mx_normalmap_vector2(value, vector2(normal_scale, normal_scale), N, T, B, result);
}
void mx_disjointover_color4(color4 fg, color4 bg, float mix, output color4 result)
{
    float summedAlpha = fg.a + bg.a;

    if (summedAlpha <= 1)
    {
        result.rgb = fg.rgb + bg.rgb;
    }
    else
    {
        if (abs(bg.a) < M_FLOAT_EPS)
        {
            result.rgb = 0.0;
        }
        else
        {
            float x = (1 - fg.a) / bg.a;
            result.rgb = fg.rgb + bg.rgb * x;
        }
    }
    result.a = min(summedAlpha, 1.0);

    result.rgb = result.rgb * mix + (1.0 - mix) * bg.rgb;
    result.a = result.a * mix + (1.0 - mix) * bg.a;
}
#include "lib/$fileTransformUv"

void mx_image_vector4(textureresource file, string layer, vector4 default_value, vector2 texcoord, string uaddressmode, string vaddressmode, string filtertype, string framerange, int frameoffset, string frameendaction, output vector4 out)
{
    if (file.filename == "" ||
        (uaddressmode == "constant" && (texcoord.x<0.0 || texcoord.x>1.0)) ||
        (vaddressmode == "constant" && (texcoord.y<0.0 || texcoord.y>1.0)))
    {
        out = default_value;
        return;
    }

    color missingColor = color(default_value.x, default_value.y, default_value.z);
    float missingAlpha = default_value.w;
    vector2 st = mx_transform_uv(texcoord);
    float alpha;
    color rgb = texture(file.filename, st.x, st.y, "alpha", alpha,
                        "subimage", layer, "interp", filtertype,
                        "missingcolor", missingColor, "missingalpha", missingAlpha,
                        "swrap", uaddressmode, "twrap", vaddressmode);

    out = vector4(rgb[0], rgb[1], rgb[2], alpha);
}
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations for OSL implementations of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- Shader nodes                                                             -->
  <!-- ======================================================================== -->

  <!-- <surfacematerial> -->
  <implementation name="IM_surfacematerial_genosl" nodedef="ND_surfacematerial" target="genosl" />

  <!-- <surface_unlit> -->
  <implementation name="IM_surface_unlit_genosl" nodedef="ND_surface_unlit" file="mx_surface_unlit.osl" function="mx_surface_unlit" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Texture nodes                                                            -->
  <!-- ======================================================================== -->

  <!-- <image> -->
  <implementation name="IM_image_float_genosl" nodedef="ND_image_float" file="mx_image_float.osl" function="mx_image_float" target="genosl">
    <input name="default" type="float" implname="default_value" />
  </implementation>
  <implementation name="IM_image_color3_genosl" nodedef="ND_image_color3" file="mx_image_color3.osl" function="mx_image_color3" target="genosl">
    <input name="default" type="color3" implname="default_value" />
  </implementation>
  <implementation name="IM_image_color4_genosl" nodedef="ND_image_color4" file="mx_image_color4.osl" function="mx_image_color4" target="genosl">
    <input name="default" type="color4" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector2_genosl" nodedef="ND_image_vector2" file="mx_image_vector2.osl" function="mx_image_vector2" target="genosl">
    <input name="default" type="vector2" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector3_genosl" nodedef="ND_image_vector3" file="mx_image_vector3.osl" function="mx_image_vector3" target="genosl">
    <input name="default" type="vector3" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector4_genosl" nodedef="ND_image_vector4" file="mx_image_vector4.osl" function="mx_image_vector4" target="genosl">
    <input name="default" type="vector4" implname="default_value" />
  </implementation>

  <!-- <triplanarprojection> -->

  <!-- <normalmap> -->
  <implementation name="IM_normalmap_float_genosl" nodedef="ND_normalmap_float" file="mx_normalmap.osl" function="mx_normalmap_float" target="genosl" />
  <implementation name="IM_normalmap_vector2_genosl" nodedef="ND_normalmap_vector2" file="mx_normalmap.osl" function="mx_normalmap_vector2" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Procedural nodes                                                         -->
  <!-- ======================================================================== -->

  <!-- <constant> -->
  <implementation name="IM_constant_float_genosl" nodedef="ND_constant_float" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_color3_genosl" nodedef="ND_constant_color3" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_color4_genosl" nodedef="ND_constant_color4" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_vector2_genosl" nodedef="ND_constant_vector2" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_vector3_genosl" nodedef="ND_constant_vector3" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_vector4_genosl" nodedef="ND_constant_vector4" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_boolean_genosl" nodedef="ND_constant_boolean" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_integer_genosl" nodedef="ND_constant_integer" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_matrix33_genosl" nodedef="ND_constant_matrix33" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_matrix44_genosl" nodedef="ND_constant_matrix44" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_string_genosl" nodedef="ND_constant_string" target="genosl" sourcecode="{{value}}" />
  <implementation name="IM_constant_filename_genosl" nodedef="ND_constant_filename" target="genosl" sourcecode="{{value}}" />

  <!-- <ramplr> -->
  <implementation name="IM_ramplr_float_genosl" nodedef="ND_ramplr_float" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, clamp({{texcoord}}.x, 0, 1))" />
  <implementation name="IM_ramplr_color3_genosl" nodedef="ND_ramplr_color3" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, clamp({{texcoord}}.x, 0, 1))" />
  <implementation name="IM_ramplr_color4_genosl" nodedef="ND_ramplr_color4" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, clamp({{texcoord}}.x, 0, 1))" />
  <implementation name="IM_ramplr_vector2_genosl" nodedef="ND_ramplr_vector2" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, clamp({{texcoord}}.x, 0, 1))" />
  <implementation name="IM_ramplr_vector3_genosl" nodedef="ND_ramplr_vector3" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, clamp({{texcoord}}.x, 0, 1))" />
  <implementation name="IM_ramplr_vector4_genosl" nodedef="ND_ramplr_vector4" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, clamp({{texcoord}}.x, 0, 1))" />

  <!-- <ramptb> -->
  <implementation name="IM_ramptb_float_genosl" nodedef="ND_ramptb_float" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, clamp({{texcoord}}.y, 0, 1))" />
  <implementation name="IM_ramptb_color3_genosl" nodedef="ND_ramptb_color3" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, clamp({{texcoord}}.y, 0, 1))" />
  <implementation name="IM_ramptb_color4_genosl" nodedef="ND_ramptb_color4" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, clamp({{texcoord}}.y, 0, 1))" />
  <implementation name="IM_ramptb_vector2_genosl" nodedef="ND_ramptb_vector2" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, clamp({{texcoord}}.y, 0, 1))" />
  <implementation name="IM_ramptb_vector3_genosl" nodedef="ND_ramptb_vector3" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, clamp({{texcoord}}.y, 0, 1))" />
  <implementation name="IM_ramptb_vector4_genosl" nodedef="ND_ramptb_vector4" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, clamp({{texcoord}}.y, 0, 1))" />

  <!-- <splitlr> -->
  <implementation name="IM_splitlr_float_genosl" nodedef="ND_splitlr_float" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, aastep({{center}}, {{texcoord}}.x))" />
  <implementation name="IM_splitlr_color3_genosl" nodedef="ND_splitlr_color3" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, aastep({{center}}, {{texcoord}}.x))" />
  <implementation name="IM_splitlr_color4_genosl" nodedef="ND_splitlr_color4" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, aastep({{center}}, {{texcoord}}.x))" />
  <implementation name="IM_splitlr_vector2_genosl" nodedef="ND_splitlr_vector2" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, aastep({{center}}, {{texcoord}}.x))" />
  <implementation name="IM_splitlr_vector3_genosl" nodedef="ND_splitlr_vector3" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, aastep({{center}}, {{texcoord}}.x))" />
  <implementation name="IM_splitlr_vector4_genosl" nodedef="ND_splitlr_vector4" target="genosl" sourcecode="mix({{valuel}}, {{valuer}}, aastep({{center}}, {{texcoord}}.x))" />

  <!-- <splittb> -->
  <implementation name="IM_splittb_float_genosl" nodedef="ND_splittb_float" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, aastep({{center}}, {{texcoord}}.y))" />
  <implementation name="IM_splittb_color3_genosl" nodedef="ND_splittb_color3" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, aastep({{center}}, {{texcoord}}.y))" />
  <implementation name="IM_splittb_color4_genosl" nodedef="ND_splittb_color4" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, aastep({{center}}, {{texcoord}}.y))" />
  <implementation name="IM_splittb_vector2_genosl" nodedef="ND_splittb_vector2" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, aastep({{center}}, {{texcoord}}.y))" />
  <implementation name="IM_splittb_vector3_genosl" nodedef="ND_splittb_vector3" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, aastep({{center}}, {{texcoord}}.y))" />
  <implementation name="IM_splittb_vector4_genosl" nodedef="ND_splittb_vector4" target="genosl" sourcecode="mix({{valuet}}, {{valueb}}, aastep({{center}}, {{texcoord}}.y))" />

  <!-- <noise2d> -->
  <implementation name="IM_noise2d_float_genosl" nodedef="ND_noise2d_float" file="mx_noise2d_float.osl" function="mx_noise2d_float" target="genosl" />
  <implementation name="IM_noise2d_vector2_genosl" nodedef="ND_noise2d_vector2" file="mx_noise2d_vector2.osl" function="mx_noise2d_vector2" target="genosl" />
  <implementation name="IM_noise2d_vector3_genosl" nodedef="ND_noise2d_vector3" file="mx_noise2d_vector3.osl" function="mx_noise2d_vector3" target="genosl" />
  <implementation name="IM_noise2d_vector4_genosl" nodedef="ND_noise2d_vector4" file="mx_noise2d_vector4.osl" function="mx_noise2d_vector4" target="genosl" />

  <!-- <noise3d> -->
  <implementation name="IM_noise3d_float_genosl" nodedef="ND_noise3d_float" file="mx_noise3d_float.osl" function="mx_noise3d_float" target="genosl" />
  <implementation name="IM_noise3d_vector2_genosl" nodedef="ND_noise3d_vector2" file="mx_noise3d_vector2.osl" function="mx_noise3d_vector2" target="genosl" />
  <implementation name="IM_noise3d_vector3_genosl" nodedef="ND_noise3d_vector3" file="mx_noise3d_vector3.osl" function="mx_noise3d_vector3" target="genosl" />
  <implementation name="IM_noise3d_vector4_genosl" nodedef="ND_noise3d_vector4" file="mx_noise3d_vector4.osl" function="mx_noise3d_vector4" target="genosl" />

  <!-- <fractal2d> -->
  <implementation name="IM_fractal2d_float_genosl" nodedef="ND_fractal2d_float" file="mx_fractal2d_float.osl" function="mx_fractal2d_float" target="genosl" />
  <implementation name="IM_fractal2d_vector2_genosl" nodedef="ND_fractal2d_vector2" file="mx_fractal2d_vector2.osl" function="mx_fractal2d_vector2" target="genosl" />
  <implementation name="IM_fractal2d_vector3_genosl" nodedef="ND_fractal2d_vector3" file="mx_fractal2d_vector3.osl" function="mx_fractal2d_vector3" target="genosl" />
  <implementation name="IM_fractal2d_vector4_genosl" nodedef="ND_fractal2d_vector4" file="mx_fractal2d_vector4.osl" function="mx_fractal2d_vector4" target="genosl" />

  <!-- <fractal3d> -->
  <implementation name="IM_fractal3d_float_genosl" nodedef="ND_fractal3d_float" file="mx_fractal3d_float.osl" function="mx_fractal3d_float" target="genosl" />
  <implementation name="IM_fractal3d_vector2_genosl" nodedef="ND_fractal3d_vector2" file="mx_fractal3d_vector2.osl" function="mx_fractal3d_vector2" target="genosl" />
  <implementation name="IM_fractal3d_vector3_genosl" nodedef="ND_fractal3d_vector3" file="mx_fractal3d_vector3.osl" function="mx_fractal3d_vector3" target="genosl" />
  <implementation name="IM_fractal3d_vector4_genosl" nodedef="ND_fractal3d_vector4" file="mx_fractal3d_vector4.osl" function="mx_fractal3d_vector4" target="genosl" />

  <!-- <cellnoise2d> -->
  <implementation name="IM_cellnoise2d_float_genosl" nodedef="ND_cellnoise2d_float" file="mx_cellnoise2d_float.osl" function="mx_cellnoise2d_float" target="genosl" />

  <!-- <cellnoise3d> -->
  <implementation name="IM_cellnoise3d_float_genosl" nodedef="ND_cellnoise3d_float" file="mx_cellnoise3d_float.osl" function="mx_cellnoise3d_float" target="genosl" />

  <!-- <worleynoise2d> -->
  <implementation name="IM_worleynoise2d_float_genosl" nodedef="ND_worleynoise2d_float" file="mx_worleynoise2d_float.osl" function="mx_worleynoise2d_float" target="genosl" />
  <implementation name="IM_worleynoise2d_vector2_genosl" nodedef="ND_worleynoise2d_vector2" file="mx_worleynoise2d_vector2.osl" function="mx_worleynoise2d_vector2" target="genosl" />
  <implementation name="IM_worleynoise2d_vector3_genosl" nodedef="ND_worleynoise2d_vector3" file="mx_worleynoise2d_vector3.osl" function="mx_worleynoise2d_vector3" target="genosl" />

  <!-- <worleynoise3d> -->
  <implementation name="IM_worleynoise3d_float_genosl" nodedef="ND_worleynoise3d_float" file="mx_worleynoise3d_float.osl" function="mx_worleynoise3d_float" target="genosl" />
  <implementation name="IM_worleynoise3d_vector2_genosl" nodedef="ND_worleynoise3d_vector2" file="mx_worleynoise3d_vector2.osl" function="mx_worleynoise3d_vector2" target="genosl" />
  <implementation name="IM_worleynoise3d_vector3_genosl" nodedef="ND_worleynoise3d_vector3" file="mx_worleynoise3d_vector3.osl" function="mx_worleynoise3d_vector3" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Geometric nodes                                                          -->
  <!-- ======================================================================== -->

  <!-- <position> -->
  <implementation name="IM_position_vector3_genosl" nodedef="ND_position_vector3" target="genosl" sourcecode="transform({{space}}, P)" />

  <!-- <normal> -->
  <implementation name="IM_normal_vector3_genosl" nodedef="ND_normal_vector3" target="genosl" sourcecode="transform({{space}}, N)" />

  <!-- <tangent> -->
  <implementation name="IM_tangent_vector3_genosl" nodedef="ND_tangent_vector3" target="genosl" sourcecode="transform({{space}}, normalize(dPdu))" />

  <!-- <bitangent> -->
  <implementation name="IM_bitangent_vector3_genosl" nodedef="ND_bitangent_vector3" target="genosl" sourcecode="transform({{space}}, normalize(dPdv))" />

  <!-- <texcoord> -->
  <implementation name="IM_texcoord_vector2_genosl" nodedef="ND_texcoord_vector2" target="genosl" sourcecode="vector2(u,v)" />
  <implementation name="IM_texcoord_vector3_genosl" nodedef="ND_texcoord_vector3" target="genosl" sourcecode="vector(u,v,0)" />

  <!-- <geomcolor> -->
  <implementation name="IM_geomcolor_float_genosl" nodedef="ND_geomcolor_float" file="mx_geomcolor_float.osl" function="mx_geomcolor_float" target="genosl" />
  <implementation name="IM_geomcolor_color3_genosl" nodedef="ND_geomcolor_color3" file="mx_geomcolor_color3.osl" function="mx_geomcolor_color3" target="genosl" />
  <implementation name="IM_geomcolor_color4_genosl" nodedef="ND_geomcolor_color4" file="mx_geomcolor_color4.osl" function="mx_geomcolor_color4" target="genosl" />

  <!-- <geompropvalue> -->
  <implementation name="IM_geompropvalue_integer_genosl" nodedef="ND_geompropvalue_integer" file="mx_geompropvalue_integer.osl" function="mx_geompropvalue_integer" target="genosl" />
  <implementation name="IM_geompropvalue_boolean_genosl" nodedef="ND_geompropvalue_boolean" file="mx_geompropvalue_boolean.osl" function="mx_geompropvalue_boolean" target="genosl" />
  <implementation name="IM_geompropvalue_float_genosl" nodedef="ND_geompropvalue_float" file="mx_geompropvalue_float.osl" function="mx_geompropvalue_float" target="genosl" />
  <implementation name="IM_geompropvalue_color3_genosl" nodedef="ND_geompropvalue_color3" file="mx_geompropvalue_color3.osl" function="mx_geompropvalue_color" target="genosl" />
  <implementation name="IM_geompropvalue_color4_genosl" nodedef="ND_geompropvalue_color4" file="mx_geompropvalue_color4.osl" function="mx_geompropvalue_color4" target="genosl" />
  <implementation name="IM_geompropvalue_vector2_genosl" nodedef="ND_geompropvalue_vector2" file="mx_geompropvalue_vector2.osl" function="mx_geompropvalue_vector2" target="genosl" />
  <implementation name="IM_geompropvalue_vector3_genosl" nodedef="ND_geompropvalue_vector3" file="mx_geompropvalue_vector3.osl" function="mx_geompropvalue_vector" target="genosl" />
  <implementation name="IM_geompropvalue_vector4_genosl" nodedef="ND_geompropvalue_vector4" file="mx_geompropvalue_vector4.osl" function="mx_geompropvalue_vector4" target="genosl" />

  <!-- <geompropvalueuniform> -->
  <implementation name="IM_geompropvalue_string_genosl" nodedef="ND_geompropvalueuniform_string" file="mx_geompropvalue_string.osl" function="mx_geompropvalue_string" target="genosl" />
  <implementation name="IM_geompropvalue_filename_genosl" nodedef="ND_geompropvalueuniform_filename" file="mx_geompropvalue_string.osl" function="mx_geompropvalue_string" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Application nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <frame> -->
  <implementation name="IM_frame_float_genosl" nodedef="ND_frame_float" file="mx_frame_float.osl" function="mx_frame_float" target="genosl" />

  <!-- <time> -->
  <implementation name="IM_time_float_genosl" nodedef="ND_time_float" file="mx_time_float.osl" function="mx_time_float" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Math nodes                                                               -->
  <!-- ======================================================================== -->

  <!-- <add> -->
  <implementation name="IM_add_float_genosl" nodedef="ND_add_float" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_integer_genosl" nodedef="ND_add_integer" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_color3_genosl" nodedef="ND_add_color3" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_color3FA_genosl" nodedef="ND_add_color3FA" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_color4_genosl" nodedef="ND_add_color4" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_color4FA_genosl" nodedef="ND_add_color4FA" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector2_genosl" nodedef="ND_add_vector2" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector2FA_genosl" nodedef="ND_add_vector2FA" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector3_genosl" nodedef="ND_add_vector3" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector3FA_genosl" nodedef="ND_add_vector3FA" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector4_genosl" nodedef="ND_add_vector4" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_vector4FA_genosl" nodedef="ND_add_vector4FA" target="genosl" sourcecode="{{in1}} + {{in2}}" />
  <implementation name="IM_add_matrix33_genosl" nodedef="ND_add_matrix33" sourcecode="mx_add({{in1}}, {{in2}})" target="genosl" />
  <implementation name="IM_add_matrix33FA_genosl" nodedef="ND_add_matrix33FA" sourcecode="mx_add({{in1}}, {{in2}})" target="genosl" />
  <implementation name="IM_add_matrix44_genosl" nodedef="ND_add_matrix44" sourcecode="mx_add({{in1}}, {{in2}})" target="genosl" />
  <implementation name="IM_add_matrix44FA_genosl" nodedef="ND_add_matrix44FA" sourcecode="mx_add({{in1}}, {{in2}})" target="genosl" />

  <!-- <subtract> -->
  <implementation name="IM_subtract_float_genosl" nodedef="ND_subtract_float" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_integer_genosl" nodedef="ND_subtract_integer" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_color3_genosl" nodedef="ND_subtract_color3" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_color3FA_genosl" nodedef="ND_subtract_color3FA" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_color4_genosl" nodedef="ND_subtract_color4" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_color4FA_genosl" nodedef="ND_subtract_color4FA" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector2_genosl" nodedef="ND_subtract_vector2" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector2FA_genosl" nodedef="ND_subtract_vector2FA" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector3_genosl" nodedef="ND_subtract_vector3" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector3FA_genosl" nodedef="ND_subtract_vector3FA" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector4_genosl" nodedef="ND_subtract_vector4" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_vector4FA_genosl" nodedef="ND_subtract_vector4FA" target="genosl" sourcecode="{{in1}} - {{in2}}" />
  <implementation name="IM_subtract_matrix33_genosl" nodedef="ND_subtract_matrix33" sourcecode="mx_subtract({{in1}}, {{in2}})" target="genosl" />
  <implementation name="IM_subtract_matrix33FA_genosl" nodedef="ND_subtract_matrix33FA" sourcecode="mx_subtract({{in1}}, {{in2}})" target="genosl" />
  <implementation name="IM_subtract_matrix44_genosl" nodedef="ND_subtract_matrix44" sourcecode="mx_subtract({{in1}}, {{in2}})" target="genosl" />
  <implementation name="IM_subtract_matrix44FA_genosl" nodedef="ND_subtract_matrix44FA" sourcecode="mx_subtract({{in1}}, {{in2}})" target="genosl" />

  <!-- <multiply> -->
  <implementation name="IM_multiply_float_genosl" nodedef="ND_multiply_float" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_color3_genosl" nodedef="ND_multiply_color3" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_color3FA_genosl" nodedef="ND_multiply_color3FA" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_color4_genosl" nodedef="ND_multiply_color4" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_color4FA_genosl" nodedef="ND_multiply_color4FA" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector2_genosl" nodedef="ND_multiply_vector2" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector2FA_genosl" nodedef="ND_multiply_vector2FA" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector3_genosl" nodedef="ND_multiply_vector3" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector3FA_genosl" nodedef="ND_multiply_vector3FA" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector4_genosl" nodedef="ND_multiply_vector4" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_vector4FA_genosl" nodedef="ND_multiply_vector4FA" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_matrix33_genosl" nodedef="ND_multiply_matrix33" target="genosl" sourcecode="{{in1}} * {{in2}}" />
  <implementation name="IM_multiply_matrix44_genosl" nodedef="ND_multiply_matrix44" target="genosl" sourcecode="{{in1}} * {{in2}}" />

  <!-- <divide> -->
  <implementation name="IM_divide_float_genosl" nodedef="ND_divide_float" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_color3_genosl" nodedef="ND_divide_color3" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_color3FA_genosl" nodedef="ND_divide_color3FA" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_color4_genosl" nodedef="ND_divide_color4" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_color4FA_genosl" nodedef="ND_divide_color4FA" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector2_genosl" nodedef="ND_divide_vector2" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector2FA_genosl" nodedef="ND_divide_vector2FA" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector3_genosl" nodedef="ND_divide_vector3" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector3FA_genosl" nodedef="ND_divide_vector3FA" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector4_genosl" nodedef="ND_divide_vector4" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_vector4FA_genosl" nodedef="ND_divide_vector4FA" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_matrix33_genosl" nodedef="ND_divide_matrix33" target="genosl" sourcecode="{{in1}} / {{in2}}" />
  <implementation name="IM_divide_matrix44_genosl" nodedef="ND_divide_matrix44" target="genosl" sourcecode="{{in1}} / {{in2}}" />

  <!-- <modulo> -->
  <implementation name="IM_modulo_float_genosl" nodedef="ND_modulo_float" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_color3_genosl" nodedef="ND_modulo_color3" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_color3FA_genosl" nodedef="ND_modulo_color3FA" target="genosl" sourcecode="mod({{in1}}, color({{in2}},{{in2}},{{in2}}))" />
  <implementation name="IM_modulo_color4_genosl" nodedef="ND_modulo_color4" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_color4FA_genosl" nodedef="ND_modulo_color4FA" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector2_genosl" nodedef="ND_modulo_vector2" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector2FA_genosl" nodedef="ND_modulo_vector2FA" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector3_genosl" nodedef="ND_modulo_vector3" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector3FA_genosl" nodedef="ND_modulo_vector3FA" target="genosl" sourcecode="mod({{in1}}, vector({{in2}},{{in2}},{{in2}}))" />
  <implementation name="IM_modulo_vector4_genosl" nodedef="ND_modulo_vector4" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />
  <implementation name="IM_modulo_vector4FA_genosl" nodedef="ND_modulo_vector4FA" target="genosl" sourcecode="mod({{in1}}, {{in2}})" />

  <!-- <fract> -->
  <implementation name="IM_fract_float_genosl" nodedef="ND_fract_float" target="genosl" sourcecode="{{in}} - floor({{in}})" />
  <implementation name="IM_fract_color3_genosl" nodedef="ND_fract_color3" target="genosl" sourcecode="{{in}} - floor({{in}})" />
  <implementation name="IM_fract_color4_genosl" nodedef="ND_fract_color4" target="genosl" sourcecode="{{in}} - floor({{in}})" />
  <implementation name="IM_fract_vector2_genosl" nodedef="ND_fract_vector2" target="genosl" sourcecode="{{in}} - floor({{in}})" />
  <implementation name="IM_fract_vector3_genosl" nodedef="ND_fract_vector3" target="genosl" sourcecode="{{in}} - floor({{in}})" />
  <implementation name="IM_fract_vector4_genosl" nodedef="ND_fract_vector4" target="genosl" sourcecode="{{in}} - floor({{in}})" />

  <!-- <invert> -->
  <implementation name="IM_invert_float_genosl" nodedef="ND_invert_float" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_color3_genosl" nodedef="ND_invert_color3" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_color3FA_genosl" nodedef="ND_invert_color3FA" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_color4_genosl" nodedef="ND_invert_color4" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_color4FA_genosl" nodedef="ND_invert_color4FA" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector2_genosl" nodedef="ND_invert_vector2" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector2FA_genosl" nodedef="ND_invert_vector2FA" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector3_genosl" nodedef="ND_invert_vector3" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector3FA_genosl" nodedef="ND_invert_vector3FA" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector4_genosl" nodedef="ND_invert_vector4" target="genosl" sourcecode="{{amount}} - {{in}}" />
  <implementation name="IM_invert_vector4FA_genosl" nodedef="ND_invert_vector4FA" target="genosl" sourcecode="{{amount}} - {{in}}" />

  <!-- <absval> -->
  <implementation name="IM_absval_float_genosl" nodedef="ND_absval_float" target="genosl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_color3_genosl" nodedef="ND_absval_color3" target="genosl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_color4_genosl" nodedef="ND_absval_color4" target="genosl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_vector2_genosl" nodedef="ND_absval_vector2" target="genosl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_vector3_genosl" nodedef="ND_absval_vector3" target="genosl" sourcecode="abs({{in}})" />
  <implementation name="IM_absval_vector4_genosl" nodedef="ND_absval_vector4" target="genosl" sourcecode="abs({{in}})" />

  <!-- <floor> -->
  <implementation name="IM_floor_float_genosl" nodedef="ND_floor_float" target="genosl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_color3_genosl" nodedef="ND_floor_color3" target="genosl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_color4_genosl" nodedef="ND_floor_color4" target="genosl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_vector2_genosl" nodedef="ND_floor_vector2" target="genosl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_vector3_genosl" nodedef="ND_floor_vector3" target="genosl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_vector4_genosl" nodedef="ND_floor_vector4" target="genosl" sourcecode="floor({{in}})" />
  <implementation name="IM_floor_integer_genosl" nodedef="ND_floor_integer" target="genosl" sourcecode="int(floor({{in}}))" />

  <!-- <ceil> -->
  <implementation name="IM_ceil_float_genosl" nodedef="ND_ceil_float" target="genosl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_color3_genosl" nodedef="ND_ceil_color3" target="genosl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_color4_genosl" nodedef="ND_ceil_color4" target="genosl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_vector2_genosl" nodedef="ND_ceil_vector2" target="genosl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_vector3_genosl" nodedef="ND_ceil_vector3" target="genosl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_vector4_genosl" nodedef="ND_ceil_vector4" target="genosl" sourcecode="ceil({{in}})" />
  <implementation name="IM_ceil_integer_genosl" nodedef="ND_ceil_integer" target="genosl" sourcecode="int(ceil({{in}}))" />

  <!-- <round> -->
  <implementation name="IM_round_float_genosl" nodedef="ND_round_float" target="genosl" sourcecode="round({{in}})" />
  <implementation name="IM_round_color3_genosl" nodedef="ND_round_color3" target="genosl" sourcecode="round({{in}})" />
  <implementation name="IM_round_color4_genosl" nodedef="ND_round_color4" target="genosl" sourcecode="round({{in}})" />
  <implementation name="IM_round_vector2_genosl" nodedef="ND_round_vector2" target="genosl" sourcecode="round({{in}})" />
  <implementation name="IM_round_vector3_genosl" nodedef="ND_round_vector3" target="genosl" sourcecode="round({{in}})" />
  <implementation name="IM_round_vector4_genosl" nodedef="ND_round_vector4" target="genosl" sourcecode="round({{in}})" />
  <implementation name="IM_round_integer_genosl" nodedef="ND_round_integer" target="genosl" sourcecode="int(round({{in}}))" />

  <!-- <power> -->
  <implementation name="IM_power_float_genosl" nodedef="ND_power_float" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_color3_genosl" nodedef="ND_power_color3" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_color3FA_genosl" nodedef="ND_power_color3FA" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_color4_genosl" nodedef="ND_power_color4" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_color4FA_genosl" nodedef="ND_power_color4FA" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector2_genosl" nodedef="ND_power_vector2" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector2FA_genosl" nodedef="ND_power_vector2FA" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector3_genosl" nodedef="ND_power_vector3" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector3FA_genosl" nodedef="ND_power_vector3FA" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector4_genosl" nodedef="ND_power_vector4" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />
  <implementation name="IM_power_vector4FA_genosl" nodedef="ND_power_vector4FA" target="genosl" sourcecode="pow({{in1}}, {{in2}})" />

  <!-- <sin>, <cos>, <tan>, <asin>, <acos>, <atan2> -->
  <implementation name="IM_sin_float_genosl" nodedef="ND_sin_float" target="genosl" sourcecode="sin({{in}})" />
  <implementation name="IM_cos_float_genosl" nodedef="ND_cos_float" target="genosl" sourcecode="cos({{in}})" />
  <implementation name="IM_tan_float_genosl" nodedef="ND_tan_float" target="genosl" sourcecode="tan({{in}})" />
  <implementation name="IM_asin_float_genosl" nodedef="ND_asin_float" target="genosl" sourcecode="asin({{in}})" />
  <implementation name="IM_acos_float_genosl" nodedef="ND_acos_float" target="genosl" sourcecode="acos({{in}})" />
  <implementation name="IM_atan2_float_genosl" nodedef="ND_atan2_float" target="genosl" sourcecode="atan2({{iny}},{{inx}})" />
  <implementation name="IM_sin_vector2_genosl" nodedef="ND_sin_vector2" target="genosl" sourcecode="sin({{in}})" />
  <implementation name="IM_cos_vector2_genosl" nodedef="ND_cos_vector2" target="genosl" sourcecode="cos({{in}})" />
  <implementation name="IM_tan_vector2_genosl" nodedef="ND_tan_vector2" target="genosl" sourcecode="tan({{in}})" />
  <implementation name="IM_asin_vector2_genosl" nodedef="ND_asin_vector2" target="genosl" sourcecode="asin({{in}})" />
  <implementation name="IM_acos_vector2_genosl" nodedef="ND_acos_vector2" target="genosl" sourcecode="acos({{in}})" />
  <implementation name="IM_atan2_vector2_genosl" nodedef="ND_atan2_vector2" target="genosl" sourcecode="atan2({{iny}},{{inx}})" />
  <implementation name="IM_sin_vector3_genosl" nodedef="ND_sin_vector3" target="genosl" sourcecode="sin({{in}})" />
  <implementation name="IM_cos_vector3_genosl" nodedef="ND_cos_vector3" target="genosl" sourcecode="cos({{in}})" />
  <implementation name="IM_tan_vector3_genosl" nodedef="ND_tan_vector3" target="genosl" sourcecode="tan({{in}})" />
  <implementation name="IM_asin_vector3_genosl" nodedef="ND_asin_vector3" target="genosl" sourcecode="asin({{in}})" />
  <implementation name="IM_acos_vector3_genosl" nodedef="ND_acos_vector3" target="genosl" sourcecode="acos({{in}})" />
  <implementation name="IM_atan2_vector3_genosl" nodedef="ND_atan2_vector3" target="genosl" sourcecode="atan2({{iny}},{{inx}})" />
  <implementation name="IM_sin_vector4_genosl" nodedef="ND_sin_vector4" target="genosl" sourcecode="sin({{in}})" />
  <implementation name="IM_cos_vector4_genosl" nodedef="ND_cos_vector4" target="genosl" sourcecode="cos({{in}})" />
  <implementation name="IM_tan_vector4_genosl" nodedef="ND_tan_vector4" target="genosl" sourcecode="tan({{in}})" />
  <implementation name="IM_asin_vector4_genosl" nodedef="ND_asin_vector4" target="genosl" sourcecode="asin({{in}})" />
  <implementation name="IM_acos_vector4_genosl" nodedef="ND_acos_vector4" target="genosl" sourcecode="acos({{in}})" />
  <implementation name="IM_atan2_vector4_genosl" nodedef="ND_atan2_vector4" target="genosl" sourcecode="atan2({{iny}},{{inx}})" />

  <!-- <sqrt> -->
  <implementation name="IM_sqrt_float_genosl" nodedef="ND_sqrt_float" target="genosl" sourcecode="sqrt({{in}})" />
  <implementation name="IM_sqrt_vector2_genosl" nodedef="ND_sqrt_vector2" target="genosl" sourcecode="sqrt({{in}})" />
  <implementation name="IM_sqrt_vector3_genosl" nodedef="ND_sqrt_vector3" target="genosl" sourcecode="sqrt({{in}})" />
  <implementation name="IM_sqrt_vector4_genosl" nodedef="ND_sqrt_vector4" target="genosl" sourcecode="sqrt({{in}})" />

  <!-- <ln> -->
  <implementation name="IM_ln_float_genosl" nodedef="ND_ln_float" target="genosl" sourcecode="log({{in}})" />
  <implementation name="IM_ln_vector2_genosl" nodedef="ND_ln_vector2" target="genosl" sourcecode="log({{in}})" />
  <implementation name="IM_ln_vector3_genosl" nodedef="ND_ln_vector3" target="genosl" sourcecode="log({{in}})" />
  <implementation name="IM_ln_vector4_genosl" nodedef="ND_ln_vector4" target="genosl" sourcecode="log({{in}})" />

  <!-- <exp> -->
  <implementation name="IM_exp_float_genosl" nodedef="ND_exp_float" target="genosl" sourcecode="exp({{in}})" />
  <implementation name="IM_exp_vector2_genosl" nodedef="ND_exp_vector2" target="genosl" sourcecode="exp({{in}})" />
  <implementation name="IM_exp_vector3_genosl" nodedef="ND_exp_vector3" target="genosl" sourcecode="exp({{in}})" />
  <implementation name="IM_exp_vector4_genosl" nodedef="ND_exp_vector4" target="genosl" sourcecode="exp({{in}})" />

  <!-- sign -->
  <implementation name="IM_sign_float_genosl" nodedef="ND_sign_float" target="genosl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_color3_genosl" nodedef="ND_sign_color3" target="genosl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_color4_genosl" nodedef="ND_sign_color4" target="genosl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_vector2_genosl" nodedef="ND_sign_vector2" target="genosl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_vector3_genosl" nodedef="ND_sign_vector3" target="genosl" sourcecode="sign({{in}})" />
  <implementation name="IM_sign_vector4_genosl" nodedef="ND_sign_vector4" target="genosl" sourcecode="sign({{in}})" />

  <!-- <clamp> -->
  <implementation name="IM_clamp_float_genosl" nodedef="ND_clamp_float" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_color3_genosl" nodedef="ND_clamp_color3" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_color3FA_genosl" nodedef="ND_clamp_color3FA" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_color4_genosl" nodedef="ND_clamp_color4" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_color4FA_genosl" nodedef="ND_clamp_color4FA" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector2_genosl" nodedef="ND_clamp_vector2" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector2FA_genosl" nodedef="ND_clamp_vector2FA" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector3_genosl" nodedef="ND_clamp_vector3" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector3FA_genosl" nodedef="ND_clamp_vector3FA" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector4_genosl" nodedef="ND_clamp_vector4" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />
  <implementation name="IM_clamp_vector4FA_genosl" nodedef="ND_clamp_vector4FA" target="genosl" sourcecode="clamp({{in}}, {{low}}, {{high}})" />

  <!-- <min> -->
  <implementation name="IM_min_float_genosl" nodedef="ND_min_float" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_color3_genosl" nodedef="ND_min_color3" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_color3FA_genosl" nodedef="ND_min_color3FA" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_color4_genosl" nodedef="ND_min_color4" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_color4FA_genosl" nodedef="ND_min_color4FA" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector2_genosl" nodedef="ND_min_vector2" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector2FA_genosl" nodedef="ND_min_vector2FA" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector3_genosl" nodedef="ND_min_vector3" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector3FA_genosl" nodedef="ND_min_vector3FA" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector4_genosl" nodedef="ND_min_vector4" target="genosl" sourcecode="min({{in1}}, {{in2}})" />
  <implementation name="IM_min_vector4FA_genosl" nodedef="ND_min_vector4FA" target="genosl" sourcecode="min({{in1}}, {{in2}})" />

  <!-- <max> -->
  <implementation name="IM_max_float_genosl" nodedef="ND_max_float" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_color3_genosl" nodedef="ND_max_color3" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_color3FA_genosl" nodedef="ND_max_color3FA" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_color4_genosl" nodedef="ND_max_color4" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_color4FA_genosl" nodedef="ND_max_color4FA" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector2_genosl" nodedef="ND_max_vector2" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector2FA_genosl" nodedef="ND_max_vector2FA" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector3_genosl" nodedef="ND_max_vector3" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector3FA_genosl" nodedef="ND_max_vector3FA" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector4_genosl" nodedef="ND_max_vector4" target="genosl" sourcecode="max({{in1}}, {{in2}})" />
  <implementation name="IM_max_vector4FA_genosl" nodedef="ND_max_vector4FA" target="genosl" sourcecode="max({{in1}}, {{in2}})" />

  <!-- <normalize> -->
  <implementation name="IM_normalize_vector2_genosl" nodedef="ND_normalize_vector2" target="genosl" sourcecode="normalize({{in}})" />
  <implementation name="IM_normalize_vector3_genosl" nodedef="ND_normalize_vector3" target="genosl" sourcecode="normalize({{in}})" />
  <implementation name="IM_normalize_vector4_genosl" nodedef="ND_normalize_vector4" target="genosl" sourcecode="normalize({{in}})" />

  <!-- <magnitude> -->
  <implementation name="IM_magnitude_vector2_genosl" nodedef="ND_magnitude_vector2" target="genosl" sourcecode="length({{in}})" />
  <implementation name="IM_magnitude_vector3_genosl" nodedef="ND_magnitude_vector3" target="genosl" sourcecode="length({{in}})" />
  <implementation name="IM_magnitude_vector4_genosl" nodedef="ND_magnitude_vector4" target="genosl" sourcecode="length({{in}})" />

  <!-- <dotproduct> -->
  <implementation name="IM_dotproduct_vector2_genosl" nodedef="ND_dotproduct_vector2" target="genosl" sourcecode="dot({{in1}}, {{in2}})" />
  <implementation name="IM_dotproduct_vector3_genosl" nodedef="ND_dotproduct_vector3" target="genosl" sourcecode="dot({{in1}}, {{in2}})" />
  <implementation name="IM_dotproduct_vector4_genosl" nodedef="ND_dotproduct_vector4" target="genosl" sourcecode="dot({{in1}}, {{in2}})" />

  <!-- <crossproduct> -->
  <implementation name="IM_crossproduct_vector3_genosl" nodedef="ND_crossproduct_vector3" target="genosl" sourcecode="cross({{in1}}, {{in2}})" />

  <!-- <transformpoint> -->
  <implementation name="IM_transformpoint_vector3_genosl" nodedef="ND_transformpoint_vector3" target="genosl" sourcecode="transform({{fromspace}}, {{tospace}}, point({{in}}))" />

  <!-- <transformvector> -->
  <implementation name="IM_transformvector_vector3_genosl" nodedef="ND_transformvector_vector3" target="genosl" sourcecode="transform({{fromspace}}, {{tospace}}, {{in}})" />

  <!-- <transformnormal> -->
  <implementation name="IM_transformnormal_vector3_genosl" nodedef="ND_transformnormal_vector3" target="genosl" sourcecode="transform({{fromspace}}, {{tospace}}, normal({{in}}))" />

  <!-- <transformmatrix> -->
  <implementation name="IM_transformmatrix_vector2M3_genosl" nodedef="ND_transformmatrix_vector2M3" function="mx_transformmatrix_vector2M3" file="mx_transformmatrix_vector2M3.osl" target="genosl" />
  <implementation name="IM_transformmatrix_vector3_genosl" nodedef="ND_transformmatrix_vector3" target="genosl" sourcecode="transform({{mat}}, {{in}})" />
  <implementation name="IM_transformmatrix_vector3M4_genosl" nodedef="ND_transformmatrix_vector3M4" target="genosl" sourcecode="transform({{mat}}, {{in}})" />
  <implementation name="IM_transformmatrix_vector4_genosl" nodedef="ND_transformmatrix_vector4" target="genosl" sourcecode="transform({{mat}}, {{in}})" />

  <!-- <transpose> -->
  <implementation name="IM_transpose_matrix33_genosl" nodedef="ND_transpose_matrix33" target="genosl" sourcecode="transpose({{in}})" />
  <implementation name="IM_transpose_matrix44_genosl" nodedef="ND_transpose_matrix44" target="genosl" sourcecode="transpose({{in}})" />

  <!-- <determinant> -->
  <implementation name="IM_determinant_matrix33_genosl" nodedef="ND_determinant_matrix33" target="genosl" sourcecode="determinant({{in}})" />
  <implementation name="IM_determinant_matrix44_genosl" nodedef="ND_determinant_matrix44" target="genosl" sourcecode="determinant({{in}})" />

  <!-- <invertmatrix> -->
  <implementation name="IM_invertmatrix_matrix33_genosl" nodedef="ND_invertmatrix_matrix33" target="genosl" sourcecode="1 / {{in}}" />
  <implementation name="IM_invertmatrix_matrix44_genosl" nodedef="ND_invertmatrix_matrix44" target="genosl" sourcecode="1 / {{in}}" />

  <!-- <rotate2d> -->
  <implementation name="IM_rotate2d_vector2_genosl" nodedef="ND_rotate2d_vector2" file="mx_rotate_vector2.osl" function="mx_rotate_vector2" target="genosl" />

  <!-- <rotate3d> -->
  <implementation name="IM_rotate3d_vector3_genosl" nodedef="ND_rotate3d_vector3" file="mx_rotate_vector3.osl" function="mx_rotate_vector3" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Adjustment nodes                                                         -->
  <!-- ======================================================================== -->

  <!-- <remap> -->
  <implementation name="IM_remap_float_genosl" nodedef="ND_remap_float" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_color3_genosl" nodedef="ND_remap_color3" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_color3FA_genosl" nodedef="ND_remap_color3FA" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_color4_genosl" nodedef="ND_remap_color4" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_color4FA_genosl" nodedef="ND_remap_color4FA" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_vector2_genosl" nodedef="ND_remap_vector2" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_vector2FA_genosl" nodedef="ND_remap_vector2FA" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_vector3_genosl" nodedef="ND_remap_vector3" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_vector3FA_genosl" nodedef="ND_remap_vector3FA" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_vector4_genosl" nodedef="ND_remap_vector4" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />
  <implementation name="IM_remap_vector4FA_genosl" nodedef="ND_remap_vector4FA" target="genosl" sourcecode="mx_remap({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}}, 0)" />

  <!-- <smoothstep> -->
  <implementation name="IM_smoothstep_float_genosl" nodedef="ND_smoothstep_float" target="genosl" sourcecode="smoothstep({{low}}, {{high}}, {{in}})" />
  <implementation name="IM_smoothstep_vector2_genosl" nodedef="ND_smoothstep_vector2" target="genosl" sourcecode="smoothstep({{low}}, {{high}}, {{in}})" />
  <implementation name="IM_smoothstep_vector3_genosl" nodedef="ND_smoothstep_vector3" target="genosl" sourcecode="smoothstep({{low}}, {{high}}, {{in}})" />
  <implementation name="IM_smoothstep_vector4_genosl" nodedef="ND_smoothstep_vector4" target="genosl" sourcecode="smoothstep({{low}}, {{high}}, {{in}})" />

  <!-- <luminance> -->
  <implementation name="IM_luminance_color3_genosl" nodedef="ND_luminance_color3" file="mx_luminance_color3.osl" function="mx_luminance_color3" target="genosl" />
  <implementation name="IM_luminance_color4_genosl" nodedef="ND_luminance_color4" file="mx_luminance_color4.osl" function="mx_luminance_color4" target="genosl" />

  <!-- <rgbtohsv> -->
  <implementation name="IM_rgbtohsv_color3_genosl" nodedef="ND_rgbtohsv_color3" file="mx_rgbtohsv_color3.osl" function="mx_rgbtohsv_color3" target="genosl" />
  <implementation name="IM_rgbtohsv_color4_genosl" nodedef="ND_rgbtohsv_color4" file="mx_rgbtohsv_color4.osl" function="mx_rgbtohsv_color4" target="genosl" />

  <!-- <hsvtorgb> -->
  <implementation name="IM_hsvtorgb_color3_genosl" nodedef="ND_hsvtorgb_color3" file="mx_hsvtorgb_color3.osl" function="mx_hsvtorgb_color3" target="genosl" />
  <implementation name="IM_hsvtorgb_color4_genosl" nodedef="ND_hsvtorgb_color4" file="mx_hsvtorgb_color4.osl" function="mx_hsvtorgb_color4" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Compositing nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <premult> -->
  <implementation name="IM_premult_color4_genosl" nodedef="ND_premult_color4" file="mx_premult_color4.osl" function="mx_premult_color4" target="genosl" />

  <!-- <unpremult> -->
  <implementation name="IM_unpremult_color4_genosl" nodedef="ND_unpremult_color4" file="mx_unpremult_color4.osl" function="mx_unpremult_color4" target="genosl" />

  <!-- <plus> -->
  <implementation name="IM_plus_float_genosl" nodedef="ND_plus_float" target="genosl" sourcecode="({{mix}}*({{bg}} + {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_plus_color3_genosl" nodedef="ND_plus_color3" target="genosl" sourcecode="({{mix}}*({{bg}} + {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_plus_color4_genosl" nodedef="ND_plus_color4" target="genosl" sourcecode="({{mix}}*({{bg}} + {{fg}})) + ((1.0-{{mix}})*{{bg}})" />

  <!-- <minus> -->
  <implementation name="IM_minus_float_genosl" nodedef="ND_minus_float" target="genosl" sourcecode="({{mix}}*({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_minus_color3_genosl" nodedef="ND_minus_color3" target="genosl" sourcecode="({{mix}}*({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_minus_color4_genosl" nodedef="ND_minus_color4" target="genosl" sourcecode="({{mix}}*({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />

  <!-- <difference> -->
  <implementation name="IM_difference_float_genosl" nodedef="ND_difference_float" target="genosl" sourcecode="({{mix}}*abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_difference_color3_genosl" nodedef="ND_difference_color3" target="genosl" sourcecode="({{mix}}*abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_difference_color4_genosl" nodedef="ND_difference_color4" target="genosl" sourcecode="({{mix}}*abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" />

  <!-- <burn> -->
  <implementation name="IM_burn_float_genosl" nodedef="ND_burn_float" file="mx_burn_float.osl" function="mx_burn_float" target="genosl" />
  <implementation name="IM_burn_color3_genosl" nodedef="ND_burn_color3" file="mx_burn_color3.osl" function="mx_burn_color3" target="genosl" />
  <implementation name="IM_burn_color4_genosl" nodedef="ND_burn_color4" file="mx_burn_color4.osl" function="mx_burn_color4" target="genosl" />

  <!-- <dodge> -->
  <implementation name="IM_dodge_float_genosl" nodedef="ND_dodge_float" file="mx_dodge_float.osl" function="mx_dodge_float" target="genosl" />
  <implementation name="IM_dodge_color3_genosl" nodedef="ND_dodge_color3" file="mx_dodge_color3.osl" function="mx_dodge_color3" target="genosl" />
  <implementation name="IM_dodge_color4_genosl" nodedef="ND_dodge_color4" file="mx_dodge_color4.osl" function="mx_dodge_color4" target="genosl" />

  <!-- <screen> -->
  <implementation name="IM_screen_float_genosl" nodedef="ND_screen_float" target="genosl" sourcecode="({{mix}}*((1.0 - (1.0 - {{fg}}) * (1 - {{bg}})))) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_screen_color3_genosl" nodedef="ND_screen_color3" target="genosl" sourcecode="({{mix}}*((1.0 - (1.0 - {{fg}}) * (1 - {{bg}})))) + ((1.0-{{mix}})*{{bg}})" />
  <implementation name="IM_screen_color4_genosl" nodedef="ND_screen_color4" target="genosl" sourcecode="({{mix}}*((1.0 - (1.0 - {{fg}}) * (1 - {{bg}})))) + ((1.0-{{mix}})*{{bg}})" />

  <!-- <disjointover> -->
  <implementation name="IM_disjointover_color4_genosl" nodedef="ND_disjointover_color4" file="mx_disjointover_color4.osl" function="mx_disjointover_color4" target="genosl" />

  <!-- <in> -->
  <implementation name="IM_in_color4_genosl" nodedef="ND_in_color4" target="genosl" sourcecode="({{fg}}*{{bg}}.a  * {{mix}}) + ({{bg}} * (1.0-{{mix}}))" />

  <!-- <mask> -->
  <implementation name="IM_mask_color4_genosl" nodedef="ND_mask_color4" target="genosl" sourcecode="({{bg}}*{{fg}}.a  * {{mix}}) + ({{bg}} * (1.0-{{mix}}));" />

  <!-- <matte> -->
  <implementation name="IM_matte_color4_genosl" nodedef="ND_matte_color4" target="genosl" sourcecode="color4({{fg}}.rgb*{{fg}}.a + {{bg}}.rgb*(1.0-{{fg}}.a), {{fg}}.a + ({{bg}}.a*(1.0-{{fg}}.a)) ) * {{mix}} + ({{bg}} * (1.0-{{mix}}))" />

  <!-- <out> -->
  <implementation name="IM_out_color4_genosl" nodedef="ND_out_color4" target="genosl" sourcecode="({{fg}}*(1.0-{{bg}}.a)  * {{mix}}) + ({{bg}} * (1.0-{{mix}}))" />

  <!-- <over> -->
  <implementation name="IM_over_color4_genosl" nodedef="ND_over_color4" target="genosl" sourcecode="({{fg}} + ({{bg}}*(1.0-{{fg}}.a))) * {{mix}} + {{bg}} * (1.0-{{mix}})" />

  <!-- <inside> -->
  <implementation name="IM_inside_float_genosl" nodedef="ND_inside_float" target="genosl" sourcecode="{{in}} * {{mask}}" />
  <implementation name="IM_inside_color3_genosl" nodedef="ND_inside_color3" target="genosl" sourcecode="{{in}} * {{mask}}" />
  <implementation name="IM_inside_color4_genosl" nodedef="ND_inside_color4" target="genosl" sourcecode="{{in}} * {{mask}}" />

  <!-- <outside> -->
  <implementation name="IM_outside_float_genosl" nodedef="ND_outside_float" target="genosl" sourcecode="{{in}} * (1.0 - {{mask}})" />
  <implementation name="IM_outside_color3_genosl" nodedef="ND_outside_color3" target="genosl" sourcecode="{{in}} * (1.0 - {{mask}})" />
  <implementation name="IM_outside_color4_genosl" nodedef="ND_outside_color4" target="genosl" sourcecode="{{in}} * (1.0 - {{mask}})" />

  <!-- <mix> -->
  <implementation name="IM_mix_float_genosl" nodedef="ND_mix_float" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_color3_genosl" nodedef="ND_mix_color3" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_color3_color3_genosl" nodedef="ND_mix_color3_color3" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_color4_genosl" nodedef="ND_mix_color4" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_color4_color4_genosl" nodedef="ND_mix_color4_color4" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector2_genosl" nodedef="ND_mix_vector2" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector2_vector2_genosl" nodedef="ND_mix_vector2_vector2" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector3_genosl" nodedef="ND_mix_vector3" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector3_vector3_genosl" nodedef="ND_mix_vector3_vector3" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector4_genosl" nodedef="ND_mix_vector4" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_vector4_vector4_genosl" nodedef="ND_mix_vector4_vector4" target="genosl" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" />
  <implementation name="IM_mix_surfaceshader_genosl" nodedef="ND_mix_surfaceshader" file="mx_mix_surfaceshader.osl" function="mx_mix_surfaceshader" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Conditional nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <ifgreater> -->
  <implementation name="IM_ifgreater_float_genosl" nodedef="ND_ifgreater_float" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_integer_genosl" nodedef="ND_ifgreater_integer" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_color3_genosl" nodedef="ND_ifgreater_color3" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_color4_genosl" nodedef="ND_ifgreater_color4" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_vector2_genosl" nodedef="ND_ifgreater_vector2" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_vector3_genosl" nodedef="ND_ifgreater_vector3" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_vector4_genosl" nodedef="ND_ifgreater_vector4" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_matrix33_genosl" nodedef="ND_ifgreater_matrix33" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_matrix44_genosl" nodedef="ND_ifgreater_matrix44" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_boolean_genosl" nodedef="ND_ifgreater_boolean" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, 1, 0)" />
  <implementation name="IM_ifgreater_floatI_genosl" nodedef="ND_ifgreater_floatI" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_integerI_genosl" nodedef="ND_ifgreater_integerI" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_color3I_genosl" nodedef="ND_ifgreater_color3I" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_color4I_genosl" nodedef="ND_ifgreater_color4I" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_vector2I_genosl" nodedef="ND_ifgreater_vector2I" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_vector3I_genosl" nodedef="ND_ifgreater_vector3I" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_vector4I_genosl" nodedef="ND_ifgreater_vector4I" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_matrix33I_genosl" nodedef="ND_ifgreater_matrix33I" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_matrix44I_genosl" nodedef="ND_ifgreater_matrix44I" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreater_booleanI_genosl" nodedef="ND_ifgreater_booleanI" target="genosl" sourcecode="mx_ternary({{value1}} > {{value2}}, 1, 0)" />

  <!-- <ifgreatereq> -->
  <implementation name="IM_ifgreatereq_float_genosl" nodedef="ND_ifgreatereq_float" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_integer_genosl" nodedef="ND_ifgreatereq_integer" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_color3_genosl" nodedef="ND_ifgreatereq_color3" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_color4_genosl" nodedef="ND_ifgreatereq_color4" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_vector2_genosl" nodedef="ND_ifgreatereq_vector2" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_vector3_genosl" nodedef="ND_ifgreatereq_vector3" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_vector4_genosl" nodedef="ND_ifgreatereq_vector4" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_matrix33_genosl" nodedef="ND_ifgreatereq_matrix33" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_matrix44_genosl" nodedef="ND_ifgreatereq_matrix44" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_boolean_genosl" nodedef="ND_ifgreatereq_boolean" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, 1, 0)" />
  <implementation name="IM_ifgreatereq_floatI_genosl" nodedef="ND_ifgreatereq_floatI" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_integerI_genosl" nodedef="ND_ifgreatereq_integerI" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_color3I_genosl" nodedef="ND_ifgreatereq_color3I" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_color4I_genosl" nodedef="ND_ifgreatereq_color4I" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_vector2I_genosl" nodedef="ND_ifgreatereq_vector2I" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_vector3I_genosl" nodedef="ND_ifgreatereq_vector3I" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_vector4I_genosl" nodedef="ND_ifgreatereq_vector4I" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_matrix33I_genosl" nodedef="ND_ifgreatereq_matrix33I" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_matrix44I_genosl" nodedef="ND_ifgreatereq_matrix44I" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifgreatereq_booleanI_genosl" nodedef="ND_ifgreatereq_booleanI" target="genosl" sourcecode="mx_ternary({{value1}} >= {{value2}}, 1, 0)" />

  <!-- <ifequal> -->
  <implementation name="IM_ifequal_float_genosl" nodedef="ND_ifequal_float" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_integer_genosl" nodedef="ND_ifequal_integer" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_color3_genosl" nodedef="ND_ifequal_color3" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_color4_genosl" nodedef="ND_ifequal_color4" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector2_genosl" nodedef="ND_ifequal_vector2" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector3_genosl" nodedef="ND_ifequal_vector3" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector4_genosl" nodedef="ND_ifequal_vector4" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_matrix33_genosl" nodedef="ND_ifequal_matrix33" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_matrix44_genosl" nodedef="ND_ifequal_matrix44" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_boolean_genosl" nodedef="ND_ifequal_boolean" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, 1, 0)" />
  <implementation name="IM_ifequal_floatI_genosl" nodedef="ND_ifequal_floatI" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_integerI_genosl" nodedef="ND_ifequal_integerI" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_color3I_genosl" nodedef="ND_ifequal_color3I" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_color4I_genosl" nodedef="ND_ifequal_color4I" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector2I_genosl" nodedef="ND_ifequal_vector2I" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector3I_genosl" nodedef="ND_ifequal_vector3I" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector4I_genosl" nodedef="ND_ifequal_vector4I" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_matrix33I_genosl" nodedef="ND_ifequal_matrix33I" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_matrix44I_genosl" nodedef="ND_ifequal_matrix44I" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_booleanI_genosl" nodedef="ND_ifequal_booleanI" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, 1, 0)" />
  <implementation name="IM_ifequal_floatB_genosl" nodedef="ND_ifequal_floatB" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_integerB_genosl" nodedef="ND_ifequal_integerB" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_color3B_genosl" nodedef="ND_ifequal_color3B" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_color4B_genosl" nodedef="ND_ifequal_color4B" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector2B_genosl" nodedef="ND_ifequal_vector2B" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector3B_genosl" nodedef="ND_ifequal_vector3B" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_vector4B_genosl" nodedef="ND_ifequal_vector4B" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_matrix33B_genosl" nodedef="ND_ifequal_matrix33B" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_matrix44B_genosl" nodedef="ND_ifequal_matrix44B" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}})" />
  <implementation name="IM_ifequal_booleanB_genosl" nodedef="ND_ifequal_booleanB" target="genosl" sourcecode="mx_ternary({{value1}} == {{value2}}, 1, 0)" />

  <!-- ======================================================================== -->
  <!-- Channel nodes                                                            -->
  <!-- ======================================================================== -->

  <!-- <convert> -->
  <implementation name="IM_convert_boolean_float_genosl" nodedef="ND_convert_boolean_float" target="genosl" sourcecode="float({{in}})" />
  <implementation name="IM_convert_integer_float_genosl" nodedef="ND_convert_integer_float" target="genosl" sourcecode="float({{in}})" />

  <!-- <combine2> -->
  <implementation name="IM_combine2_vector2_genosl" nodedef="ND_combine2_vector2" target="genosl" sourcecode="{ {{in1}},{{in2}} }" />
  <implementation name="IM_combine2_color4CF_genosl" nodedef="ND_combine2_color4CF" target="genosl" sourcecode="{ color({{in1}}[0],{{in1}}[1],{{in1}}[2]),{{in2}} }" />
  <implementation name="IM_combine2_vector4VF_genosl" nodedef="ND_combine2_vector4VF" target="genosl" sourcecode="{ {{in1}}[0],{{in1}}[1],{{in1}}[2],{{in2}} }" />
  <implementation name="IM_combine2_vector4VV_genosl" nodedef="ND_combine2_vector4VV" target="genosl" sourcecode="{ {{in1}}.x,{{in1}}.y,{{in2}}.x,{{in2}}.y }" />

  <!-- <combine3> -->
  <implementation name="IM_combine3_color3_genosl" nodedef="ND_combine3_color3" target="genosl" sourcecode="color( {{in1}},{{in2}},{{in3}} )" />
  <implementation name="IM_combine3_vector3_genosl" nodedef="ND_combine3_vector3" target="genosl" sourcecode="vector( {{in1}},{{in2}},{{in3}} )" />

  <!-- <combine4> -->
  <implementation name="IM_combine4_color4_genosl" nodedef="ND_combine4_color4" target="genosl" sourcecode="{ color({{in1}},{{in2}},{{in3}}),{{in4}} }" />
  <implementation name="IM_combine4_vector4_genosl" nodedef="ND_combine4_vector4" target="genosl" sourcecode="{ {{in1}},{{in2}},{{in3}},{{in4}} }" />

  <!-- <creatematrix> -->
  <implementation name="IM_creatematrix_vector3_matrix33_genosl" nodedef="ND_creatematrix_vector3_matrix33" file="mx_creatematrix.osl" function="mx_creatematrix_vector3_matrix33" target="genosl" />
  <implementation name="IM_creatematrix_vector3_matrix44_genosl" nodedef="ND_creatematrix_vector3_matrix44" file="mx_creatematrix.osl" function="mx_creatematrix_vector3_matrix44" target="genosl" />
  <implementation name="IM_creatematrix_vector4_matrix44_genosl" nodedef="ND_creatematrix_vector4_matrix44" file="mx_creatematrix.osl" function="mx_creatematrix_vector4_matrix44" target="genosl" />

  <!-- <extract> -->
  <implementation name="IM_extract_color3_genosl" nodedef="ND_extract_color3" sourcecode="mx_extract({{in}}, {{index}})" target="genosl" />
  <implementation name="IM_extract_color4_genosl" nodedef="ND_extract_color4" sourcecode="mx_extract({{in}}, {{index}})" target="genosl" />
  <implementation name="IM_extract_vector2_genosl" nodedef="ND_extract_vector2" sourcecode="mx_extract({{in}}, {{index}})" target="genosl" />
  <implementation name="IM_extract_vector3_genosl" nodedef="ND_extract_vector3" sourcecode="mx_extract({{in}}, {{index}})" target="genosl" />
  <implementation name="IM_extract_vector4_genosl" nodedef="ND_extract_vector4" sourcecode="mx_extract({{in}}, {{index}})" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Convolution nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <blur> -->
  <implementation name="IM_blur_float_genosl" nodedef="ND_blur_float" target="genosl" />
  <implementation name="IM_blur_color3_genosl" nodedef="ND_blur_color3" target="genosl" />
  <implementation name="IM_blur_color4_genosl" nodedef="ND_blur_color4" target="genosl" />
  <implementation name="IM_blur_vector2_genosl" nodedef="ND_blur_vector2" target="genosl" />
  <implementation name="IM_blur_vector3_genosl" nodedef="ND_blur_vector3" target="genosl" />
  <implementation name="IM_blur_vector4_genosl" nodedef="ND_blur_vector4" target="genosl" />

  <!-- <heighttonormal> -->
  <implementation name="IM_heighttonormal_vector3_genosl" nodedef="ND_heighttonormal_vector3" file="mx_heighttonormal_vector3.osl" function="mx_heighttonormal_vector3" target="genosl" />

  <!-- ======================================================================== -->
  <!-- Logical operator nodes                                                   -->
  <!-- ======================================================================== -->

  <implementation name="IM_logical_and_genosl" nodedef="ND_logical_and" target="genosl" sourcecode="{{in1}} && {{in2}}"/>
  <implementation name="IM_logical_or_genosl" nodedef="ND_logical_or" target="genosl" sourcecode="{{in1}} || {{in2}}"/>
  <implementation name="IM_logical_not_genosl" nodedef="ND_logical_not" target="genosl" sourcecode="!{{in}}"/>

  <!-- ======================================================================== -->
  <!-- Organization nodes                                                       -->
  <!-- ======================================================================== -->

  <!-- <dot> -->
  <implementation name="IM_dot_float_genosl" nodedef="ND_dot_float" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_color3_genosl" nodedef="ND_dot_color3" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_color4_genosl" nodedef="ND_dot_color4" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_vector2_genosl" nodedef="ND_dot_vector2" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_vector3_genosl" nodedef="ND_dot_vector3" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_vector4_genosl" nodedef="ND_dot_vector4" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_boolean_genosl" nodedef="ND_dot_boolean" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_integer_genosl" nodedef="ND_dot_integer" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_matrix33_genosl" nodedef="ND_dot_matrix33" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_matrix44_genosl" nodedef="ND_dot_matrix44" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_string_genosl" nodedef="ND_dot_string" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_filename_genosl" nodedef="ND_dot_filename" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_surfaceshader_genosl" nodedef="ND_dot_surfaceshader" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_displacementshader_genosl" nodedef="ND_dot_displacementshader" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_volumeshader_genosl" nodedef="ND_dot_volumeshader" target="genosl" sourcecode="{{in}}" />
  <implementation name="IM_dot_lightshader_genosl" nodedef="ND_dot_lightshader" target="genosl" sourcecode="{{in}}" />
</materialx>
void mx_mix_surfaceshader(surfaceshader fg, surfaceshader bg, float w, output surfaceshader result)
{
    result.bsdf = mix(bg.bsdf, fg.bsdf, w);
    result.edf = mix(bg.edf, fg.edf, w);
    result.opacity = mix(bg.opacity, fg.opacity, w);
}
void mx_fractal3d_vector4(vector4 amplitude, int octaves, float lacunarity, float diminish, vector position, output vector4 result)
{
    vector4 f = mx_fbm(position, octaves, lacunarity, diminish, "snoise");
    result = f * amplitude;
}
void mx_geomcolor_float(int index, output float result)
{
    getattribute("color", result);
}
// Copyright Contributors to the Open Shading Language project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage

#pragma once
#define COLOR4_H


// color4 is a color + alpha
struct color4
{
    color rgb;
    float a;
};



//
// For color4, define math operators to match color
//

color4 __operator__neg__(color4 a)
{
    return color4(-a.rgb, -a.a);
}

color4 __operator__add__(color4 a, color4 b)
{
    return color4(a.rgb + b.rgb, a.a + b.a);
}

color4 __operator__add__(color4 a, int b)
{
    return a + color4(color(b), b);
}

color4 __operator__add__(color4 a, float b)
{
    return a + color4(color(b), b);
}

color4 __operator__add__(int a, color4 b)
{
    return color4(color(a), a) + b;
}

color4 __operator__add__(float a, color4 b)
{
    return color4(color(a), a) + b;
}

color4 __operator__sub__(color4 a, color4 b)
{
    return color4(a.rgb - b.rgb, a.a - b.a);
}

color4 __operator__sub__(color4 a, int b)
{
    return a - color4(color(b), b);
}

color4 __operator__sub__(color4 a, float b)
{
    return a - color4(color(b), b);
}

color4 __operator__sub__(int a, color4 b)
{
    return color4(color(a), a) - b;
}

color4 __operator__sub__(float a, color4 b)
{
    return color4(color(a), a) - b;
}

color4 __operator__mul__(color4 a, color4 b)
{
    return color4(a.rgb * b.rgb, a.a * b.a);
}

color4 __operator__mul__(color4 a, int b)
{
    return a * color4(color(b), b);
}

color4 __operator__mul__(color4 a, float b)
{
    return a * color4(color(b), b);
}

color4 __operator__mul__(int a, color4 b)
{
    return color4(color(a), a) * b;
}

color4 __operator__mul__(float a, color4 b)
{
    return color4(color(a), a) * b;
}

color4 __operator__div__(color4 a, color4 b)
{
    return color4(a.rgb / b.rgb, a.a / b.a);
}

color4 __operator__div__(color4 a, int b)
{
    float b_inv = 1.0 / float(b);
    return a * color4(color(b_inv), b_inv);
}

color4 __operator__div__(color4 a, float b)
{
    float b_inv = 1.0 / b;
    return a * color4(color(b_inv), b_inv);
}

color4 __operator_div__(int a, color4 b)
{
    return color4(color(a), a) / b;
}

color4 __operator__div__(float a, color4 b)
{
    return color4(color(a), a) / b;
}

int __operator__eq__(color4 a, color4 b)
{
    return (a.rgb == b.rgb) && (a.a == b.a);
}

int __operator__neq__(color4 a, color4 b)
{
    return (a.rgb != b.rgb) || (a.a != b.a);
}



//
// For color4, define most of the stdosl functions to match color
//

color4 abs(color4 a)
{
    return color4(abs(a.rgb), abs(a.a));
}

color4 ceil(color4 a)
{
    return color4(ceil(a.rgb), ceil(a.a));
}

color4 round(color4 a)
{
    return color4(round(a.rgb), round(a.a));
}

color4 floor(color4 a)
{
    return color4(floor(a.rgb), floor(a.a));
}

color4 sqrt(color4 a)
{
    return color4(sqrt(a.rgb), sqrt(a.a));
}

color4 exp(color4 a)
{
    return color4(exp(a.rgb), exp(a.a));
}

color4 log(color4 a)
{
    return color4(log(a.rgb), log(a.a));
}

color4 log2(color4 a)
{
    return color4(log2(a.rgb), log2(a.a));
}

color4 mix(color4 a, color4 b, float x )
{
    return color4(mix(a.rgb, b.rgb, x),
                  mix(a.a, b.a, x));
}

color4 mix(color4 a, color4 b, color4 x )
{
    return color4(mix(a.rgb, b.rgb, x.rgb),
                  mix(a.a, b.a, x.a));
}

color4 smoothstep(color4 edge0, color4 edge1, color4 c)
{
    return color4(smoothstep(edge0.rgb, edge1.rgb, c.rgb),
                  smoothstep(edge0.a, edge1.a, c.a));
}

color4 smoothstep(float edge0, float edge1, color4 c)
{
    return smoothstep(color4(color(edge0), edge0), color4(color(edge1), edge1), c);
}

color4 clamp(color4 c, color4 minval, color4 maxval)
{
    return color4(clamp(c.rgb, minval.rgb, maxval.rgb),
                  clamp(c.a, minval.a, maxval.a));
}

color4 clamp(color4 c, float minval, float maxval)
{
    return clamp(c, color4(color(minval), minval), color4(color(maxval), maxval));
}

color4 max(color4 a, color4 b)
{
    return color4(max(a.rgb, b.rgb),
                  max(a.a, b.a));
}

color4 max(color4 a, float b)
{
    return color4(max(a.rgb, b),
                  max(a.a, b));
}

color4 min(color4 a, color4 b)
{
    return color4(min(a.rgb, b.rgb),
                  min(a.a, b.a));
}

color4 min(color4 a, float b)
{
    return color4(min(a.rgb, b),
                  min(a.a, b));
}

color4 mod(color4 a, color4 b)
{
    return color4(mod(a.rgb, b.rgb),
                  mod(a.a, b.a));
}

color4 mod(color4 a, float b)
{
    return mod(a, color4(color(b), b));
}

color4 fmod(color4 a, color4 b)
{
    return color4(fmod(a.rgb, b.rgb),
                  fmod(a.a, b.a));
}

color4 fmod(color4 a, int b)
{
    return fmod(a, color4(color(b), b));
}

color4 fmod(color4 a, float b)
{
    return fmod(a, color4(color(b), b));
}

color4 pow(color4 base, color4 power)
{
    return color4(pow(base.rgb, power.rgb), pow(base.a, power.a));
}

color4 pow(color4 base, float power)
{
    return pow(base, color4(color(power), power));
}

color4 sign(color4 a)
{
    return color4(sign(a.rgb),
                  sign(a.a));
}

color4 sin(color4 a)
{
    return color4(sin(a.rgb),
                  sin(a.a));
}

color4 cos(color4 a)
{
    return color4(cos(a.rgb),
                  cos(a.a));
}

color4 tan(color4 a)
{
    return color4(tan(a.rgb),
                  tan(a.a));
}

color4 asin(color4 a)
{
    return color4(asin(a.rgb),
                  asin(a.a));
}

color4 acos(color4 a)
{
    return color4(acos(a.rgb),
                  acos(a.a));
}

color4 atan2(color4 a, float f)
{
    return color4(atan2(a.rgb, f),
                  atan2(a.a, f));
}

color4 atan2(color4 a, color4 b)
{
    return color4(atan2(a.rgb, b.rgb),
                  atan2(a.a, b.a));
}


color4 transformc (string fromspace, string tospace, color4 C)
{
    return color4 (transformc (fromspace, tospace, C.rgb), C.a);
}
// Copyright Contributors to the Open Shading Language project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage

#pragma once
#define VECTOR2_H

// vector2 is a 2D vector
struct vector2
{
    float x;
    float y;
};



//
// For vector2, define math operators to match vector
//

vector2 __operator__neg__(vector2 a)
{
    return vector2(-a.x, -a.y);
}

vector2 __operator__add__(vector2 a, vector2 b)
{
    return vector2(a.x + b.x, a.y + b.y);
}

vector2 __operator__add__(vector2 a, int b)
{
    return a + vector2(b, b);
}

vector2 __operator__add__(vector2 a, float b)
{
    return a + vector2(b, b);
}

vector2 __operator__add__(int a, vector2 b)
{
    return vector2(a, a) + b;
}

vector2 __operator__add__(float a, vector2 b)
{
    return vector2(a, a) + b;
}

vector2 __operator__sub__(vector2 a, vector2 b)
{
    return vector2(a.x - b.x, a.y - b.y);
}

vector2 __operator__sub__(vector2 a, int b)
{
    return a - vector2(b, b);
}

vector2 __operator__sub__(vector2 a, float b)
{
    return a - vector2(b, b);
}

vector2 __operator__sub__(int a, vector2 b)
{
    return vector2(a, a) - b;
}

vector2 __operator__sub__(float a, vector2 b)
{
    return vector2(a, a) - b;
}

vector2 __operator__mul__(vector2 a, vector2 b)
{
    return vector2(a.x * b.x, a.y * b.y);
}

vector2 __operator__mul__(vector2 a, int b)
{
    return a * vector2(b, b);
}

vector2 __operator__mul__(vector2 a, float b)
{
    return a * vector2(b, b);
}

vector2 __operator__mul__(int a, vector2 b)
{
    return b * vector2(a, a);
}

vector2 __operator__mul__(float a, vector2 b)
{
    return b * vector2(a, a);
}

vector2 __operator__div__(vector2 a, vector2 b)
{
    return vector2(a.x / b.x, a.y / b.y);
}

vector2 __operator__div__(vector2 a, int b)
{
    float b_inv = 1.0 / float(b);
    return a * vector2(b_inv, b_inv);
}

vector2 __operator__div__(vector2 a, float b)
{
    float b_inv = 1.0 / b;
    return a * vector2(b_inv, b_inv);
}

vector2 __operator__div__(int a, vector2 b)
{
    return vector2(a, a) / b;
}

vector2 __operator__div__(float a, vector2 b)
{
    return vector2(a, a) / b;
}

int __operator__eq__(vector2 a, vector2 b)
{
    return (a.x == b.x) && (a.y == b.y);
}

int __operator__neq__(vector2 a, vector2 b)
{
    return (a.x != b.x) || (a.y != b.y);
}




//
// For vector2, define most of the stdosl functions to match vector
//

vector2 abs(vector2 a)
{
    return vector2 (abs(a.x), abs(a.y));
}

vector2 ceil(vector2 a)
{
    return vector2 (ceil(a.x), ceil(a.y));
}

vector2 round(vector2 a)
{
    return vector2 (round(a.x), round(a.y));
}

vector2 floor(vector2 a)
{
    return vector2 (floor(a.x), floor(a.y));
}

vector2 sqrt(vector2 a)
{
    return vector2 (sqrt(a.x), sqrt(a.y));
}

vector2 exp(vector2 a)
{
    return vector2 (exp(a.x), exp(a.y));
}

vector2 log(vector2 a)
{
    return vector2 (log(a.x), log(a.y));
}

vector2 log2(vector2 a)
{
    return vector2 (log2(a.x), log2(a.y));
}

vector2 mix(vector2 a, vector2 b, float x )
{
    return vector2 (mix(a.x, b.x, x), mix(a.y, b.y, x));
}

vector2 mix(vector2 a, vector2 b, vector2 x )
{
    return vector2 (mix(a.x, b.x, x.x), mix(a.y, b.y, x.y));
}

float dot(vector2 a, vector2 b)
{
    return (a.x * b.x + a.y * b.y);
}

float length (vector2 a)
{
    return hypot (a.x, a.y);
}

vector2 smoothstep(vector2 low, vector2 high, vector2 in)
{
    return vector2 (smoothstep(low.x, high.x, in.x),
                    smoothstep(low.y, high.y, in.y));
}

vector2 smoothstep(float low, float high, vector2 in)
{
    return vector2 (smoothstep(low, high, in.x),
                    smoothstep(low, high, in.y));
}

vector2 clamp(vector2 in, vector2 low, vector2 high)
{
    return vector2 (clamp(in.x, low.x, high.x),
                    clamp(in.y, low.y, high.y));
}

vector2 clamp(vector2 in, float low, float high)
{
    return clamp(in, vector2(low, low), vector2(high, high));
}

vector2 max(vector2 a, vector2 b)
{
    return vector2 (max(a.x, b.x),
                    max(a.y, b.y));
}

vector2 min(vector2 a, vector2 b)
{
    return vector2 (min(a.x, b.x),
                    min(a.y, b.y));
}

vector2 min(vector2 a, float b)
{
    return min(a, vector2(b, b));
}

vector2 max(vector2 a, float b)
{
    return max(a, vector2(b, b));
}

vector2 normalize(vector2 a)
{
    return a / length(a);
}

vector2 mod(vector2 a, vector2 b)
{
    return vector2(mod(a.x, b.x),
                   mod(a.y, b.y));
}

vector2 mod(vector2 a, float b)
{
    return mod(a, vector2(b, b));
}

vector2 fmod(vector2 a, vector2 b)
{
    return vector2 (fmod(a.x, b.x),
                    fmod(a.y, b.y));
}

vector2 fmod(vector2 a, float b)
{
    return fmod(a, vector2(b, b));
}

vector2 pow(vector2 in, vector2 amount)
{
    return vector2(pow(in.x, amount.x), pow(in.y, amount.y));
}

vector2 pow(vector2 in, float amount)
{
    return pow(in, vector2(amount, amount));
}

vector2 sign(vector2 a)
{
    return vector2(sign(a.x),
                   sign(a.y));
}

vector2 sin(vector2 a)
{
    return vector2(sin(a.x),
                   sin(a.y));
}

vector2 cos(vector2 a)
{
    return vector2(cos(a.x),
                   cos(a.y));
}

vector2 tan(vector2 a)
{
    return vector2(tan(a.x),
                   tan(a.y));
}

vector2 asin(vector2 a)
{
    return vector2(asin(a.x),
                   asin(a.y));
}

vector2 acos(vector2 a)
{
    return vector2(acos(a.x),
                   acos(a.y));
}

vector2 atan2(vector2 a, float f)
{
    return vector2(atan2(a.x, f),
                   atan2(a.y, f));
}

vector2 atan2(vector2 a, vector2 b)
{
    return vector2(atan2(a.x, b.x),
                   atan2(a.y, b.y));
}
// Copyright Contributors to the Open Shading Language project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage

#pragma once
#define VECTOR4_H


// vector4 is a 4D vector
struct vector4
{
    float x;
    float y;
    float z;
    float w;
};



//
// For vector4, define math operators to match vector
//

vector4 __operator__neg__(vector4 a)
{
    return vector4(-a.x, -a.y, -a.z, -a.w);
}

vector4 __operator__add__(vector4 a, vector4 b)
{
    return vector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
}

vector4 __operator__add__(vector4 a, int b)
{
    return a + vector4(b, b, b, b);
}

vector4 __operator__add__(vector4 a, float b)
{
    return a + vector4(b, b, b, b);
}

vector4 __operator__add__(int a, vector4 b)
{
    return vector4(a, a, a, a) + b;
}

vector4 __operator__add__(float a, vector4 b)
{
    return vector4(a, a, a, a) + b;
}

vector4 __operator__sub__(vector4 a, vector4 b)
{
    return vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
}

vector4 __operator__sub__(vector4 a, int b)
{
    return a - vector4(b, b, b, b);
}

vector4 __operator__sub__(vector4 a, float b)
{
    return a - vector4(b, b, b, b);
}

vector4 __operator__sub__(int a, vector4 b)
{
    return vector4(a, a, a, a) - b;
}

vector4 __operator__sub__(float a, vector4 b)
{
    return vector4(a, a, a, a) - b;
}

vector4 __operator__mul__(vector4 a, vector4 b)
{
    return vector4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
}

vector4 __operator__mul__(vector4 a, int b)
{
    return a * vector4(b, b, b, b);
}

vector4 __operator__mul__(vector4 a, float b)
{
    return a * vector4(b, b, b, b);
}

vector4 __operator__mul__(int a, vector4 b)
{
    return vector4(a, a, a, a) * b;
}

vector4 __operator__mul__(float a, vector4 b)
{
    return vector4(a, a, a, a) * b;
}

vector4 __operator__div__(vector4 a, vector4 b)
{
    return vector4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
}

vector4 __operator__div__(vector4 a, int b)
{
    float b_inv = 1.0 / float(b);
    return a * vector4(b_inv, b_inv, b_inv, b_inv);
}

vector4 __operator__div__(vector4 a, float b)
{
    float b_inv = 1.0 / b;
    return a * vector4(b_inv, b_inv, b_inv, b_inv);
}

vector4 __operator__div__(int a, vector4 b)
{
    return vector4(a, a, a, a) / b;
}

vector4 __operator__div__(float a, vector4 b)
{
    return vector4(a, a, a, a) / b;
}

int __operator__eq__(vector4 a, vector4 b)
{
    return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w);
}

int __operator__neq__(vector4 a, vector4 b)
{
    return (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w);
}




//
// For vector4, define most of the stdosl functions to match vector
//

vector4 abs(vector4 in)
{
    return vector4 (abs(in.x),
                    abs(in.y),
                    abs(in.z),
                    abs(in.w));
}

vector4 ceil(vector4 in)
{
    return vector4 (ceil(in.x),
                    ceil(in.y),
                    ceil(in.z),
                    ceil(in.w));
}

vector4 round(vector4 in)
{
    return vector4 (round(in.x),
                    round(in.y),
                    round(in.z),
                    round(in.w));
}

vector4 floor(vector4 in)
{
    return vector4 (floor(in.x),
                    floor(in.y),
                    floor(in.z),
                    floor(in.w));
}

vector4 sqrt(vector4 in)
{
    return vector4 (sqrt(in.x),
                    sqrt(in.y),
                    sqrt(in.z),
                    sqrt(in.w));
}

vector4 exp(vector4 in)
{
    return vector4 (exp(in.x),
                    exp(in.y),
                    exp(in.z),
                    exp(in.w));
}

vector4 log(vector4 in)
{
    return vector4 (log(in.x),
                    log(in.y),
                    log(in.z),
                    log(in.w));
}

vector4 log2(vector4 in)
{
    return vector4 (log2(in.x),
                    log2(in.y),
                    log2(in.z),
                    log2(in.w));
}

vector4 mix(vector4 value1, vector4 value2, float x )
{
    return vector4 (mix( value1.x, value2.x, x),
                    mix( value1.y, value2.y, x),
                    mix( value1.z, value2.z, x),
                    mix( value1.w, value2.w, x));
}

vector4 mix(vector4 value1, vector4 value2, vector4 x )
{
    return vector4 (mix( value1.x, value2.x, x.x),
                    mix( value1.y, value2.y, x.y),
                    mix( value1.z, value2.z, x.z),
                    mix( value1.w, value2.w, x.w));
}

vector vec4ToVec3(vector4 v)
{
    return vector(v.x, v.y, v.z) / v.w;
}

float dot(vector4 a, vector4 b)
{
    return ((a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w));
}

float length (vector4 a)
{
    return sqrt (a.x*a.x + a.y*a.y + a.z*a.z + a.w*a.w);
}

vector4 smoothstep(vector4 low, vector4 high, vector4 in)
{
    return vector4 (smoothstep(low.x, high.x, in.x),
                    smoothstep(low.y, high.y, in.y),
                    smoothstep(low.z, high.z, in.z),
                    smoothstep(low.w, high.w, in.w));
}

vector4 smoothstep(float low, float high, vector4 in)
{
    return vector4 (smoothstep(low, high, in.x),
                    smoothstep(low, high, in.y),
                    smoothstep(low, high, in.z),
                    smoothstep(low, high, in.w));
}

vector4 clamp(vector4 in, vector4 low, vector4 high)
{
    return vector4 (clamp(in.x, low.x, high.x),
                    clamp(in.y, low.y, high.y),
                    clamp(in.z, low.z, high.z),
                    clamp(in.w, low.w, high.w));
}

vector4 clamp(vector4 in, float low, float high)
{
    return vector4 (clamp(in.x, low, high),
                    clamp(in.y, low, high),
                    clamp(in.z, low, high),
                    clamp(in.w, low, high));
}

vector4 max(vector4 a, vector4 b)
{
    return vector4 (max(a.x, b.x),
                    max(a.y, b.y),
                    max(a.z, b.z),
                    max(a.w, b.w));
}

vector4 max(vector4 a, float b)
{
    return max(a, vector4(b, b, b, b));
}

vector4 min(vector4 a, vector4 b)
{
    return vector4 (min(a.x, b.x),
                    min(a.y, b.y),
                    min(a.z, b.z),
                    min(a.w, b.w));
}

vector4 min(vector4 a, float b)
{
    return min(a, vector4(b, b, b, b));
}

vector4 normalize(vector4 a)
{
    return a / length(a);
}

vector4 mod(vector4 a, vector4 b)
{
    return vector4(mod(a.x, b.x),
                   mod(a.y, b.y),
                   mod(a.z, b.z),
                   mod(a.w, b.w));
}

vector4 mod(vector4 a, float b)
{
    return mod(a, vector4(b, b, b, b));
}

vector4 fmod(vector4 a, vector4 b)
{
    return vector4 (fmod(a.x, b.x),
                    fmod(a.y, b.y),
                    fmod(a.z, b.z),
                    fmod(a.w, b.w));
}

vector4 fmod(vector4 a, float b)
{
    return fmod(a, vector4(b, b, b, b));
}

vector4 pow(vector4 in, vector4 amount)
{
    return vector4 (pow(in.x, amount.x),
                    pow(in.y, amount.y),
                    pow(in.z, amount.z),
                    pow(in.w, amount.w));
}

vector4 pow(vector4 in, float amount)
{
    return vector4 (pow(in.x, amount),
                    pow(in.y, amount),
                    pow(in.z, amount),
                    pow(in.w, amount));
}

vector4 sign(vector4 a)
{
    return vector4(sign(a.x),
                   sign(a.y),
                   sign(a.z),
                   sign(a.w));
}

vector4 sin(vector4 a)
{
    return vector4(sin(a.x),
                   sin(a.y),
                   sin(a.z),
                   sin(a.w));
}

vector4 cos(vector4 a)
{
    return vector4(cos(a.x),
                   cos(a.y),
                   cos(a.z),
                   cos(a.w));
}

vector4 tan(vector4 a)
{
    return vector4(tan(a.x),
                   tan(a.y),
                   tan(a.z),
                   tan(a.w));
}

vector4 asin(vector4 a)
{
    return vector4(asin(a.x),
                   asin(a.y),
                   asin(a.z),
                   asin(a.w));
}

vector4 acos(vector4 a)
{
    return vector4(acos(a.x),
                   acos(a.y),
                   acos(a.z),
                   acos(a.w));
}

vector4 atan2(vector4 a, float f)
{
    return vector4(atan2(a.x, f),
                   atan2(a.y, f),
                   atan2(a.z, f),
                   atan2(a.w, f));
}

vector4 atan2(vector4 a, vector4 b)
{
    return vector4(atan2(a.x, b.x),
                   atan2(a.y, b.y),
                   atan2(a.z, b.z),
                   atan2(a.w, b.w));
}


vector4 transform (matrix M, vector4 p)
{
    return vector4 (M[0][0]*p.x + M[1][0]*p.y + M[2][0]*p.z + M[3][0]*p.w,
                    M[0][1]*p.x + M[1][1]*p.y + M[2][1]*p.z + M[3][1]*p.w,
                    M[0][2]*p.x + M[1][2]*p.y + M[2][2]*p.z + M[3][2]*p.w,
                    M[0][3]*p.x + M[1][3]*p.y + M[2][3]*p.z + M[3][3]*p.w);
}

vector4 transform (string fromspace, string tospace, vector4 p)
{
    return transform (matrix(fromspace,tospace), p);
}
// Open Shading Language : Copyright (c) 2009-2017 Sony Pictures Imageworks Inc., et al.
// https://github.com/imageworks/OpenShadingLanguage/blob/master/LICENSE
//
// MaterialX specification (c) 2017 Lucasfilm Ltd.
// http://www.materialx.org/

#pragma once

#include "color4.h"
#include "vector2.h"
#include "vector4.h"
#include "matrix33.h"

//
// Support functions for OSL implementations of the MaterialX nodes.
//

float mx_ternary(int expr, float v1, float v2) { if (expr) return v1; else return v2; }
int mx_ternary(int expr, int v1, int v2) { if (expr) return v1; else return v2; }
color mx_ternary(int expr, color v1, color v2) { if (expr) return v1; else return v2; }
color4 mx_ternary(int expr, color4 v1, color4 v2) { if (expr) return v1; else return v2; }
vector mx_ternary(int expr, vector v1, vector v2) { if (expr) return v1; else return v2; }
vector2 mx_ternary(int expr, vector2 v1, vector2 v2) { if (expr) return v1; else return v2; }
vector4 mx_ternary(int expr, vector4 v1, vector4 v2) { if (expr) return v1; else return v2; }
matrix mx_ternary(int expr, matrix v1, matrix v2) { if (expr) return v1; else return v2; }
matrix33 mx_ternary(int expr, matrix33 v1, matrix33 v2) { if (expr) return v1; else return v2; }


matrix33 mx_add(matrix33 a, matrix33 b)
{
    return matrix33(matrix(
        a.m[0][0]+b.m[0][0], a.m[0][1]+b.m[0][1], a.m[0][2]+b.m[0][2], 0.0,
        a.m[1][0]+b.m[1][0], a.m[1][1]+b.m[1][1], a.m[1][2]+b.m[1][2], 0.0,
        a.m[2][0]+b.m[2][0], a.m[2][1]+b.m[2][1], a.m[2][2]+b.m[2][2], 0.0,
        0.0, 0.0, 0.0, 1.0));
}

matrix33 mx_add(matrix33 a, float b)
{
    return matrix33(matrix(
        a.m[0][0]+b, a.m[0][1]+b, a.m[0][2]+b, 0.0,
        a.m[1][0]+b, a.m[1][1]+b, a.m[1][2]+b, 0.0,
        a.m[2][0]+b, a.m[2][1]+b, a.m[2][2]+b, 0.0,
        0.0, 0.0, 0.0, 1.0));
}

matrix mx_add(matrix a, matrix b)
{
    return matrix(
        a[0][0]+b[0][0], a[0][1]+b[0][1], a[0][2]+b[0][2], a[0][3]+b[0][3],
        a[1][0]+b[1][0], a[1][1]+b[1][1], a[1][2]+b[1][2], a[1][3]+b[1][3],
        a[2][0]+b[2][0], a[2][1]+b[2][1], a[2][2]+b[2][2], a[2][3]+b[2][3],
        a[3][0]+b[3][0], a[3][1]+b[3][1], a[3][2]+b[3][2], a[3][3]+b[3][3]);
}

matrix mx_add(matrix a, float b)
{
    return matrix(
        a[0][0]+b, a[0][1]+b, a[0][2]+b, a[0][3]+b,
        a[1][0]+b, a[1][1]+b, a[1][2]+b, a[1][3]+b,
        a[2][0]+b, a[2][1]+b, a[2][2]+b, a[2][3]+b,
        a[3][0]+b, a[3][1]+b, a[3][2]+b, a[3][3]+b);
}


matrix33 mx_subtract(matrix33 a, matrix33 b)
{
    return matrix33(matrix(
        a.m[0][0]-b.m[0][0], a.m[0][1]-b.m[0][1], a.m[0][2]-b.m[0][2], 0.0,
        a.m[1][0]-b.m[1][0], a.m[1][1]-b.m[1][1], a.m[1][2]-b.m[1][2], 0.0,
        a.m[2][0]-b.m[2][0], a.m[2][1]-b.m[2][1], a.m[2][2]-b.m[2][2], 0.0,
        0.0, 0.0, 0.0, 1.0));
}

matrix33 mx_subtract(matrix33 a, float b)
{
    return matrix33(matrix(
        a.m[0][0]-b, a.m[0][1]-b, a.m[0][2]-b, 0.0,
        a.m[1][0]-b, a.m[1][1]-b, a.m[1][2]-b, 0.0,
        a.m[2][0]-b, a.m[2][1]-b, a.m[2][2]-b, 0.0,
        0.0, 0.0, 0.0, 1.0));
}

matrix mx_subtract(matrix a, matrix b)
{
   return matrix(
       a[0][0]-b[0][0], a[0][1]-b[0][1], a[0][2]-b[0][2], a[0][3]-b[0][3],
       a[1][0]-b[1][0], a[1][1]-b[1][1], a[1][2]-b[1][2], a[1][3]-b[1][3],
       a[2][0]-b[2][0], a[2][1]-b[2][1], a[2][2]-b[2][2], a[2][3]-b[2][3],
       a[3][0]-b[3][0], a[3][1]-b[3][1], a[3][2]-b[3][2], a[3][3]-b[3][3]);
}

matrix mx_subtract(matrix a, float b)
{
    return matrix(
        a[0][0]-b, a[0][1]-b, a[0][2]-b, a[0][3]-b,
        a[1][0]-b, a[1][1]-b, a[1][2]-b, a[1][3]-b,
        a[2][0]-b, a[2][1]-b, a[2][2]-b, a[2][3]-b,
        a[3][0]-b, a[3][1]-b, a[3][2]-b, a[3][3]-b);
}


float mx_extract(color in, int index)
{
    return in[index];
}

float mx_extract(color4 in, int index)
{
    if (index == 0) return in.rgb.r;
    else if (index == 1) return in.rgb.g;
    else if (index == 2) return in.rgb.b;
    else return in.a;
}

float mx_extract(vector2 in, int index)
{
    if (index == 0) return in.x;
    else return in.y;
}

float mx_extract(vector in, int index)
{
    return in[index];
}

float mx_extract(vector4 in, int index)
{
    if (index == 0) return in.x;
    else if (index == 1) return in.y;
    else if (index == 2) return in.z;
    else return in.w;
}


float mx_remap(float in, float inLow, float inHigh, float outLow, float outHigh, int doClamp)
{
      float x = (in - inLow)/(inHigh-inLow);
      if (doClamp == 1) {
           x = clamp(x, 0, 1);
      }
      return outLow + (outHigh - outLow) * x;
}

color mx_remap(color in, color inLow, color inHigh, color outLow, color outHigh, int doClamp)
{
      color x = (in - inLow) / (inHigh - inLow);
      if (doClamp == 1) {
           x = clamp(x, 0, 1);
      }
      return outLow + (outHigh - outLow) * x;
}

color mx_remap(color in, float inLow, float inHigh, float outLow, float outHigh, int doClamp)
{
      color x = (in - inLow) / (inHigh - inLow);
      if (doClamp == 1) {
           x = clamp(x, 0, 1);
      }
      return outLow + (outHigh - outLow) * x;
}

color4 mx_remap(color4 c, color4 inLow, color4 inHigh, color4 outLow, color4 outHigh, int doClamp)
{
      return color4(mx_remap(c.rgb, inLow.rgb, inHigh.rgb, outLow.rgb, outHigh.rgb, doClamp),
                    mx_remap(c.a, inLow.a, inHigh.a, outLow.a, outHigh.a, doClamp));
}

color4 mx_remap(color4 c, float inLow, float inHigh, float outLow, float outHigh, int doClamp)
{
    color4 c4_inLow = color4(color(inLow), inLow);
    color4 c4_inHigh = color4(color(inHigh), inHigh);
    color4 c4_outLow = color4(color(outLow), outLow);
    color4 c4_outHigh = color4(color(outHigh), outHigh);
    return mx_remap(c, c4_inLow, c4_inHigh, c4_outLow, c4_outHigh, doClamp);
}

vector2 mx_remap(vector2 in, vector2 inLow, vector2 inHigh, vector2 outLow, vector2 outHigh, int doClamp)
{
    return vector2(mx_remap(in.x, inLow.x, inHigh.x, outLow.x, outHigh.x, doClamp),
                   mx_remap(in.y, inLow.y, inHigh.y, outLow.y, outHigh.y, doClamp));
}

vector2 mx_remap(vector2 in, float inLow, float inHigh, float outLow, float outHigh, int doClamp)
{
    return vector2(mx_remap(in.x, inLow, inHigh, outLow, outHigh, doClamp),
                   mx_remap(in.y, inLow, inHigh, outLow, outHigh, doClamp));
}

vector4 mx_remap(vector4 in, vector4 inLow, vector4 inHigh, vector4 outLow, vector4 outHigh, int doClamp)
{
    return vector4(mx_remap(in.x, inLow.x, inHigh.x, outLow.x, outHigh.x, doClamp),
                   mx_remap(in.y, inLow.y, inHigh.y, outLow.y, outHigh.y, doClamp),
                   mx_remap(in.z, inLow.z, inHigh.z, outLow.z, outHigh.z, doClamp),
                   mx_remap(in.w, inLow.w, inHigh.w, outLow.w, outHigh.w, doClamp));
}

vector4 mx_remap(vector4 in, float inLow, float inHigh, float outLow, float outHigh, int doClamp)
{
    return vector4(mx_remap(in.x, inLow, inHigh, outLow, outHigh, doClamp),
                   mx_remap(in.y, inLow, inHigh, outLow, outHigh, doClamp),
                   mx_remap(in.z, inLow, inHigh, outLow, outHigh, doClamp),
                   mx_remap(in.w, inLow, inHigh, outLow, outHigh, doClamp));
}


float mx_contrast(float in, float amount, float pivot)
{
    float out = in - pivot;
    out *= amount;
    out += pivot;
    return out;
}

color mx_contrast(color in, color amount, color pivot)
{
    color out = in - pivot;
    out *= amount;
    out += pivot;
    return out;
}

color mx_contrast(color in, float amount, float pivot)
{
    color out = in - pivot;
    out *= amount;
    out += pivot;
    return out;
}

color4 mx_contrast(color4 c, color4 amount, color4 pivot)
{
    return color4(mx_contrast(c.rgb, amount.rgb, pivot.rgb),
                  mx_contrast(c.a, amount.a, pivot.a));
}

color4 mx_contrast(color4 c, float amount, float pivot)
{
    return mx_contrast(c, color4(color(amount), amount), color4(color(pivot), pivot));
}

vector2 mx_contrast(vector2 in, vector2 amount, vector2 pivot)
{
    return vector2 (mx_contrast(in.x, amount.x, pivot.x),
                    mx_contrast(in.y, amount.y, pivot.y));
}

vector2 mx_contrast(vector2 in, float amount, float pivot)
{
    return mx_contrast(in, vector2(amount, amount), vector2(pivot, pivot));
}

vector4 mx_contrast(vector4 in, vector4 amount, vector4 pivot)
{
    return vector4(mx_contrast(in.x, amount.x, pivot.x),
                   mx_contrast(in.y, amount.y, pivot.y),
                   mx_contrast(in.z, amount.z, pivot.z),
                   mx_contrast(in.w, amount.w, pivot.w));
}

vector4 mx_contrast(vector4 in, float amount, float pivot)
{
    return vector4(mx_contrast(in.x, amount, pivot),
                   mx_contrast(in.y, amount, pivot),
                   mx_contrast(in.z, amount, pivot),
                   mx_contrast(in.w, amount, pivot));
}


vector2 mx_noise(string noisetype, float x, float y)
{
    color cnoise = (color) noise(noisetype, x, y);
    return vector2 (cnoise[0], cnoise[1]);
}

color4 mx_noise(string noisetype, float x, float y)
{
    color cnoise = (color) noise(noisetype, x, y);
    float fnoise = (float) noise(noisetype, x + 19, y + 73);
    return color4 (cnoise, fnoise);
}

vector4 mx_noise(string noisetype, float x, float y)
{
    color cnoise = (color) noise(noisetype, x, y);
    float fnoise = (float) noise(noisetype, x + 19, y + 73);
    return vector4 (cnoise[0], cnoise[1], cnoise[2], fnoise);
}

vector2 mx_noise(string noisetype, point position)
{
    color cnoise = (color) noise(noisetype, position);
    return vector2 (cnoise[0], cnoise[1]);
}

color4 mx_noise(string noisetype, point position)
{
    color cnoise = (color) noise(noisetype, position);
    float fnoise = (float) noise(noisetype, position+vector(19,73,29));
    return color4 (cnoise, fnoise);
}

vector4 mx_noise(string noisetype, point position)
{
    color cnoise = (color) noise(noisetype, position);
    float fnoise = (float) noise(noisetype, position+vector(19,73,29));
    return vector4 (cnoise[0], cnoise[1], cnoise[2], fnoise);
}

float mx_fbm(float x, float y, int octaves, float lacunarity, float diminish, string noisetype)
{
    float out = 0;
    float amp = 1.0;
    float xx = x;
    float yy = y;

    for (int i = 0;  i < octaves;  i += 1) {
        out += amp * noise(noisetype, xx, yy);
        amp *= diminish;
        xx *= lacunarity;
        yy *= lacunarity;
    }
    return out;
}

color mx_fbm(float x, float y, int octaves, float lacunarity, float diminish, string noisetype)
{
    color out = 0;
    float amp = 1.0;
    float xx = x;
    float yy = y;

    for (int i = 0;  i < octaves;  i += 1) {
        out += amp * (color)noise(noisetype, xx, yy);
        amp *= diminish;
        xx *= lacunarity;
        yy *= lacunarity;
    }
    return out;
}

vector2 mx_fbm(float x, float y, int octaves, float lacunarity, float diminish, string noisetype)
{
    return vector2((float) mx_fbm(x, y, octaves, lacunarity, diminish, noisetype),
                   (float) mx_fbm(x+19, y+193, octaves, lacunarity, diminish, noisetype));
}

color4 mx_fbm(float x, float y, int octaves, float lacunarity, float diminish, string noisetype)
{
    color c = (color) mx_fbm(x, y, octaves, lacunarity, diminish, noisetype);
    float f = (float) mx_fbm(x+19, y+193, octaves, lacunarity, diminish, noisetype);
    return color4 (c, f);
}

vector4 mx_fbm(float x, float y, int octaves, float lacunarity, float diminish, string noisetype)
{
    color c = (color) mx_fbm(x, y, octaves, lacunarity, diminish, noisetype);
    float f = (float) mx_fbm(x+19, y+193, octaves, lacunarity, diminish, noisetype);
    return vector4 (c[0], c[1], c[2], f);
}

float mx_fbm(point position, int octaves, float lacunarity, float diminish, string noisetype)
{
    float out = 0;
    float amp = 1.0;
    point p = position;

    for (int i = 0;  i < octaves;  i += 1) {
        out += amp * noise(noisetype, p);
        amp *= diminish;
        p *= lacunarity;
    }
    return out;
}

color mx_fbm(point position, int octaves, float lacunarity, float diminish, string noisetype)
{
    color out = 0;
    float amp = 1.0;
    point p = position;

    for (int i = 0;  i < octaves;  i += 1) {
        out += amp * (color)noise(noisetype, p);
        amp *= diminish;
        p *= lacunarity;
    }
    return out;
}

vector2 mx_fbm(point position, int octaves, float lacunarity, float diminish, string noisetype)
{
    return vector2((float) mx_fbm(position, octaves, lacunarity, diminish, noisetype),
                   (float) mx_fbm(position+point(19, 193, 17), octaves, lacunarity, diminish, noisetype));
}

color4 mx_fbm(point position, int octaves, float lacunarity, float diminish, string noisetype)
{
    color c = (color) mx_fbm(position, octaves, lacunarity, diminish, noisetype);
    float f = (float) mx_fbm(position+point(19, 193, 17), octaves, lacunarity, diminish, noisetype);
    return color4 (c, f);
}

vector4 mx_fbm(point position, int octaves, float lacunarity, float diminish, string noisetype)
{
    color c = (color) mx_fbm(position, octaves, lacunarity, diminish, noisetype);
    float f = (float) mx_fbm(position+point(19, 193, 17), octaves, lacunarity, diminish, noisetype);
    return vector4 (c[0], c[1], c[2], f);
}

vector2 mx_worley_cell_position(int x, int y, int xoff, int yoff, float jitter)
{
    vector  tmp = cellnoise(x+xoff, y+yoff);
    vector2 off = vector2(tmp.x, tmp.y);
    off -= 0.5;
    off *= jitter;
    off += 0.5;
    return vector2(x, y) + off;
}

vector mx_worley_cell_position(int x, int y, int z, int xoff, int yoff, int zoff, float jitter)
{
    vector off = cellnoise(vector(x+xoff, y+yoff, z+zoff));
    off -= 0.5;
    off *= jitter;
    off += 0.5;
    return vector(x,y,z) + off;
}

float mx_worley_distance(vector2 p, int x, int y, int X, int Y, float jitter, int metric)
{
    vector2 cellpos = mx_worley_cell_position(x,y,X,Y,jitter);
    vector2 diff = cellpos - p;

    if (metric == 2)
        return abs(diff.x) + abs(diff.y);     // Manhattan distance
    if (metric == 3)
        return max(abs(diff.x), abs(diff.y)); // Chebyshev distance
    return diff.x*diff.x + diff.y*diff.y;       // Euclidean or distance^2
}

float mx_worley_distance(vector p, int x, int y, int z, int X, int Y, int Z, float jitter, int metric)
{
    vector cellpos = mx_worley_cell_position(x,y,z,X,Y,Z,jitter);
    vector diff = cellpos - p;
    if (metric == 2)
        return abs(diff[0]) + abs(diff[1]);     // Manhattan distance
    if (metric == 3)
        return max(abs(diff[0]), abs(diff[1])); // Chebyshev distance
    return dot(diff, diff);                     // Eucldean or distance^2
}

void mx_sort_distance(float dist, output vector2 result)
{
    if (dist < result.x)
    {
        result.y = result.x;
        result.x = dist;
    }
    else if (dist < result.y)
    {
        result.y = dist;
    }
}

void mx_sort_distance(float dist, output vector result)
{
    if (dist < result[0])
    {
        result[2] = result[1];
        result[1] = result[0];
        result[0] = dist;
    }
    else if (dist < result[1])
    {
        result[2] = result[1];
        result[1] = dist;
    }
    else if (dist < result[2])
    {
        result[2] = dist;
    }
}

// return floor as well as the fractional remainder
float mx_floorfrac(float x, output int i)
{
    i = (int)floor(x);
    return x - float(i);
}

float mx_worley_noise_float(vector2 p, float jitter, int style, int metric)
{
    int X, Y;
    float sqdist = 1e6;
    vector2 localpos = vector2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y));
    vector2 minpos = vector2(0.0, 0.0);

    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric);
            vector2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos;
            if (dist < sqdist)
            {
                sqdist = dist;
                minpos = cellpos;
            }
        }
    }
    if (style == 1)
    {
        vector2 tmpP = minpos + p;
        return cellnoise(tmpP.x, tmpP.y);
    }
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

vector2 mx_worley_noise_vector2(vector2 p, float jitter, int style, int metric)
{
    int X, Y;
    vector2 sqdist = vector2(1e6, 1e6);
    vector2 localpos = vector2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y));
    vector2 minpos = vector2(0.0, 0.0);

    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric);
            vector2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos;
            if (dist < sqdist.x)
            {
                sqdist.y = sqdist.x;
                sqdist.x = dist;
                minpos = cellpos;
            }
            else if (dist < sqdist.y)
            {
                sqdist.y = dist;
            }
        }
    }

    if (style == 1)
    {
        vector2 tmpP = minpos + p;
        vector tmp = cellnoise(tmpP.x, tmpP.y);
        return vector2(tmp.x, tmp.y);
    }
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

vector mx_worley_noise_vector3(vector2 p, float jitter, int style, int metric)
{
    int X, Y;
    vector sqdist = vector(1e6, 1e6, 1e6);
    vector2 localpos = vector2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y));
    vector2 minpos = vector2(0.0, 0.0);

    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric);
            vector2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos;
            if (dist < sqdist.x)
            {
                sqdist.z = sqdist.y;
                sqdist.y = sqdist.x;
                sqdist.x = dist;
                minpos = cellpos;
            }
            else if (dist < sqdist.y)
            {
                sqdist.z = sqdist.y;
                sqdist.y = dist;
            }
            else if (dist < sqdist.z)
            {
                sqdist.z = dist;
            }
        }
    }
    if (style == 1)
    {
        vector2 tmpP = minpos + p;
        return cellnoise(tmpP.x, tmpP.y);
    }
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

float mx_worley_noise_float(vector p, float jitter, int style, int metric)
{
    int X, Y, Z;
    vector seed = p;
    float sqdist = 1e6;
    vector localpos = vector(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z));
    vector minpos = vector(0.0, 0.0, 0.0);
    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            for (int z = -1; z <= 1; ++z)
            {
                float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric);
                vector cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos;
                if(dist < sqdist)
                {
                    sqdist = dist;
                    minpos = cellpos;
                }
            }
        }
    }
    if (style == 1)
        return cellnoise(minpos + p);
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

vector2 mx_worley_noise_vector2(vector p, float jitter, int style, int metric)
{
    int X, Y, Z;
    vector2 sqdist = vector2(1e6, 1e6);
    vector localpos = vector(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z));
    vector minpos = vector(0.0, 0.0, 0.0);

    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            for (int z = -1; z <= 1; ++z)
            {
                float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric);
                vector cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos;
                if (dist < sqdist.x)
                {
                    sqdist.y = sqdist.x;
                    sqdist.x = dist;
                    minpos = cellpos;
                }
                else if (dist < sqdist.y)
                {
                    sqdist.y = dist;
                }
            }
        }
    }
    if (style == 1)
    {
        vector tmp = cellnoise(minpos + p);
        return vector2(tmp.x,tmp.y);
    }
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}

vector mx_worley_noise_vector3(vector p, float jitter, int style, int metric)
{
    int X, Y, Z;
    vector sqdist = 1e6;
    vector localpos = vector(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z));
    vector minpos = vector(0.0, 0.0, 0.0);

    for (int x = -1; x <= 1; ++x)
    {
        for (int y = -1; y <= 1; ++y)
        {
            for (int z = -1; z <= 1; ++z)
            {
                float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric);
                vector cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos;
                if (dist < sqdist.x)
                {
                    sqdist.z = sqdist.y;
                    sqdist.y = sqdist.x;
                    sqdist.x = dist;
                    minpos = cellpos;
                }
                else if (dist < sqdist.y)
                {
                    sqdist.z = sqdist.y;
                    sqdist.y = dist;
                }
                else if (dist < sqdist.z)
                {
                    sqdist.z = dist;
                }
            }
        }
    }
    if (style == 1)
        return cellnoise(minpos + p);
    else
    {
        if (metric == 0)
            sqdist = sqrt(sqdist);
        return sqdist;
    }
}
// Copyright Contributors to the Open Shading Language project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage


#pragma once
#define MATRIX33_H


struct matrix33
{
    matrix m;
};

int isValidAs33(matrix m44)
{
    return m44[0][3] == 0 && 
           m44[1][3] == 0 &&
           m44[2][3] == 0 &&
           m44[3][0] == 0 &&
           m44[3][1] == 0 &&
           m44[3][2] == 0 &&
           m44[3][3] == 1;
}

matrix matrix33To44 (matrix33 m33)
{
    return m33.m;
}

// Convert an arbitrary m44 to m33 by removing the translation
//QUESTION: should we check if it's valid to represent the 4x4 as a 3x3?
matrix33 matrix44To33 (matrix m44)
{
    matrix33 m33;
    m33.m = m44;
    m33.m[0][3] = 0;
    m33.m[1][3] = 0;
    m33.m[2][3] = 0;
    m33.m[3][0] = 0;
    m33.m[3][1] = 0;
    m33.m[3][2] = 0;
    m33.m[3][3] = 1;

    return m33;
}

matrix33 __operator__neg__(matrix33 a)
{
    matrix33 m33;
    m33.m = -a.m;
    return m33;
}


matrix33 __operator__mul__(int a, matrix33 b)
{
    matrix33 m33;
    m33.m = a * b.m;
    return m33;
}

matrix33 __operator__mul__(float a, matrix33 b)
{
    matrix33 m33;
    m33.m = a * b.m;
    return m33;
}

matrix33 __operator__mul__(matrix33 a, int b)
{
    matrix33 m33;
    m33.m = a.m * b;
    return m33;
}

matrix33 __operator__mul__(matrix33 a, float b)
{
    matrix33 m33;
    m33.m = a.m * b;
    return m33;
}

matrix33 __operator__mul__(matrix33 a, matrix33 b)
{
    matrix33 m33;
    m33.m = a.m * b.m;
    return m33;
}

matrix33 __operator__div__(int a, matrix33 b)
{
    matrix33 m33;
    m33.m = a / b.m;
    return m33;
}

matrix33 __operator__div__(float a, matrix33 b)
{
    matrix33 m33;
    m33.m = a / b.m;
    return m33;
}

matrix33 __operator__div__(matrix33 a, int b)
{
    matrix33 m33;
    m33.m = a.m / b;
    return m33;
}

matrix33 __operator__div__(matrix33 a, float b)
{
    matrix33 m33;
    m33.m = a.m / b;
    return m33;
}

matrix33 __operator__div__(matrix33 a, matrix33 b)
{
    matrix33 m33;
    m33.m = a.m / b.m;
    return m33;
}

int __operator__eq__(matrix33 a, matrix33 b)
{
    return a.m == b.m;
}

int __operator__ne__(matrix33 a, matrix33 b)
{
    return a.m != b.m;
}

float determinant (matrix33 a)
{
    return determinant(a.m);
}

matrix33 transpose(matrix33 a)
{
    matrix33 m33;
    m33.m = transpose(a.m);
    return m33;
}

point transform(matrix33 a, point b)
{
    return transform(a.m, b);
}

vector transform(matrix33 a, vector b)
{
    return transform(a.m, b);
}

normal transform(matrix33 a, normal b)
{
    return transform(a.m, b);
}
vector2 mx_transform_uv(vector2 texcoord)
{
    return vector2(texcoord.x, 1.0 - texcoord.y);
}
vector2 mx_transform_uv(vector2 texcoord)
{
    return texcoord;
}
// Adds some syntactic sugar allowing mixing vector4 and color4 as
// arguments of some binary operators used by OCIO transform code.

vector4 __operator__mul__(matrix m, vector4 v)
{
    return transform(m, v);
}

vector4 __operator__mul__(color4 c, vector4 v)
{
    return vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a) * v;
}

vector4 __operator__mul__(vector4 v, color4 c)
{
    return c * v;
}

vector4 __operator__sub__(color4 c, vector4 v)
{
    return vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a) - v;
}

vector4 __operator__add__(vector4 v, color4 c)
{
    return v + vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a);
}

vector4 __operator__add__(color4 c, vector4 v)
{
    return v + c;
}

vector4 pow(color4 c, vector4 v)
{
    return pow(vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a), v);
}

vector4 max(vector4 v, color4 c)
{
    return max(v, vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a));
}
// Restrict to 7x7 kernel size for performance reasons
#define MX_MAX_SAMPLE_COUNT 49
// Size of all weights for all levels (including level 1)
#define MX_WEIGHT_ARRAY_SIZE 84

//
// Function to compute the sample size relative to a texture coordinate
//
vector2 mx_compute_sample_size_uv(vector2 uv, float filterSize, float filterOffset)
{
   vector derivUVx = Dx(vector(uv.x, uv.y, 0.0)) * 0.5;
   vector derivUVy = Dy(vector(uv.x, uv.y, 0.0)) * 0.5;
   float derivX = abs(derivUVx[0]) + abs(derivUVy[0]);
   float derivY = abs(derivUVx[1]) + abs(derivUVy[1]);
   float sampleSizeU = filterSize * derivX + filterOffset;
   if (sampleSizeU < 1.0E-05)
       sampleSizeU = 1.0E-05;
   float sampleSizeV = filterSize * derivY + filterOffset;
   if (sampleSizeV < 1.0E-05)
       sampleSizeV = 1.0E-05;
   return vector2(sampleSizeU, sampleSizeV);
}

// Kernel weights for box filter
void mx_get_box_weights(output float W[MX_MAX_SAMPLE_COUNT], int filterSize)
{
    int sampleCount = filterSize*filterSize;
    float value = 1.0 / float(sampleCount);
    for (int i=0; i<sampleCount; i++)
    {
        W[i] = value;
    }
}

// Kernel weights for Gaussian filter. Sigma is assumed to be 1.
void mx_get_gaussian_weights(output float W[MX_MAX_SAMPLE_COUNT], int filterSize)
{
    if (filterSize >= 7)
    {
        W[0] = 0.000036;  W[1] = 0.000363;  W[2] = 0.001446;  W[3] = 0.002291;  W[4] = 0.001446;  W[5] = 0.000363;  W[6] = 0.000036;
        W[7] = 0.000363;  W[8] = 0.003676;  W[9] = 0.014662;  W[10] = 0.023226; W[11] = 0.014662; W[12] = 0.003676; W[13] = 0.000363;
        W[14] = 0.001446; W[15] = 0.014662; W[16] = 0.058488; W[17] = 0.092651; W[18] = 0.058488; W[19] = 0.014662; W[20] = 0.001446;
        W[21] = 0.002291; W[22] = 0.023226; W[23] = 0.092651; W[24] = 0.146768; W[25] = 0.092651; W[26] = 0.023226; W[27] = 0.002291;
        W[28] = 0.001446; W[29] = 0.014662; W[30] = 0.058488; W[31] = 0.092651; W[32] = 0.058488; W[33] = 0.014662; W[34] = 0.001446;
        W[35] = 0.000363; W[36] = 0.003676; W[37] = 0.014662; W[38] = 0.023226; W[39] = 0.014662; W[40] = 0.003676; W[41] = 0.000363;
        W[42] = 0.000036; W[43] = 0.000363; W[44] = 0.001446; W[45] = 0.002291; W[46] = 0.001446; W[47] = 0.000363; W[48] = 0.000036;
    }
    else if (filterSize >= 5)
    {
        W[0] = 0.003765;  W[1] = 0.015019;  W[2] = 0.023792;  W[3] = 0.015019;  W[4] = 0.003765;
        W[5] = 0.015019;  W[6] = 0.059912;  W[7] = 0.094907;  W[8] = 0.059912;  W[9] = 0.015019;
        W[10] = 0.023792; W[11] = 0.094907; W[12] = 0.150342; W[13] = 0.094907; W[14] = 0.023792;
        W[15] = 0.015019; W[16] = 0.059912; W[17] = 0.094907; W[18] = 0.059912; W[19] = 0.015019;
        W[20] = 0.003765; W[21] = 0.015019; W[22] = 0.023792; W[23] = 0.015019; W[24] = 0.003765;
    }
    else if (filterSize >= 3)
    {
        W[0] = 0.0625; W[1] = 0.125; W[2] = 0.0625;
        W[3] = 0.125;  W[4] = 0.25;  W[5] = 0.125;
        W[6] = 0.0625; W[7] = 0.125; W[8] = 0.0625;
    }
    else
    {
        W[0] = 1.0;
    }
}

//
// Apply filter for float samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
float mx_convolution_float(float S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    float result = 0.0;
    for (int i = 0;  i < sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vector2 samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vector2 mx_convolution_vector2(vector2 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vector2 result = vector2(0.0, 0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vector samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
vector mx_convolution_vector(vector S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vector result = vector(0.0, 0.0, 0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for vector4 samples S, using weights W.
// sampleCount should be a square of a odd number { 1, 3, 5, 7 }
//
vector4 mx_convolution_vector4(vector4 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    vector4 result = vector4(0.0, 0.0, 0.0, 0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for color samples S, using weights W.
// sampleCount should be a square of a odd number in the range { 1, 3, 5, 7 }
//
color mx_convolution_color(color S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    color result = color(0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}

//
// Apply filter for color4 samples S, using weights W.
// sampleCount should be a square of a odd number { 1, 3, 5, 7 }
//
color4 mx_convolution_color4(color4 S[MX_MAX_SAMPLE_COUNT], float W[MX_WEIGHT_ARRAY_SIZE], int offset, int sampleCount)
{
    color4 result = color4(color(0.0, 0.0, 0.0), 0.0);
    for (int i=0;  i<sampleCount; i++)
    {
        result += S[i]*W[i+offset];
    }
    return result;
}
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations for MDL implementations of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- Shader nodes                                                             -->
  <!-- ======================================================================== -->

  <!-- <surfacematerial> -->
  <implementation name="IM_surfacematerial_genmdl" nodedef="ND_surfacematerial" target="genmdl" />

  <!-- <surface_unlit> -->
  <implementation name="IM_surface_unlit_genmdl" nodedef="ND_surface_unlit" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_surface_unlit({{emission}}, {{emission_color}}, {{transmission}}, {{transmission_color}}, {{opacity}})" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Texture nodes                                                            -->
  <!-- ======================================================================== -->

  <!-- <image> -->
  <implementation name="IM_image_float_genmdl" nodedef="ND_image_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_image_float({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
    <input name="default" type="float" implname="default_value" />
  </implementation>
  <implementation name="IM_image_color3_genmdl" nodedef="ND_image_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_image_color3({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
    <input name="default" type="color3" implname="default_value" />
  </implementation>
  <implementation name="IM_image_color4_genmdl" nodedef="ND_image_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_image_color4({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
    <input name="default" type="color4" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector2_genmdl" nodedef="ND_image_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_image_vector2({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
    <input name="default" type="vector2" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector3_genmdl" nodedef="ND_image_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_image_vector3({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
    <input name="default" type="vector3" implname="default_value" />
  </implementation>
  <implementation name="IM_image_vector4_genmdl" nodedef="ND_image_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_image_vector4({{file}}, {{layer}}, {{default}}, {{texcoord}}, {{uaddressmode}}, {{vaddressmode}}, {{filtertype}}, {{framerange}}, {{frameoffset}}, {{frameendaction}}, mxp_flip_v:{{flip_v}})" target="genmdl">
    <input name="default" type="vector4" implname="default_value" />
  </implementation>

  <!-- <hextiledimage> -->
  <implementation name="IM_hextiledimage_color3_genmdl" nodedef="ND_hextiledimage_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_hextiledimage_color3({{file}}, {{default}}, {{texcoord}}, {{tiling}}, {{rotation}}, {{rotationrange}}, {{scale}}, {{scalerange}}, {{offset}}, {{offsetrange}}, {{falloff}}, {{falloffcontrast}}, {{lumacoeffs}})" target="genmdl">
    <input name="default" type="color3" implname="default_value" />
  </implementation>
  <implementation name="IM_hextiledimage_color4_genmdl" nodedef="ND_hextiledimage_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_hextiledimage_color4({{file}}, {{default}}, {{texcoord}}, {{tiling}}, {{rotation}}, {{rotationrange}}, {{scale}}, {{scalerange}}, {{offset}}, {{offsetrange}}, {{falloff}}, {{falloffcontrast}}, {{lumacoeffs}})" target="genmdl">
    <input name="default" type="color4" implname="default_value" />
  </implementation>

  <!-- <triplanarprojection> -->

  <!-- <normalmap> -->
  <implementation name="IM_normalmap_float_genmdl" nodedef="ND_normalmap_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_normalmap_float(mxp_in:{{in}}, mxp_scale:{{scale}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_bitangent:{{bitangent}})" target="genmdl" />
  <implementation name="IM_normalmap_vector2_genmdl" nodedef="ND_normalmap_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_normalmap_vector2(mxp_in:{{in}}, mxp_scale:{{scale}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_bitangent:{{bitangent}})" target="genmdl" />

  <!-- <hextilednormalmap> -->
  <implementation name="IM_hextilednormalmap_vector3_genmdl" nodedef="ND_hextilednormalmap_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_hextilednormalmap_vector3({{file}}, {{default}}, {{texcoord}}, {{tiling}}, {{rotation}}, {{rotationrange}}, {{scale}}, {{scalerange}}, {{offset}}, {{offsetrange}}, {{falloff}},{{strength}}, {{flip_g}}, {{normal}}, {{tangent}}, {{bitangent}})" target="genmdl">
    <input name="default" type="vector3" implname="default_value" />
  </implementation>

  <!-- ======================================================================== -->
  <!-- Procedural nodes                                                         -->
  <!-- ======================================================================== -->

  <!-- <constant> -->
  <implementation name="IM_constant_float_genmdl" nodedef="ND_constant_float" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_color3_genmdl" nodedef="ND_constant_color3" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_color4_genmdl" nodedef="ND_constant_color4" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_vector2_genmdl" nodedef="ND_constant_vector2" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_vector3_genmdl" nodedef="ND_constant_vector3" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_vector4_genmdl" nodedef="ND_constant_vector4" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_boolean_genmdl" nodedef="ND_constant_boolean" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_integer_genmdl" nodedef="ND_constant_integer" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_matrix33_genmdl" nodedef="ND_constant_matrix33" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_matrix44_genmdl" nodedef="ND_constant_matrix44" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_string_genmdl" nodedef="ND_constant_string" sourcecode="{{value}}" target="genmdl" />
  <implementation name="IM_constant_filename_genmdl" nodedef="ND_constant_filename" sourcecode="{{value}}" target="genmdl" />

  <!-- <ramplr> -->
  <implementation name="IM_ramplr_float_genmdl" nodedef="ND_ramplr_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramplr_float(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramplr_color3_genmdl" nodedef="ND_ramplr_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramplr_color3(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramplr_color4_genmdl" nodedef="ND_ramplr_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramplr_color4(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramplr_vector2_genmdl" nodedef="ND_ramplr_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramplr_vector2(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramplr_vector3_genmdl" nodedef="ND_ramplr_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramplr_vector3(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramplr_vector4_genmdl" nodedef="ND_ramplr_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramplr_vector4(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_texcoord:{{texcoord}})" target="genmdl" />

  <!-- <ramptb> -->
  <implementation name="IM_ramptb_float_genmdl" nodedef="ND_ramptb_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramptb_float(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramptb_color3_genmdl" nodedef="ND_ramptb_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramptb_color3(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramptb_color4_genmdl" nodedef="ND_ramptb_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramptb_color4(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramptb_vector2_genmdl" nodedef="ND_ramptb_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramptb_vector2(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramptb_vector3_genmdl" nodedef="ND_ramptb_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramptb_vector3(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_ramptb_vector4_genmdl" nodedef="ND_ramptb_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ramptb_vector4(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_texcoord:{{texcoord}})" target="genmdl" />

  <!-- <splitlr> -->
  <implementation name="IM_splitlr_float_genmdl" nodedef="ND_splitlr_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splitlr_float(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splitlr_color3_genmdl" nodedef="ND_splitlr_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splitlr_color3(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splitlr_color4_genmdl" nodedef="ND_splitlr_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splitlr_color4(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splitlr_vector2_genmdl" nodedef="ND_splitlr_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splitlr_vector2(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splitlr_vector3_genmdl" nodedef="ND_splitlr_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splitlr_vector3(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splitlr_vector4_genmdl" nodedef="ND_splitlr_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splitlr_vector4(mxp_valuel:{{valuel}}, mxp_valuer:{{valuer}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />

  <!-- <splittb> -->
  <implementation name="IM_splittb_float_genmdl" nodedef="ND_splittb_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splittb_float(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splittb_color3_genmdl" nodedef="ND_splittb_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splittb_color3(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splittb_color4_genmdl" nodedef="ND_splittb_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splittb_color4(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splittb_vector2_genmdl" nodedef="ND_splittb_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splittb_vector2(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splittb_vector3_genmdl" nodedef="ND_splittb_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splittb_vector3(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_splittb_vector4_genmdl" nodedef="ND_splittb_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_splittb_vector4(mxp_valuet:{{valuet}}, mxp_valueb:{{valueb}}, mxp_center:{{center}}, mxp_texcoord:{{texcoord}})" target="genmdl" />

  <!-- <noise2d> -->
  <implementation name="IM_noise2d_float_genmdl" nodedef="ND_noise2d_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_noise2d_float(mxp_amplitude:{{amplitude}}, mxp_pivot:{{pivot}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_noise2d_vector2_genmdl" nodedef="ND_noise2d_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_noise2d_float2(mxp_amplitude:{{amplitude}}, mxp_pivot:{{pivot}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_noise2d_vector3_genmdl" nodedef="ND_noise2d_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_noise2d_float3(mxp_amplitude:{{amplitude}}, mxp_pivot:{{pivot}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_noise2d_vector4_genmdl" nodedef="ND_noise2d_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_noise2d_float4(mxp_amplitude:{{amplitude}}, mxp_pivot:{{pivot}}, mxp_texcoord:{{texcoord}})" target="genmdl" />

  <!-- <noise3d> -->
  <implementation name="IM_noise3d_float_genmdl" nodedef="ND_noise3d_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_noise3d_float(mxp_amplitude:{{amplitude}}, mxp_pivot:{{pivot}}, mxp_position:{{position}})" target="genmdl" />
  <implementation name="IM_noise3d_vector2_genmdl" nodedef="ND_noise3d_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_noise3d_float2(mxp_amplitude:{{amplitude}}, mxp_pivot:{{pivot}}, mxp_position:{{position}})" target="genmdl" />
  <implementation name="IM_noise3d_vector3_genmdl" nodedef="ND_noise3d_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_noise3d_float3(mxp_amplitude:{{amplitude}}, mxp_pivot:{{pivot}}, mxp_position:{{position}})" target="genmdl" />
  <implementation name="IM_noise3d_vector4_genmdl" nodedef="ND_noise3d_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_noise3d_float4(mxp_amplitude:{{amplitude}}, mxp_pivot:{{pivot}}, mxp_position:{{position}})" target="genmdl" />

  <!-- <fractal2d> -->
  <implementation name="IM_fractal2d_float_genmdl" nodedef="ND_fractal2d_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fractal2d_float(mxp_amplitude:{{amplitude}}, mxp_octaves:{{octaves}}, mxp_lacunarity:{{lacunarity}}, mxp_diminish:{{diminish}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_fractal2d_vector2_genmdl" nodedef="ND_fractal2d_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fractal2d_float2(mxp_amplitude:{{amplitude}}, mxp_octaves:{{octaves}}, mxp_lacunarity:{{lacunarity}}, mxp_diminish:{{diminish}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_fractal2d_vector3_genmdl" nodedef="ND_fractal2d_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fractal2d_float3(mxp_amplitude:{{amplitude}}, mxp_octaves:{{octaves}}, mxp_lacunarity:{{lacunarity}}, mxp_diminish:{{diminish}}, mxp_texcoord:{{texcoord}})" target="genmdl" />
  <implementation name="IM_fractal2d_vector4_genmdl" nodedef="ND_fractal2d_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fractal2d_float4(mxp_amplitude:{{amplitude}}, mxp_octaves:{{octaves}}, mxp_lacunarity:{{lacunarity}}, mxp_diminish:{{diminish}}, mxp_texcoord:{{texcoord}})" target="genmdl" />

  <!-- <fractal3d> -->
  <implementation name="IM_fractal3d_float_genmdl" nodedef="ND_fractal3d_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fractal3d_float(mxp_amplitude:{{amplitude}}, mxp_octaves:{{octaves}}, mxp_lacunarity:{{lacunarity}}, mxp_diminish:{{diminish}}, mxp_position:{{position}})" target="genmdl" />
  <implementation name="IM_fractal3d_vector2_genmdl" nodedef="ND_fractal3d_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fractal3d_float2(mxp_amplitude:{{amplitude}}, mxp_octaves:{{octaves}}, mxp_lacunarity:{{lacunarity}}, mxp_diminish:{{diminish}}, mxp_position:{{position}})" target="genmdl" />
  <implementation name="IM_fractal3d_vector3_genmdl" nodedef="ND_fractal3d_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fractal3d_float3(mxp_amplitude:{{amplitude}}, mxp_octaves:{{octaves}}, mxp_lacunarity:{{lacunarity}}, mxp_diminish:{{diminish}}, mxp_position:{{position}})" target="genmdl" />
  <implementation name="IM_fractal3d_vector4_genmdl" nodedef="ND_fractal3d_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fractal3d_float4(mxp_amplitude:{{amplitude}}, mxp_octaves:{{octaves}}, mxp_lacunarity:{{lacunarity}}, mxp_diminish:{{diminish}}, mxp_position:{{position}})" target="genmdl" />

  <!-- <cellnoise2d> -->
  <implementation name="IM_cellnoise2d_float_genmdl" nodedef="ND_cellnoise2d_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_cellnoise2d_float(mxp_texcoord:{{texcoord}})" target="genmdl" />

  <!-- <cellnoise3d> -->
  <implementation name="IM_cellnoise3d_float_genmdl" nodedef="ND_cellnoise3d_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_cellnoise3d_float(mxp_position:{{position}})" target="genmdl" />

  <!-- <worleynoise2d> -->
  <implementation name="IM_worleynoise2d_float_genmdl" nodedef="ND_worleynoise2d_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_worleynoise2d_float(mxp_texcoord:{{texcoord}}, mxp_jitter:{{jitter}})" target="genmdl" />
  <implementation name="IM_worleynoise2d_vector2_genmdl" nodedef="ND_worleynoise2d_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_worleynoise2d_float2(mxp_texcoord:{{texcoord}}, mxp_jitter:{{jitter}})" target="genmdl" />
  <implementation name="IM_worleynoise2d_vector3_genmdl" nodedef="ND_worleynoise2d_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_worleynoise2d_float3(mxp_texcoord:{{texcoord}}, mxp_jitter:{{jitter}})" target="genmdl" />

  <!-- <worleynoise3d> -->
  <implementation name="IM_worleynoise3d_float_genmdl" nodedef="ND_worleynoise3d_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_worleynoise3d_float(mxp_position:{{position}}, mxp_jitter:{{jitter}})" target="genmdl" />
  <implementation name="IM_worleynoise3d_vector2_genmdl" nodedef="ND_worleynoise3d_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_worleynoise3d_float2(mxp_position:{{position}}, mxp_jitter:{{jitter}})" target="genmdl" />
  <implementation name="IM_worleynoise3d_vector3_genmdl" nodedef="ND_worleynoise3d_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_worleynoise3d_float3(mxp_position:{{position}}, mxp_jitter:{{jitter}})" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Geometric nodes                                                          -->
  <!-- ======================================================================== -->

  <!-- <position> -->
  <implementation name="IM_position_vector3_genmdl" nodedef="ND_position_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_position_vector3(mxp_space:{{space}})" target="genmdl" />

  <!-- <normal> -->
  <implementation name="IM_normal_vector3_genmdl" nodedef="ND_normal_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_normal_vector3(mxp_space:{{space}})" target="genmdl" />

  <!-- <tangent> -->
  <implementation name="IM_tangent_vector3_genmdl" nodedef="ND_tangent_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_tangent_vector3(mxp_space:{{space}}, mxp_index:{{index}})" target="genmdl" />

  <!-- <bitangent> -->
  <implementation name="IM_bitangent_vector3_genmdl" nodedef="ND_bitangent_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_bitangent_vector3(mxp_space:{{space}}, mxp_index:{{index}})" target="genmdl" />

  <!-- <texcoord> -->
  <implementation name="IM_texcoord_vector2_genmdl" nodedef="ND_texcoord_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_texcoord_vector2(mxp_index:{{index}})" target="genmdl" />
  <implementation name="IM_texcoord_vector3_genmdl" nodedef="ND_texcoord_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_texcoord_vector3(mxp_index:{{index}})" target="genmdl" />

  <!-- <geomcolor> -->
  <implementation name="IM_geomcolor_float_genmdl" nodedef="ND_geomcolor_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geomcolor_float(mxp_index:{{index}})" target="genmdl" />
  <implementation name="IM_geomcolor_color3_genmdl" nodedef="ND_geomcolor_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geomcolor_color3(mxp_index:{{index}})" target="genmdl" />
  <implementation name="IM_geomcolor_color4_genmdl" nodedef="ND_geomcolor_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geomcolor_color4(mxp_index:{{index}})" target="genmdl" />

  <!-- <geompropvalue> -->
  <implementation name="IM_geompropvalue_integer_genmdl" nodedef="ND_geompropvalue_integer" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_integer(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />
  <implementation name="IM_geompropvalue_boolean_genmdl" nodedef="ND_geompropvalue_boolean" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_boolean(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />
  <implementation name="IM_geompropvalue_float_genmdl" nodedef="ND_geompropvalue_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_float(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />
  <implementation name="IM_geompropvalue_color3_genmdl" nodedef="ND_geompropvalue_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_color3(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />
  <implementation name="IM_geompropvalue_color4_genmdl" nodedef="ND_geompropvalue_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_color4(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />
  <implementation name="IM_geompropvalue_vector2_genmdl" nodedef="ND_geompropvalue_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_vector2(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />
  <implementation name="IM_geompropvalue_vector3_genmdl" nodedef="ND_geompropvalue_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_vector3(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />
  <implementation name="IM_geompropvalue_vector4_genmdl" nodedef="ND_geompropvalue_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_vector4(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />

  <!-- <geompropvalueuniform> -->
  <implementation name="IM_geompropvalue_string_genmdl" nodedef="ND_geompropvalueuniform_string" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_string(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />
  <implementation name="IM_geompropvalue_filename_genmdl" nodedef="ND_geompropvalueuniform_filename" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_geompropvalue_string(mxp_geomprop:{{geomprop}}, mxp_default:{{default}})" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Application nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <frame> -->
  <implementation name="IM_frame_float_genmdl" nodedef="ND_frame_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_frame_float()" target="genmdl" />

  <!-- <time> -->
  <implementation name="IM_time_float_genmdl" nodedef="ND_time_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_time_float()" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Math nodes                                                               -->
  <!-- ======================================================================== -->

  <!-- <add> -->
  <implementation name="IM_add_float_genmdl" nodedef="ND_add_float" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_integer_genmdl" nodedef="ND_add_integer" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_color3_genmdl" nodedef="ND_add_color3" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_color3FA_genmdl" nodedef="ND_add_color3FA" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_color4_genmdl" nodedef="ND_add_color4" sourcecode="mx_add({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_add_color4FA_genmdl" nodedef="ND_add_color4FA" sourcecode="mx_add({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_add_vector2_genmdl" nodedef="ND_add_vector2" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_vector2FA_genmdl" nodedef="ND_add_vector2FA" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_vector3_genmdl" nodedef="ND_add_vector3" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_vector3FA_genmdl" nodedef="ND_add_vector3FA" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_vector4_genmdl" nodedef="ND_add_vector4" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_vector4FA_genmdl" nodedef="ND_add_vector4FA" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_matrix33_genmdl" nodedef="ND_add_matrix33" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_matrix33FA_genmdl" nodedef="ND_add_matrix33FA" sourcecode="{{in1}} + float3x3({{in2}})" target="genmdl" />
  <implementation name="IM_add_matrix44_genmdl" nodedef="ND_add_matrix44" sourcecode="{{in1}} + {{in2}}" target="genmdl" />
  <implementation name="IM_add_matrix44FA_genmdl" nodedef="ND_add_matrix44FA" sourcecode="{{in1}} + float4x4({{in2}})" target="genmdl" />

  <!-- <subtract> -->
  <implementation name="IM_subtract_float_genmdl" nodedef="ND_subtract_float" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_integer_genmdl" nodedef="ND_subtract_integer" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_color3_genmdl" nodedef="ND_subtract_color3" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_color3FA_genmdl" nodedef="ND_subtract_color3FA" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_color4_genmdl" nodedef="ND_subtract_color4" sourcecode="mx_subtract({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_subtract_color4FA_genmdl" nodedef="ND_subtract_color4FA" sourcecode="mx_subtract({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_subtract_vector2_genmdl" nodedef="ND_subtract_vector2" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_vector2FA_genmdl" nodedef="ND_subtract_vector2FA" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_vector3_genmdl" nodedef="ND_subtract_vector3" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_vector3FA_genmdl" nodedef="ND_subtract_vector3FA" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_vector4_genmdl" nodedef="ND_subtract_vector4" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_vector4FA_genmdl" nodedef="ND_subtract_vector4FA" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_matrix33_genmdl" nodedef="ND_subtract_matrix33" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_matrix33FA_genmdl" nodedef="ND_subtract_matrix33FA" sourcecode="{{in1}} - float3x3({{in2}})" target="genmdl" />
  <implementation name="IM_subtract_matrix44_genmdl" nodedef="ND_subtract_matrix44" sourcecode="{{in1}} - {{in2}}" target="genmdl" />
  <implementation name="IM_subtract_matrix44FA_genmdl" nodedef="ND_subtract_matrix44FA" sourcecode="{{in1}} - float4x4({{in2}})" target="genmdl" />

  <!-- <multiply> -->
  <implementation name="IM_multiply_float_genmdl" nodedef="ND_multiply_float" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_color3_genmdl" nodedef="ND_multiply_color3" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_color3FA_genmdl" nodedef="ND_multiply_color3FA" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_color4_genmdl" nodedef="ND_multiply_color4" sourcecode="mx_multiply({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_multiply_color4FA_genmdl" nodedef="ND_multiply_color4FA" sourcecode="mx_multiply({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_multiply_vector2_genmdl" nodedef="ND_multiply_vector2" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_vector2FA_genmdl" nodedef="ND_multiply_vector2FA" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_vector3_genmdl" nodedef="ND_multiply_vector3" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_vector3FA_genmdl" nodedef="ND_multiply_vector3FA" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_vector4_genmdl" nodedef="ND_multiply_vector4" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_vector4FA_genmdl" nodedef="ND_multiply_vector4FA" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_matrix33_genmdl" nodedef="ND_multiply_matrix33" sourcecode="{{in1}} * {{in2}}" target="genmdl" />
  <implementation name="IM_multiply_matrix44_genmdl" nodedef="ND_multiply_matrix44" sourcecode="{{in1}} * {{in2}}" target="genmdl" />

  <!-- <divide> -->
  <implementation name="IM_divide_float_genmdl" nodedef="ND_divide_float" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_color3_genmdl" nodedef="ND_divide_color3" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_color3FA_genmdl" nodedef="ND_divide_color3FA" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_color4_genmdl" nodedef="ND_divide_color4" sourcecode="mx_divide({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_divide_color4FA_genmdl" nodedef="ND_divide_color4FA" sourcecode="mx_divide({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_divide_vector2_genmdl" nodedef="ND_divide_vector2" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_vector2FA_genmdl" nodedef="ND_divide_vector2FA" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_vector3_genmdl" nodedef="ND_divide_vector3" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_vector3FA_genmdl" nodedef="ND_divide_vector3FA" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_vector4_genmdl" nodedef="ND_divide_vector4" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_vector4FA_genmdl" nodedef="ND_divide_vector4FA" sourcecode="{{in1}} / {{in2}}" target="genmdl" />
  <implementation name="IM_divide_matrix33_genmdl" nodedef="ND_divide_matrix33" sourcecode="{{in1}}" target="genmdl" /> <!-- TODO: Implement properly -->
  <implementation name="IM_divide_matrix44_genmdl" nodedef="ND_divide_matrix44" sourcecode="{{in1}}" target="genmdl" /> <!-- TODO: Implement properly -->

  <!-- <modulo> -->
  <implementation name="IM_modulo_float_genmdl" nodedef="ND_modulo_float" sourcecode="mx_mod({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_color3_genmdl" nodedef="ND_modulo_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_modulo_color3({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_color3FA_genmdl" nodedef="ND_modulo_color3FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_modulo_color3FA({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_color4_genmdl" nodedef="ND_modulo_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_modulo_color4({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_color4FA_genmdl" nodedef="ND_modulo_color4FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_modulo_color4FA({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_vector2_genmdl" nodedef="ND_modulo_vector2" sourcecode="mx_mod({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_vector2FA_genmdl" nodedef="ND_modulo_vector2FA" sourcecode="mx_mod({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_vector3_genmdl" nodedef="ND_modulo_vector3" sourcecode="mx_mod({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_vector3FA_genmdl" nodedef="ND_modulo_vector3FA" sourcecode="mx_mod({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_vector4_genmdl" nodedef="ND_modulo_vector4" sourcecode="mx_mod({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_modulo_vector4FA_genmdl" nodedef="ND_modulo_vector4FA" sourcecode="mx_mod({{in1}}, {{in2}})" target="genmdl" />

  <!-- <fract> -->
  <implementation name="IM_fract_float_genmdl" nodedef="ND_fract_float" sourcecode="math::frac({{in}})" target="genmdl" />
  <implementation name="IM_fract_color3_genmdl" nodedef="ND_fract_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fract_color3({{in}})" target="genmdl" />
  <implementation name="IM_fract_color4_genmdl" nodedef="ND_fract_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_fract_color4({{in}})" target="genmdl" />
  <implementation name="IM_fract_vector2_genmdl" nodedef="ND_fract_vector2" sourcecode="math::frac({{in}})" target="genmdl" />
  <implementation name="IM_fract_vector3_genmdl" nodedef="ND_fract_vector3" sourcecode="math::frac({{in}})" target="genmdl" />
  <implementation name="IM_fract_vector4_genmdl" nodedef="ND_fract_vector4" sourcecode="math::frac({{in}})" target="genmdl" />

  <!-- <invert> -->
  <implementation name="IM_invert_float_genmdl" nodedef="ND_invert_float" sourcecode="{{amount}} - {{in}}" target="genmdl" />
  <implementation name="IM_invert_color3_genmdl" nodedef="ND_invert_color3" sourcecode="{{amount}} - {{in}}" target="genmdl" />
  <implementation name="IM_invert_color3FA_genmdl" nodedef="ND_invert_color3FA" sourcecode="{{amount}} - {{in}}" target="genmdl" />
  <implementation name="IM_invert_color4_genmdl" nodedef="ND_invert_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_invert_color4({{in}}, {{amount}})" target="genmdl" />
  <implementation name="IM_invert_color4FA_genmdl" nodedef="ND_invert_color4FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_invert_color4FA({{in}}, {{amount}})" target="genmdl" />
  <implementation name="IM_invert_vector2_genmdl" nodedef="ND_invert_vector2" sourcecode="{{amount}} - {{in}}" target="genmdl" />
  <implementation name="IM_invert_vector2FA_genmdl" nodedef="ND_invert_vector2FA" sourcecode="{{amount}} - {{in}}" target="genmdl" />
  <implementation name="IM_invert_vector3_genmdl" nodedef="ND_invert_vector3" sourcecode="{{amount}} - {{in}}" target="genmdl" />
  <implementation name="IM_invert_vector3FA_genmdl" nodedef="ND_invert_vector3FA" sourcecode="{{amount}} - {{in}}" target="genmdl" />
  <implementation name="IM_invert_vector4_genmdl" nodedef="ND_invert_vector4" sourcecode="{{amount}} - {{in}}" target="genmdl" />
  <implementation name="IM_invert_vector4FA_genmdl" nodedef="ND_invert_vector4FA" sourcecode="{{amount}} - {{in}}" target="genmdl" />

  <!-- <absval> -->
  <implementation name="IM_absval_float_genmdl" nodedef="ND_absval_float" sourcecode="math::abs({{in}})" target="genmdl" />
  <implementation name="IM_absval_color3_genmdl" nodedef="ND_absval_color3" sourcecode="math::abs({{in}})" target="genmdl" />
  <implementation name="IM_absval_color4_genmdl" nodedef="ND_absval_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_absval_color4({{in}})" target="genmdl" />
  <implementation name="IM_absval_vector2_genmdl" nodedef="ND_absval_vector2" sourcecode="math::abs({{in}})" target="genmdl" />
  <implementation name="IM_absval_vector3_genmdl" nodedef="ND_absval_vector3" sourcecode="math::abs({{in}})" target="genmdl" />
  <implementation name="IM_absval_vector4_genmdl" nodedef="ND_absval_vector4" sourcecode="math::abs({{in}})" target="genmdl" />

  <!-- <floor> -->
  <implementation name="IM_floor_float_genmdl" nodedef="ND_floor_float" sourcecode="math::floor({{in}})" target="genmdl" />
  <implementation name="IM_floor_color3_genmdl" nodedef="ND_floor_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_floor_color3({{in}})" target="genmdl" />
  <implementation name="IM_floor_color4_genmdl" nodedef="ND_floor_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_floor_color4({{in}})" target="genmdl" />
  <implementation name="IM_floor_vector2_genmdl" nodedef="ND_floor_vector2" sourcecode="math::floor({{in}})" target="genmdl" />
  <implementation name="IM_floor_vector3_genmdl" nodedef="ND_floor_vector3" sourcecode="math::floor({{in}})" target="genmdl" />
  <implementation name="IM_floor_vector4_genmdl" nodedef="ND_floor_vector4" sourcecode="math::floor({{in}})" target="genmdl" />
  <implementation name="IM_floor_integer_genmdl" nodedef="ND_floor_integer" sourcecode="int(math::floor({{in}}))" target="genmdl" />

  <!-- <ceil> -->
  <implementation name="IM_ceil_float_genmdl" nodedef="ND_ceil_float" sourcecode="math::ceil({{in}})" target="genmdl" />
  <implementation name="IM_ceil_color3_genmdl" nodedef="ND_ceil_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ceil_color3({{in}})" target="genmdl" />
  <implementation name="IM_ceil_color4_genmdl" nodedef="ND_ceil_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ceil_color4({{in}})" target="genmdl" />
  <implementation name="IM_ceil_vector2_genmdl" nodedef="ND_ceil_vector2" sourcecode="math::ceil({{in}})" target="genmdl" />
  <implementation name="IM_ceil_vector3_genmdl" nodedef="ND_ceil_vector3" sourcecode="math::ceil({{in}})" target="genmdl" />
  <implementation name="IM_ceil_vector4_genmdl" nodedef="ND_ceil_vector4" sourcecode="math::ceil({{in}})" target="genmdl" />
  <implementation name="IM_ceil_integer_genmdl" nodedef="ND_ceil_integer" sourcecode="int(math::ceil({{in}}))" target="genmdl" />

  <!-- <round> -->
  <implementation name="IM_round_float_genmdl" nodedef="ND_round_float" sourcecode="math::round({{in}})" target="genmdl" />
  <implementation name="IM_round_color3_genmdl" nodedef="ND_round_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_round_color3({{in}})" target="genmdl" />
  <implementation name="IM_round_color4_genmdl" nodedef="ND_round_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_round_color4({{in}})" target="genmdl" />
  <implementation name="IM_round_vector2_genmdl" nodedef="ND_round_vector2" sourcecode="math::round({{in}})" target="genmdl" />
  <implementation name="IM_round_vector3_genmdl" nodedef="ND_round_vector3" sourcecode="math::round({{in}})" target="genmdl" />
  <implementation name="IM_round_vector4_genmdl" nodedef="ND_round_vector4" sourcecode="math::round({{in}})" target="genmdl" />
  <implementation name="IM_round_integer_genmdl" nodedef="ND_round_integer" sourcecode="int(math::round({{in}}))" target="genmdl" />

  <!-- <power> -->
  <implementation name="IM_power_float_genmdl" nodedef="ND_power_float" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_color3_genmdl" nodedef="ND_power_color3" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_color3FA_genmdl" nodedef="ND_power_color3FA" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_color4_genmdl" nodedef="ND_power_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_power_color4({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_color4FA_genmdl" nodedef="ND_power_color4FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_power_color4FA({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_vector2_genmdl" nodedef="ND_power_vector2" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_vector2FA_genmdl" nodedef="ND_power_vector2FA" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_vector3_genmdl" nodedef="ND_power_vector3" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_vector3FA_genmdl" nodedef="ND_power_vector3FA" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_vector4_genmdl" nodedef="ND_power_vector4" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_power_vector4FA_genmdl" nodedef="ND_power_vector4FA" sourcecode="math::pow({{in1}}, {{in2}})" target="genmdl" />

  <!-- <sin>, <cos>, <tan>, <asin>, <acos>, <atan2> -->
  <implementation name="IM_sin_float_genmdl" nodedef="ND_sin_float" sourcecode="math::sin({{in}})" target="genmdl" />
  <implementation name="IM_cos_float_genmdl" nodedef="ND_cos_float" sourcecode="math::cos({{in}})" target="genmdl" />
  <implementation name="IM_tan_float_genmdl" nodedef="ND_tan_float" sourcecode="math::tan({{in}})" target="genmdl" />
  <implementation name="IM_asin_float_genmdl" nodedef="ND_asin_float" sourcecode="math::asin({{in}})" target="genmdl" />
  <implementation name="IM_acos_float_genmdl" nodedef="ND_acos_float" sourcecode="math::acos({{in}})" target="genmdl" />
  <implementation name="IM_atan2_float_genmdl" nodedef="ND_atan2_float" sourcecode="math::atan2({{iny}}, {{inx}})" target="genmdl" />

  <implementation name="IM_sin_vector2_genmdl" nodedef="ND_sin_vector2" sourcecode="math::sin({{in}})" target="genmdl" />
  <implementation name="IM_cos_vector2_genmdl" nodedef="ND_cos_vector2" sourcecode="math::cos({{in}})" target="genmdl" />
  <implementation name="IM_tan_vector2_genmdl" nodedef="ND_tan_vector2" sourcecode="math::tan({{in}})" target="genmdl" />
  <implementation name="IM_asin_vector2_genmdl" nodedef="ND_asin_vector2" sourcecode="math::asin({{in}})" target="genmdl" />
  <implementation name="IM_acos_vector2_genmdl" nodedef="ND_acos_vector2" sourcecode="math::acos({{in}})" target="genmdl" />
  <implementation name="IM_atan2_vector2_genmdl" nodedef="ND_atan2_vector2" sourcecode="math::atan2({{iny}}, {{inx}})" target="genmdl" />

  <implementation name="IM_sin_vector3_genmdl" nodedef="ND_sin_vector3" sourcecode="math::sin({{in}})" target="genmdl" />
  <implementation name="IM_cos_vector3_genmdl" nodedef="ND_cos_vector3" sourcecode="math::cos({{in}})" target="genmdl" />
  <implementation name="IM_tan_vector3_genmdl" nodedef="ND_tan_vector3" sourcecode="math::tan({{in}})" target="genmdl" />
  <implementation name="IM_asin_vector3_genmdl" nodedef="ND_asin_vector3" sourcecode="math::asin({{in}})" target="genmdl" />
  <implementation name="IM_acos_vector3_genmdl" nodedef="ND_acos_vector3" sourcecode="math::acos({{in}})" target="genmdl" />
  <implementation name="IM_atan2_vector3_genmdl" nodedef="ND_atan2_vector3" sourcecode="math::atan2({{iny}}, {{inx}})" target="genmdl" />

  <implementation name="IM_sin_vector4_genmdl" nodedef="ND_sin_vector4" sourcecode="math::sin({{in}})" target="genmdl" />
  <implementation name="IM_cos_vector4_genmdl" nodedef="ND_cos_vector4" sourcecode="math::cos({{in}})" target="genmdl" />
  <implementation name="IM_tan_vector4_genmdl" nodedef="ND_tan_vector4" sourcecode="math::tan({{in}})" target="genmdl" />
  <implementation name="IM_asin_vector4_genmdl" nodedef="ND_asin_vector4" sourcecode="math::asin({{in}})" target="genmdl" />
  <implementation name="IM_acos_vector4_genmdl" nodedef="ND_acos_vector4" sourcecode="math::acos({{in}})" target="genmdl" />
  <implementation name="IM_atan2_vector4_genmdl" nodedef="ND_atan2_vector4" sourcecode="math::atan2({{iny}}, {{inx}})" target="genmdl" />

  <!-- <sqrt> -->
  <implementation name="IM_sqrt_float_genmdl" nodedef="ND_sqrt_float" sourcecode="math::sqrt({{in}})" target="genmdl" />
  <implementation name="IM_sqrt_vector2_genmdl" nodedef="ND_sqrt_vector2" sourcecode="math::sqrt({{in}})" target="genmdl" />
  <implementation name="IM_sqrt_vector3_genmdl" nodedef="ND_sqrt_vector3" sourcecode="math::sqrt({{in}})" target="genmdl" />
  <implementation name="IM_sqrt_vector4_genmdl" nodedef="ND_sqrt_vector4" sourcecode="math::sqrt({{in}})" target="genmdl" />

  <!-- <ln> -->
  <implementation name="IM_ln_float_genmdl" nodedef="ND_ln_float" sourcecode="math::log({{in}})" target="genmdl" />
  <implementation name="IM_ln_vector2_genmdl" nodedef="ND_ln_vector2" sourcecode="math::log({{in}})" target="genmdl" />
  <implementation name="IM_ln_vector3_genmdl" nodedef="ND_ln_vector3" sourcecode="math::log({{in}})" target="genmdl" />
  <implementation name="IM_ln_vector4_genmdl" nodedef="ND_ln_vector4" sourcecode="math::log({{in}})" target="genmdl" />

  <!-- <exp> -->
  <implementation name="IM_exp_float_genmdl" nodedef="ND_exp_float" sourcecode="math::exp({{in}})" target="genmdl" />
  <implementation name="IM_exp_vector2_genmdl" nodedef="ND_exp_vector2" sourcecode="math::exp({{in}})" target="genmdl" />
  <implementation name="IM_exp_vector3_genmdl" nodedef="ND_exp_vector3" sourcecode="math::exp({{in}})" target="genmdl" />
  <implementation name="IM_exp_vector4_genmdl" nodedef="ND_exp_vector4" sourcecode="math::exp({{in}})" target="genmdl" />

  <!-- sign -->
  <implementation name="IM_sign_float_genmdl" nodedef="ND_sign_float" sourcecode="math::sign({{in}})" target="genmdl" />
  <implementation name="IM_sign_color3_genmdl" nodedef="ND_sign_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_sign_color3({{in}})" target="genmdl" />
  <implementation name="IM_sign_color4_genmdl" nodedef="ND_sign_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_sign_color4({{in}})" target="genmdl" />
  <implementation name="IM_sign_vector2_genmdl" nodedef="ND_sign_vector2" sourcecode="math::sign({{in}})" target="genmdl" />
  <implementation name="IM_sign_vector3_genmdl" nodedef="ND_sign_vector3" sourcecode="math::sign({{in}})" target="genmdl" />
  <implementation name="IM_sign_vector4_genmdl" nodedef="ND_sign_vector4" sourcecode="math::sign({{in}})" target="genmdl" />

  <!-- <clamp> -->
  <implementation name="IM_clamp_float_genmdl" nodedef="ND_clamp_float" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_color3_genmdl" nodedef="ND_clamp_color3" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_color3FA_genmdl" nodedef="ND_clamp_color3FA" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_color4_genmdl" nodedef="ND_clamp_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_clamp_color4({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_color4FA_genmdl" nodedef="ND_clamp_color4FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_clamp_color4FA({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_vector2_genmdl" nodedef="ND_clamp_vector2" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_vector2FA_genmdl" nodedef="ND_clamp_vector2FA" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_vector3_genmdl" nodedef="ND_clamp_vector3" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_vector3FA_genmdl" nodedef="ND_clamp_vector3FA" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_vector4_genmdl" nodedef="ND_clamp_vector4" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_clamp_vector4FA_genmdl" nodedef="ND_clamp_vector4FA" sourcecode="math::clamp({{in}}, {{low}}, {{high}})" target="genmdl" />

  <!-- <min> -->
  <implementation name="IM_min_float_genmdl" nodedef="ND_min_float" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_color3_genmdl" nodedef="ND_min_color3" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_color3FA_genmdl" nodedef="ND_min_color3FA" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_color4_genmdl" nodedef="ND_min_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_min_color4({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_color4FA_genmdl" nodedef="ND_min_color4FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_min_color4({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_vector2_genmdl" nodedef="ND_min_vector2" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_vector2FA_genmdl" nodedef="ND_min_vector2FA" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_vector3_genmdl" nodedef="ND_min_vector3" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_vector3FA_genmdl" nodedef="ND_min_vector3FA" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_vector4_genmdl" nodedef="ND_min_vector4" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_min_vector4FA_genmdl" nodedef="ND_min_vector4FA" sourcecode="math::min({{in1}}, {{in2}})" target="genmdl" />

  <!-- <max> -->
  <implementation name="IM_max_float_genmdl" nodedef="ND_max_float" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_color3_genmdl" nodedef="ND_max_color3" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_color3FA_genmdl" nodedef="ND_max_color3FA" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_color4_genmdl" nodedef="ND_max_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_max_color4({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_color4FA_genmdl" nodedef="ND_max_color4FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_max_color4({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_vector2_genmdl" nodedef="ND_max_vector2" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_vector2FA_genmdl" nodedef="ND_max_vector2FA" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_vector3_genmdl" nodedef="ND_max_vector3" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_vector3FA_genmdl" nodedef="ND_max_vector3FA" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_vector4_genmdl" nodedef="ND_max_vector4" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_max_vector4FA_genmdl" nodedef="ND_max_vector4FA" sourcecode="math::max({{in1}}, {{in2}})" target="genmdl" />

  <!-- <normalize> -->
  <implementation name="IM_normalize_vector2_genmdl" nodedef="ND_normalize_vector2" sourcecode="math::normalize({{in}})" target="genmdl" />
  <implementation name="IM_normalize_vector3_genmdl" nodedef="ND_normalize_vector3" sourcecode="math::normalize({{in}})" target="genmdl" />
  <implementation name="IM_normalize_vector4_genmdl" nodedef="ND_normalize_vector4" sourcecode="math::normalize({{in}})" target="genmdl" />

  <!-- <magnitude> -->
  <implementation name="IM_magnitude_vector2_genmdl" nodedef="ND_magnitude_vector2" sourcecode="math::length({{in}})" target="genmdl" />
  <implementation name="IM_magnitude_vector3_genmdl" nodedef="ND_magnitude_vector3" sourcecode="math::length({{in}})" target="genmdl" />
  <implementation name="IM_magnitude_vector4_genmdl" nodedef="ND_magnitude_vector4" sourcecode="math::length({{in}})" target="genmdl" />

  <!-- <dotproduct> -->
  <implementation name="IM_dotproduct_vector2_genmdl" nodedef="ND_dotproduct_vector2" sourcecode="math::dot({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_dotproduct_vector3_genmdl" nodedef="ND_dotproduct_vector3" sourcecode="math::dot({{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_dotproduct_vector4_genmdl" nodedef="ND_dotproduct_vector4" sourcecode="math::dot({{in1}}, {{in2}})" target="genmdl" />

  <!-- <crossproduct> -->
  <implementation name="IM_crossproduct_vector3_genmdl" nodedef="ND_crossproduct_vector3" sourcecode="math::cross({{in1}}, {{in2}})" target="genmdl" />

  <!-- <transformpoint> -->
  <implementation name="IM_transformpoint_vector3_genmdl" nodedef="ND_transformpoint_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_transformpoint_vector3({{in}}, {{fromspace}}, {{tospace}})" target="genmdl" />

  <!-- <transformvector> -->
  <implementation name="IM_transformvector_vector3_genmdl" nodedef="ND_transformvector_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_transformvector_vector3({{in}}, {{fromspace}}, {{tospace}})" target="genmdl" />

  <!-- <transformnormal> -->
  <implementation name="IM_transformnormal_vector3_genmdl" nodedef="ND_transformnormal_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_transformnormal_vector3({{in}}, {{fromspace}}, {{tospace}})" target="genmdl" />

  <!-- <transformmatrix> -->
  <implementation name="IM_transformmatrix_vector2M3_genmdl" nodedef="ND_transformmatrix_vector2M3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_transformmatrix_vector2M3({{in}}, {{mat}})" target="genmdl" />
  <implementation name="IM_transformmatrix_vector3_genmdl" nodedef="ND_transformmatrix_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_transformmatrix_vector3({{in}}, {{mat}})" target="genmdl" />
  <implementation name="IM_transformmatrix_vector3M4_genmdl" nodedef="ND_transformmatrix_vector3M4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_transformmatrix_vector3M4({{in}}, {{mat}})" target="genmdl" />
  <implementation name="IM_transformmatrix_vector4_genmdl" nodedef="ND_transformmatrix_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_transformmatrix_vector4({{in}}, {{mat}})" target="genmdl" />

  <!-- <transpose> -->
  <implementation name="IM_transpose_matrix33_genmdl" nodedef="ND_transpose_matrix33" sourcecode="math::transpose({{in}})" target="genmdl" />
  <implementation name="IM_transpose_matrix44_genmdl" nodedef="ND_transpose_matrix44" sourcecode="math::transpose({{in}})" target="genmdl" />

  <!-- <determinant> -->
  <implementation name="IM_determinant_matrix33_genmdl" nodedef="ND_determinant_matrix33" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_determinant_matrix33({{in}})" target="genmdl" />
  <implementation name="IM_determinant_matrix44_genmdl" nodedef="ND_determinant_matrix44" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_determinant_matrix44({{in}})" target="genmdl" />

  <!-- <invertmatrix> -->
  <implementation name="IM_invertmatrix_matrix33_genmdl" nodedef="ND_invertmatrix_matrix33" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_invertmatrix_matrix33({{in}})" target="genmdl" />
  <implementation name="IM_invertmatrix_matrix44_genmdl" nodedef="ND_invertmatrix_matrix44" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_invertmatrix_matrix44({{in}})" target="genmdl" />

  <!-- <rotate2d> -->
  <implementation name="IM_rotate2d_vector2_genmdl" nodedef="ND_rotate2d_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_rotate2d_vector2(mxp_in:{{in}}, mxp_amount:{{amount}})" target="genmdl" />

  <!-- <rotate3d> -->
  <implementation name="IM_rotate3d_vector3_genmdl" nodedef="ND_rotate3d_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_rotate3d_vector3(mxp_in:{{in}}, mxp_amount:{{amount}}, mxp_axis:{{axis}})" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Adjustment nodes                                                         -->
  <!-- ======================================================================== -->

  <!-- <contrast> implemented by nodegraph -->

  <!-- <remap> implemented -->
  <implementation name="IM_remap_float_genmdl" nodedef="ND_remap_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_float({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_color3_genmdl" nodedef="ND_remap_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_color3({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_color4_genmdl" nodedef="ND_remap_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_color4({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_vector2_genmdl" nodedef="ND_remap_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_vector2({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_vector3_genmdl" nodedef="ND_remap_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_vector3({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_vector4_genmdl" nodedef="ND_remap_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_vector4({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_color3FA_genmdl" nodedef="ND_remap_color3FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_color3FA({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_color4FA_genmdl" nodedef="ND_remap_color4FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_color4FA({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_vector2FA_genmdl" nodedef="ND_remap_vector2FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_vector2FA({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_vector3FA_genmdl" nodedef="ND_remap_vector3FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_vector3FA({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />
  <implementation name="IM_remap_vector4FA_genmdl" nodedef="ND_remap_vector4FA" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_remap_vector4FA({{in}}, {{inlow}}, {{inhigh}}, {{outlow}}, {{outhigh}})" target="genmdl" />

  <!-- <smoothstep> -->
  <implementation name="IM_smoothstep_float_genmdl" nodedef="ND_smoothstep_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_smoothstep_float({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_smoothstep_vector2_genmdl" nodedef="ND_smoothstep_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_smoothstep_vector2({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_smoothstep_vector3_genmdl" nodedef="ND_smoothstep_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_smoothstep_vector3({{in}}, {{low}}, {{high}})" target="genmdl" />
  <implementation name="IM_smoothstep_vector4_genmdl" nodedef="ND_smoothstep_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_smoothstep_vector4({{in}}, {{low}}, {{high}})" target="genmdl" />

  <!-- <saturate> implemented by nodegraph -->

  <!-- <luminance>  -->
  <implementation name="IM_luminance_color3_genmdl" nodedef="ND_luminance_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_luminance_color3({{in}}, {{lumacoeffs}})" target="genmdl" />
  <implementation name="IM_luminance_color4_genmdl" nodedef="ND_luminance_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_luminance_color4({{in}}, {{lumacoeffs}})" target="genmdl" />

  <!-- <rgbtohsv> -->
  <implementation name="IM_rgbtohsv_color3_genmdl" nodedef="ND_rgbtohsv_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_rgbtohsv_color3({{in}})" target="genmdl" />
  <implementation name="IM_rgbtohsv_color4_genmdl" nodedef="ND_rgbtohsv_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_rgbtohsv_color4({{in}})" target="genmdl" />

  <!-- <hsvtorgb> -->
  <implementation name="IM_hsvtorgb_color3_genmdl" nodedef="ND_hsvtorgb_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_hsvtorgb_color3({{in}})" target="genmdl" />
  <implementation name="IM_hsvtorgb_color4_genmdl" nodedef="ND_hsvtorgb_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_hsvtorgb_color4({{in}})" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Compositing nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <premult> -->
  <implementation name="IM_premult_color4_genmdl" nodedef="ND_premult_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_premult_color4({{in}})" target="genmdl" />

  <!-- <unpremult> -->
  <implementation name="IM_unpremult_color4_genmdl" nodedef="ND_unpremult_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_unpremult_color4({{in}})" target="genmdl" />

  <!-- <plus> -->
  <implementation name="IM_plus_float_genmdl" nodedef="ND_plus_float" sourcecode="({{mix}}*({{bg}} + {{fg}})) + ((1.0-{{mix}})*{{bg}})" target="genmdl" />
  <implementation name="IM_plus_color3_genmdl" nodedef="ND_plus_color3" sourcecode="({{mix}}*({{bg}} + {{fg}})) + ((1.0-{{mix}})*{{bg}})" target="genmdl" />
  <implementation name="IM_plus_color4_genmdl" nodedef="ND_plus_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_plus_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <minus> -->
  <implementation name="IM_minus_float_genmdl" nodedef="ND_minus_float" sourcecode="({{mix}}*({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" target="genmdl" />
  <implementation name="IM_minus_color3_genmdl" nodedef="ND_minus_color3" sourcecode="({{mix}}*({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" target="genmdl" />
  <implementation name="IM_minus_color4_genmdl" nodedef="ND_minus_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_minus_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <difference> -->
  <implementation name="IM_difference_float_genmdl" nodedef="ND_difference_float" sourcecode="({{mix}}*math::abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" target="genmdl" />
  <implementation name="IM_difference_color3_genmdl" nodedef="ND_difference_color3" sourcecode="({{mix}}*math::abs({{bg}} - {{fg}})) + ((1.0-{{mix}})*{{bg}})" target="genmdl" />
  <implementation name="IM_difference_color4_genmdl" nodedef="ND_difference_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_difference_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <burn> -->
  <implementation name="IM_burn_float_genmdl" nodedef="ND_burn_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_burn_float({{fg}}, {{bg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_burn_color3_genmdl" nodedef="ND_burn_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_burn_color3({{fg}}, {{bg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_burn_color4_genmdl" nodedef="ND_burn_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_burn_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <dodge> -->
  <implementation name="IM_dodge_float_genmdl" nodedef="ND_dodge_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_dodge_float({{fg}}, {{bg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_dodge_color3_genmdl" nodedef="ND_dodge_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_dodge_color3({{fg}}, {{bg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_dodge_color4_genmdl" nodedef="ND_dodge_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_dodge_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <screen> -->
  <implementation name="IM_screen_float_genmdl" nodedef="ND_screen_float" sourcecode="({{mix}}*((1.0 - (1.0 - {{fg}}) * (1 - {{bg}})))) + ((1.0-{{mix}})*{{bg}})" target="genmdl" />
  <implementation name="IM_screen_color3_genmdl" nodedef="ND_screen_color3" sourcecode="({{mix}}*((1.0 - (1.0 - {{fg}}) * (1 - {{bg}})))) + ((1.0-{{mix}})*{{bg}})" target="genmdl" />
  <implementation name="IM_screen_color4_genmdl" nodedef="ND_screen_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_screen_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <disjointover> -->
  <implementation name="IM_disjointover_color4_genmdl" nodedef="ND_disjointover_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_disjointover_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <in> -->
  <implementation name="IM_in_color4_genmdl" nodedef="ND_in_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_in_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <mask> -->
  <implementation name="IM_mask_color4_genmdl" nodedef="ND_mask_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_mask_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <matte> -->
  <implementation name="IM_matte_color4_genmdl" nodedef="ND_matte_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_matte_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <out> -->
  <implementation name="IM_out_color4_genmdl" nodedef="ND_out_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_out_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <over> -->
  <implementation name="IM_over_color4_genmdl" nodedef="ND_over_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_over_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- <inside> -->
  <implementation name="IM_inside_float_genmdl" nodedef="ND_inside_float" sourcecode="{{in}} * {{mask}}" target="genmdl" />
  <implementation name="IM_inside_color3_genmdl" nodedef="ND_inside_color3" sourcecode="{{in}} * {{mask}}" target="genmdl" />
  <implementation name="IM_inside_color4_genmdl" nodedef="ND_inside_color4" sourcecode="mx_multiply({{in}}, {{mask}})" target="genmdl" />

  <!-- <outside> -->
  <implementation name="IM_outside_float_genmdl" nodedef="ND_outside_float" sourcecode="{{in}} * (1.0 - {{mask}})" target="genmdl" />
  <implementation name="IM_outside_color3_genmdl" nodedef="ND_outside_color3" sourcecode="{{in}} * (1.0 - {{mask}})" target="genmdl" />
  <implementation name="IM_outside_color4_genmdl" nodedef="ND_outside_color4" sourcecode="mx_multiply({{in}}, 1.0 - {{mask}})" target="genmdl" />

  <!-- <mix> -->
  <implementation name="IM_mix_float_genmdl" nodedef="ND_mix_float" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_color3_genmdl" nodedef="ND_mix_color3" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_color3_color3_genmdl" nodedef="ND_mix_color3_color3" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_color4_genmdl" nodedef="ND_mix_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_mix_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_color4_color4_genmdl" nodedef="ND_mix_color4_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_mix_color4_color4({{fg}}, {{bg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_vector2_genmdl" nodedef="ND_mix_vector2" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_vector2_vector2_genmdl" nodedef="ND_mix_vector2_vector2" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_vector3_genmdl" nodedef="ND_mix_vector3" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_vector3_vector3_genmdl" nodedef="ND_mix_vector3_vector3" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_vector4_genmdl" nodedef="ND_mix_vector4" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_vector4_vector4_genmdl" nodedef="ND_mix_vector4_vector4" sourcecode="math::lerp({{bg}}, {{fg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_surfaceshader_genmdl" nodedef="ND_mix_surfaceshader" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_mix_surfaceshader({{fg}}, {{bg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_volumeshader_genmdl" nodedef="ND_mix_volumeshader" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_mix_volumeshader({{fg}}, {{bg}}, {{mix}})" target="genmdl" />
  <implementation name="IM_mix_displacementshader_genmdl" nodedef="ND_mix_displacementshader" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_mix_displacementshader({{fg}}, {{bg}}, {{mix}})" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Conditional nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <ifgreater> -->
  <implementation name="IM_ifgreater_float_genmdl" nodedef="ND_ifgreater_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_float({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_integer_genmdl" nodedef="ND_ifgreater_integer" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_integer({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_color3_genmdl" nodedef="ND_ifgreater_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_color3({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_color4_genmdl" nodedef="ND_ifgreater_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_color4({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_vector2_genmdl" nodedef="ND_ifgreater_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_vector2({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_vector3_genmdl" nodedef="ND_ifgreater_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_vector3({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_vector4_genmdl" nodedef="ND_ifgreater_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_vector4({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_matrix33_genmdl" nodedef="ND_ifgreater_matrix33" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_matrix33({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_matrix44_genmdl" nodedef="ND_ifgreater_matrix44" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_matrix44({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_boolean_genmdl" nodedef="ND_ifgreater_boolean" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_boolean({{value1}}, {{value2}})" target="genmdl" />
  <implementation name="IM_ifgreater_floatI_genmdl" nodedef="ND_ifgreater_floatI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_floatI({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_integerI_genmdl" nodedef="ND_ifgreater_integerI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_integerI({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_color3I_genmdl" nodedef="ND_ifgreater_color3I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_color3I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_color4I_genmdl" nodedef="ND_ifgreater_color4I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_color4I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_vector2I_genmdl" nodedef="ND_ifgreater_vector2I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_vector2I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_vector3I_genmdl" nodedef="ND_ifgreater_vector3I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_vector3I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_vector4I_genmdl" nodedef="ND_ifgreater_vector4I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_vector4I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_matrix33I_genmdl" nodedef="ND_ifgreater_matrix33I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_matrix33I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_matrix44I_genmdl" nodedef="ND_ifgreater_matrix44I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_matrix44I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreater_booleanI_genmdl" nodedef="ND_ifgreater_booleanI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreater_booleanI({{value1}}, {{value2}})" target="genmdl" />

  <!-- <ifgreatereq> -->
  <implementation name="IM_ifgreatereq_float_genmdl" nodedef="ND_ifgreatereq_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_float({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_integer_genmdl" nodedef="ND_ifgreatereq_integer" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_integer({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_color3_genmdl" nodedef="ND_ifgreatereq_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_color3({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_color4_genmdl" nodedef="ND_ifgreatereq_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_color4({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_vector2_genmdl" nodedef="ND_ifgreatereq_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_vector2({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_vector3_genmdl" nodedef="ND_ifgreatereq_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_vector3({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_vector4_genmdl" nodedef="ND_ifgreatereq_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_vector4({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_matrix33_genmdl" nodedef="ND_ifgreatereq_matrix33" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_matrix33({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_matrix44_genmdl" nodedef="ND_ifgreatereq_matrix44" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_matrix44({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_boolean_genmdl" nodedef="ND_ifgreatereq_boolean" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_boolean({{value1}}, {{value2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_floatI_genmdl" nodedef="ND_ifgreatereq_floatI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_floatI({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_integerI_genmdl" nodedef="ND_ifgreatereq_integerI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_integerI({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_color3I_genmdl" nodedef="ND_ifgreatereq_color3I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_color3I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_color4I_genmdl" nodedef="ND_ifgreatereq_color4I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_color4I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_vector2I_genmdl" nodedef="ND_ifgreatereq_vector2I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_vector2I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_vector3I_genmdl" nodedef="ND_ifgreatereq_vector3I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_vector3I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_vector4I_genmdl" nodedef="ND_ifgreatereq_vector4I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_vector4I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_matrix33I_genmdl" nodedef="ND_ifgreatereq_matrix33I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_matrix33I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_matrix44I_genmdl" nodedef="ND_ifgreatereq_matrix44I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_matrix44I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifgreatereq_booleanI_genmdl" nodedef="ND_ifgreatereq_booleanI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifgreatereq_booleanI({{value1}}, {{value2}})" target="genmdl" />

  <!-- <ifequal> -->
  <implementation name="IM_ifequal_float_genmdl" nodedef="ND_ifequal_float" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_float({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_integer_genmdl" nodedef="ND_ifequal_integer" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_integer({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_color3_genmdl" nodedef="ND_ifequal_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_color3({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_color4_genmdl" nodedef="ND_ifequal_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_color4({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector2_genmdl" nodedef="ND_ifequal_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector2({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector3_genmdl" nodedef="ND_ifequal_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector3({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector4_genmdl" nodedef="ND_ifequal_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector4({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_matrix33_genmdl" nodedef="ND_ifequal_matrix33" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_matrix33({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_matrix44_genmdl" nodedef="ND_ifequal_matrix44" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_matrix44({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_boolean4_genmdl" nodedef="ND_ifequal_boolean" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_boolean({{value1}}, {{value2}})" target="genmdl" />
  <implementation name="IM_ifequal_floatI_genmdl" nodedef="ND_ifequal_floatI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_floatI({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_integerI_genmdl" nodedef="ND_ifequal_integerI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_integerI({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_color3I_genmdl" nodedef="ND_ifequal_color3I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_color3I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_color4I_genmdl" nodedef="ND_ifequal_color4I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_color4I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector2I_genmdl" nodedef="ND_ifequal_vector2I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector2I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector3I_genmdl" nodedef="ND_ifequal_vector3I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector3I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector4I_genmdl" nodedef="ND_ifequal_vector4I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector4I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_matrix33I_genmdl" nodedef="ND_ifequal_matrix33I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_matrix33I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_matrix44I_genmdl" nodedef="ND_ifequal_matrix44I" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_matrix44I({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_booleanI_genmdl" nodedef="ND_ifequal_booleanI" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_booleanI({{value1}}, {{value2}})" target="genmdl" />
  <implementation name="IM_ifequal_floatB_genmdl" nodedef="ND_ifequal_floatB" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_floatB({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_integerB_genmdl" nodedef="ND_ifequal_integerB" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_integerB({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_color3B_genmdl" nodedef="ND_ifequal_color3B" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_color3B({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_color4B_genmdl" nodedef="ND_ifequal_color4B" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_color4B({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector2B_genmdl" nodedef="ND_ifequal_vector2B" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector2B({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector3B_genmdl" nodedef="ND_ifequal_vector3B" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector3B({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_vector4B_genmdl" nodedef="ND_ifequal_vector4B" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_vector4B({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_matrix33B_genmdl" nodedef="ND_ifequal_matrix33B" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_matrix33B({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_matrix44B_genmdl" nodedef="ND_ifequal_matrix44B" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_matrix44B({{value1}}, {{value2}}, {{in1}}, {{in2}})" target="genmdl" />
  <implementation name="IM_ifequal_booleanB_genmdl" nodedef="ND_ifequal_booleanB" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_ifequal_booleanB({{value1}}, {{value2}})" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Channel nodes                                                            -->
  <!-- ======================================================================== -->

  <!-- <convert> -->
  <implementation name="IM_convert_boolean_float_genmdl" nodedef="ND_convert_boolean_float" target="genmdl" sourcecode="float({{in}})" />
  <implementation name="IM_convert_integer_float_genmdl" nodedef="ND_convert_integer_float" target="genmdl" sourcecode="float({{in}})" />

  <!-- <combine2> -->
  <implementation name="IM_combine2_vector2_genmdl" nodedef="ND_combine2_vector2" target="genmdl" sourcecode="float2( {{in1}},{{in2}} )" />
  <implementation name="IM_combine2_color4CF_genmdl" nodedef="ND_combine2_color4CF" target="genmdl" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_combine2_color4CF({{in1}}, {{in2}})" />
  <implementation name="IM_combine2_vector4VF_genmdl" nodedef="ND_combine2_vector4VF" target="genmdl" sourcecode="float4( {{in1}}[0],{{in1}}[1],{{in1}}[2],{{in2}} )" />
  <implementation name="IM_combine2_vector4VV_genmdl" nodedef="ND_combine2_vector4VV" target="genmdl" sourcecode="float4( {{in1}}[0],{{in1}}[1],{{in2}}[0],{{in2}}[1] )" />

  <!-- <combine3> -->
  <implementation name="IM_combine3_color3_genmdl" nodedef="ND_combine3_color3" target="genmdl" sourcecode="color( {{in1}},{{in2}},{{in3}} )" />
  <implementation name="IM_combine3_vector3_genmdl" nodedef="ND_combine3_vector3" target="genmdl" sourcecode="float3( {{in1}},{{in2}},{{in3}} )" />

  <!-- <combine4> -->
  <implementation name="IM_combine4_color4_genmdl" nodedef="ND_combine4_color4" target="genmdl" sourcecode="materialx::core::mk_color4( {{in1}},{{in2}},{{in3}},{{in4}} )" />
  <implementation name="IM_combine4_vector4_genmdl" nodedef="ND_combine4_vector4" target="genmdl" sourcecode="float4( {{in1}},{{in2}},{{in3}},{{in4}} )" />

  <!-- <creatematrix> -->
  <implementation name="IM_creatematrix_vector3_matrix33_genmdl" nodedef="ND_creatematrix_vector3_matrix33" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_creatematrix_vector3_matrix33({{in1}}, {{in2}}, {{in3}})" target="genmdl" />
  <implementation name="IM_creatematrix_vector3_matrix44_genmdl" nodedef="ND_creatematrix_vector3_matrix44" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_creatematrix_vector3_matrix44({{in1}}, {{in2}}, {{in3}}, {{in4}})" target="genmdl" />
  <implementation name="IM_creatematrix_vector4_matrix44_genmdl" nodedef="ND_creatematrix_vector4_matrix44" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_creatematrix_vector4_matrix44({{in1}}, {{in2}}, {{in3}}, {{in4}})" target="genmdl" />

  <!-- <extract> -->
  <implementation name="IM_extract_color3_genmdl" nodedef="ND_extract_color3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_extract_color3({{in}}, {{index}})" target="genmdl" />
  <implementation name="IM_extract_color4_genmdl" nodedef="ND_extract_color4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_extract_color4({{in}}, {{index}})" target="genmdl" />
  <implementation name="IM_extract_vector2_genmdl" nodedef="ND_extract_vector2" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_extract_vector2({{in}}, {{index}})" target="genmdl" />
  <implementation name="IM_extract_vector3_genmdl" nodedef="ND_extract_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_extract_vector3({{in}}, {{index}})" target="genmdl" />
  <implementation name="IM_extract_vector4_genmdl" nodedef="ND_extract_vector4" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_extract_vector4({{in}}, {{index}})" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Convolution nodes                                                        -->
  <!-- ======================================================================== -->

  <!-- <blur> -->
  <implementation name="IM_blur_float_genmdl" nodedef="ND_blur_float" target="genmdl" />
  <implementation name="IM_blur_color3_genmdl" nodedef="ND_blur_color3" target="genmdl" />
  <implementation name="IM_blur_color4_genmdl" nodedef="ND_blur_color4" target="genmdl" />
  <implementation name="IM_blur_vector2_genmdl" nodedef="ND_blur_vector2" target="genmdl" />
  <implementation name="IM_blur_vector3_genmdl" nodedef="ND_blur_vector3" target="genmdl" />
  <implementation name="IM_blur_vector4_genmdl" nodedef="ND_blur_vector4" target="genmdl" />

  <!-- <heighttonormal> -->
  <implementation name="IM_heighttonormal_vector3_genmdl" nodedef="ND_heighttonormal_vector3" target="genmdl" />

  <!-- ======================================================================== -->
  <!-- Logical operator nodes                                                   -->
  <!-- ======================================================================== -->

  <implementation name="IM_logical_and_genmdl" nodedef="ND_logical_and" target="genmdl" sourcecode="{{in1}} && {{in2}}"/>
  <implementation name="IM_logical_or_genmdl" nodedef="ND_logical_or" target="genmdl" sourcecode="{{in1}} || {{in2}}"/>
  <implementation name="IM_logical_not_genmdl" nodedef="ND_logical_not" target="genmdl" sourcecode="!{{in}}"/>

  <!-- ======================================================================== -->
  <!-- Organization nodes                                                       -->
  <!-- ======================================================================== -->

  <!-- <dot> -->
  <implementation name="IM_dot_float_genmdl" nodedef="ND_dot_float" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_color3_genmdl" nodedef="ND_dot_color3" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_color4_genmdl" nodedef="ND_dot_color4" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_vector2_genmdl" nodedef="ND_dot_vector2" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_vector3_genmdl" nodedef="ND_dot_vector3" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_vector4_genmdl" nodedef="ND_dot_vector4" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_boolean_genmdl" nodedef="ND_dot_boolean" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_integer_genmdl" nodedef="ND_dot_integer" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_matrix33_genmdl" nodedef="ND_dot_matrix33" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_matrix44_genmdl" nodedef="ND_dot_matrix44" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_string_genmdl" nodedef="ND_dot_string" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_filename_genmdl" nodedef="ND_dot_filename" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_surfaceshader_genmdl" nodedef="ND_dot_surfaceshader" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_displacementshader_genmdl" nodedef="ND_dot_displacementshader" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_volumeshader_genmdl" nodedef="ND_dot_volumeshader" sourcecode="{{in}}" target="genmdl" />
  <implementation name="IM_dot_lightshader_genmdl" nodedef="ND_dot_lightshader" sourcecode="{{in}}" target="genmdl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0
  -->

  <!-- ======================================================================== -->
  <!-- Base target definition for MSL targets using shader generation.          -->
  <!-- ======================================================================== -->
  <targetdef name="genmsl" inherit="genglsl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <!--
  Copyright Contributors to the MaterialX Project
  SPDX-License-Identifier: Apache-2.0
-->

  <!-- ======================================================================== -->
  <!-- Target definition for ESSL target. Derives from base GLSL target         -->
  <!-- ======================================================================== -->
  <targetdef name="essl" inherit="genglsl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0
  -->

  <!-- ======================================================================== -->
  <!-- Base target definition for OSL targets using shader generation.          -->
  <!-- ======================================================================== -->
  <targetdef name="genosl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0
  -->

  <!-- ======================================================================== -->
  <!-- Base target definition for GLSL targets using shader generation.         -->
  <!-- ======================================================================== -->
  <targetdef name="genglsl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0
  -->

  <!-- ======================================================================== -->
  <!-- Base target definition for MDL targets using shader generation.          -->
  <!-- ======================================================================== -->
  <targetdef name="genmdl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Graph definitions of standard nodes included in the MaterialX specification.
  -->

  <!-- <glossiness_anisotropy> -->
  <nodegraph name="IMP_glossiness_anisotropy" nodedef="ND_glossiness_anisotropy">
    <invert name="invert1" type="float">
      <input name="in" type="float" interfacename="glossiness" />
    </invert>
    <roughness_anisotropy name="roughness1" type="vector2">
      <input name="roughness" type="float" nodename="invert1" />
      <input name="anisotropy" type="float" interfacename="anisotropy" />
    </roughness_anisotropy>
    <output name="out" type="vector2" nodename="roughness1" />
  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations of standard data types and nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- Data Types                                                               -->
  <!-- ======================================================================== -->

  <typedef name="BSDF" doc="Bidirectional scattering distribution function" />
  <typedef name="EDF" doc="Emission distribution function" />
  <typedef name="VDF" doc="Volume distribution function" />

  <!-- ======================================================================== -->
  <!-- BSDF Nodes                                                               -->
  <!-- ======================================================================== -->

  <!--
    Node: <oren_nayar_diffuse_bsdf>
    A BSDF node for diffuse reflection.
  -->
  <nodedef name="ND_oren_nayar_diffuse_bsdf" node="oren_nayar_diffuse_bsdf" bsdf="R" nodegroup="pbr" doc="A BSDF node for diffuse reflections.">
    <input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="color" type="color3" value="0.18, 0.18, 0.18" />
    <input name="roughness" type="float" value="0.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="energy_compensation" type="boolean" value="false" uniform="true" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <burley_diffuse_bsdf>
    A BSDF node for Burley diffuse reflection.
  -->
  <nodedef name="ND_burley_diffuse_bsdf" node="burley_diffuse_bsdf" bsdf="R" nodegroup="pbr" doc="A BSDF node for Burley diffuse reflections.">
    <input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="color" type="color3" value="0.18, 0.18, 0.18" />
    <input name="roughness" type="float" value="0.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <translucent_bsdf>
    A BSDF node for diffuse transmission.
  -->
  <nodedef name="ND_translucent_bsdf" node="translucent_bsdf" bsdf="R" nodegroup="pbr" doc="A BSDF node for pure diffuse transmission.">
    <input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="color" type="color3" value="1.0, 1.0, 1.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <dielectric_bsdf>
    A reflection/transmission BSDF node based on a microfacet model and a Fresnel curve for dielectrics.
  -->
  <nodedef name="ND_dielectric_bsdf" node="dielectric_bsdf" nodegroup="pbr" doc="A reflection/transmission BSDF node based on a microfacet model and a Fresnel curve for dielectrics.">
    <input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="tint" type="color3" value="1.0, 1.0, 1.0" />
    <input name="ior" type="float" value="1.5" />
    <input name="roughness" type="vector2" value="0.05, 0.05" />
    <input name="thinfilm_thickness" type="float" value="0" unittype="distance" unit="nanometer" />
    <input name="thinfilm_ior" type="float" value="1.5" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" />
    <input name="distribution" type="string" value="ggx" enum="ggx" uniform="true" />
    <input name="scatter_mode" type="string" value="R" enum="R,T,RT" uniform="true" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <conductor_bsdf>
    A reflection BSDF node based on a microfacet model and a Fresnel curve for conductors/metals.
  -->
  <nodedef name="ND_conductor_bsdf" node="conductor_bsdf" bsdf="R" nodegroup="pbr" doc="A reflection BSDF node based on a microfacet model and a Fresnel curve for conductors/metals.">
    <input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="ior" type="color3" value="0.183, 0.421, 1.373" />
    <input name="extinction" type="color3" value="3.424, 2.346, 1.770" />
    <input name="roughness" type="vector2" value="0.05, 0.05" />
    <input name="thinfilm_thickness" type="float" value="0" unittype="distance" unit="nanometer" />
    <input name="thinfilm_ior" type="float" value="1.5" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" />
    <input name="distribution" type="string" value="ggx" enum="ggx" uniform="true" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <generalized_schlick_bsdf>
    A reflection/transmission BSDF node based on a microfacet model and a generalized Schlick Fresnel curve.
  -->
  <nodedef name="ND_generalized_schlick_bsdf" node="generalized_schlick_bsdf" nodegroup="pbr" doc="A reflection/transmission BSDF node based on a microfacet model and a generalized Schlick Fresnel curve.">
    <input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="color0" type="color3" value="1.0, 1.0, 1.0" />
    <input name="color82" type="color3" value="1.0, 1.0, 1.0" />
    <input name="color90" type="color3" value="1.0, 1.0, 1.0" />
    <input name="exponent" type="float" value="5.0" />
    <input name="roughness" type="vector2" value="0.05, 0.05" />
    <input name="thinfilm_thickness" type="float" value="0" unittype="distance" unit="nanometer" />
    <input name="thinfilm_ior" type="float" value="1.5" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" />
    <input name="distribution" type="string" value="ggx" enum="ggx" uniform="true" />
    <input name="scatter_mode" type="string" value="R" enum="R,T,RT" uniform="true" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <subsurface_bsdf>
    A subsurface scattering BSDF for true subsurface scattering.
  -->
  <nodedef name="ND_subsurface_bsdf" node="subsurface_bsdf" bsdf="R" nodegroup="pbr" doc="A subsurface scattering BSDF for true subsurface scattering.">
    <input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="color" type="color3" value="0.18, 0.18, 0.18" />
    <input name="radius" type="color3" value="1.0, 1.0, 1.0" />
    <input name="anisotropy" type="float" value="0.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <sheen_bsdf>
    A microfacet BSDF for the back-scattering properties of cloth-like materials.
  -->
  <nodedef name="ND_sheen_bsdf" node="sheen_bsdf" bsdf="R" nodegroup="pbr" doc="A microfacet BSDF for the back-scattering properties of cloth-like materials.">
    <input name="weight" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="color" type="color3" value="1.0, 1.0, 1.0" />
    <input name="roughness" type="float" value="0.3" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="mode" type="string" value="conty_kulla" enum="conty_kulla, zeltner" uniform="true" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <chiang_hair_bsdf>
    A BSDF node for Chiang hair shading model.
  -->
  <nodedef name="ND_chiang_hair_bsdf" node="chiang_hair_bsdf" bsdf="R" nodegroup="pbr" doc="A BSDF node for Chiang hair shading model.">
    <input name="tint_R" type="color3" value="1, 1, 1" />
    <input name="tint_TT" type="color3" value="1, 1, 1" />
    <input name="tint_TRT" type="color3" value="1, 1, 1" />
    <input name="ior" type="float" value="1.55" />
    <input name="roughness_R" type="vector2" value="0.1, 0.1" />
    <input name="roughness_TT" type="vector2" value="0.05, 0.05" />
    <input name="roughness_TRT" type="vector2" value="0.2, 0.2" />
    <input name="cuticle_angle" type="float" value="0.5" />
    <input name="absorption_coefficient" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="curve_direction" type="vector3" defaultgeomprop="Tworld" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- EDF Nodes                                                                -->
  <!-- ======================================================================== -->

  <!--
    Node: <uniform_edf>
    An EDF node for uniform emission.
  -->
  <nodedef name="ND_uniform_edf" node="uniform_edf" nodegroup="pbr" doc="An EDF node for uniform emission.">
    <input name="color" type="color3" value="1.0, 1.0, 1.0" />
    <output name="out" type="EDF" />
  </nodedef>

  <!--
    Node: <conical_edf>
    Constructs an EDF emitting light inside a cone around the normal direction.
  -->
  <nodedef name="ND_conical_edf" node="conical_edf" nodegroup="pbr" doc="Constructs an EDF emitting light inside a cone around the normal direction.">
    <input name="color" type="color3" value="1.0, 1.0, 1.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="inner_angle" type="float" value="60.0" />
    <input name="outer_angle" type="float" value="0.0" />
    <output name="out" type="EDF" />
  </nodedef>

  <!--
    Node: <measured_edf>
    Constructs an EDF emitting light according to a measured IES light profile.
  -->
  <nodedef name="ND_measured_edf" node="measured_edf" nodegroup="pbr" doc="Constructs an EDF emitting light according to a measured IES light profile.">
    <input name="color" type="color3" value="1.0, 1.0, 1.0" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="file" type="filename" value="" uniform="true" />
    <output name="out" type="EDF" />
  </nodedef>

  <!--
    Node: <generalized_schlick_edf>
    Modifies an EDF with a directional factor. Attenuates the emission distribution of the base EDF according to
    a generalized Schlick fresnel function.
  -->
  <nodedef name="ND_generalized_schlick_edf" node="generalized_schlick_edf" nodegroup="pbr" doc="Modifies an EDF with a directional factor.">
    <input name="color0" type="color3" value="1.0, 1.0, 1.0" />
    <input name="color90" type="color3" value="1.0, 1.0, 1.0" />
    <input name="exponent" type="float" value="5.0" />
    <input name="base" type="EDF" value="" />
    <output name="out" type="EDF" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- VDF Nodes                                                                -->
  <!-- ======================================================================== -->

  <!--
    Node: <absorption_vdf>
    Constructs a VDF for pure light absorption.
  -->
  <nodedef name="ND_absorption_vdf" node="absorption_vdf" nodegroup="pbr" doc="Constructs a VDF for pure light absorption.">
    <input name="absorption" type="vector3" value="0.0, 0.0, 0.0" />
    <output name="out" type="VDF" />
  </nodedef>

  <!--
    Node: <anisotropic_vdf>
    Constructs a VDF scattering light for a participating medium, based on the
    Henyey-Greenstein phase function.
  -->
  <nodedef name="ND_anisotropic_vdf" node="anisotropic_vdf" nodegroup="pbr" doc="Constructs a VDF scattering light for a participating medium, based on the Henyey-Greenstein phase function.">
    <input name="absorption" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="scattering" type="vector3" value="0.0, 0.0, 0.0" />
    <input name="anisotropy" type="float" value="0.0" />
    <output name="out" type="VDF" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Shader Nodes                                                             -->
  <!-- ======================================================================== -->

  <!--
    Node: <surface>
    Construct a surface shader from scattering and emission distribution functions.
  -->
  <nodedef name="ND_surface" node="surface" nodegroup="pbr" doc="A constructor node for the surfaceshader type.">
    <input name="bsdf" type="BSDF" value="" doc="Distribution function for surface scattering." />
    <input name="edf" type="EDF" value="" doc="Distribution function for surface emission." />
    <input name="opacity" type="float" value="1.0" doc="Surface cutout opacity" />
    <input name="thin_walled" type="boolean" value="false" uniform="true" doc="Option to make the surface thin-walled." />
    <output name="out" type="surfaceshader" />
  </nodedef>

  <!--
    Node: <volume>
    Construct a volume shader describing a participating medium.
  -->
  <nodedef name="ND_volume" node="volume" nodegroup="pbr" doc="A constructor node for the volumeshader type.">
    <input name="vdf" type="VDF" value="" doc="Volume distribution function for the medium." />
    <input name="edf" type="EDF" value="" doc="Emission distribution function for the medium." />
    <output name="out" type="volumeshader" />
  </nodedef>

  <!--
    Node: <light>
    Construct a light shader from emission distribution functions.
  -->
  <nodedef name="ND_light" node="light" nodegroup="pbr" doc="A constructor node for the lightshader type.">
    <input name="edf" type="EDF" value="" doc="Distribution function for light emission." />
    <input name="intensity" type="float" value="1.0" doc="Multiplier for the light intensity" />
    <input name="exposure" type="float" value="0.0" doc="Exposure control for the light intensity" />
    <output name="out" type="lightshader" />
  </nodedef>

  <!--
    Node: <displacement>
    Construct a displacement shader.
  -->
  <nodedef name="ND_displacement_float" node="displacement" nodegroup="pbr" doc="A constructor node for the displacementshader type.">
    <input name="displacement" type="float" value="0.0" doc="Scalar displacement amount along the surface normal direction." />
    <input name="scale" type="float" value="1.0" doc="Scale factor for the displacement vector" />
    <output name="out" type="displacementshader" />
  </nodedef>
  <nodedef name="ND_displacement_vector3" node="displacement" nodegroup="pbr" doc="A constructor node for the displacementshader type.">
    <input name="displacement" type="vector3" value="0.0, 0.0, 0.0" doc="Vector displacement in (dPdu, dPdv, N) tangent/normal space." />
    <input name="scale" type="float" value="1.0" doc="Scale factor for the displacement vector" />
    <output name="out" type="displacementshader" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- Utility Nodes                                                            -->
  <!-- ======================================================================== -->

  <!--
    Node: <layer>
  -->
  <nodedef name="ND_layer_bsdf" node="layer" nodegroup="pbr" defaultinput="top" doc="Layer two BSDF's with vertical layering.">
    <input name="top" type="BSDF" value="" />
    <input name="base" type="BSDF" value="" />
    <output name="out" type="BSDF" />
  </nodedef>
  <nodedef name="ND_layer_vdf" node="layer" nodegroup="pbr" defaultinput="top" doc="Layer a BSDF over a VDF describing the interior media.">
    <input name="top" type="BSDF" value="" />
    <input name="base" type="VDF" value="" />
    <output name="out" type="BSDF" />
  </nodedef>

  <!--
    Node: <mix>
  -->
  <nodedef name="ND_mix_bsdf" node="mix" nodegroup="pbr" defaultinput="bg" doc="Mix two BSDF's according to an input mix amount.">
    <input name="fg" type="BSDF" value="" />
    <input name="bg" type="BSDF" value="" />
    <input name="mix" type="float" value="0.0" uimin="0.0" uimax="1.0" doc="Mixing weight, range [0, 1]." />
    <output name="out" type="BSDF" />
  </nodedef>
  <nodedef name="ND_mix_edf" node="mix" nodegroup="pbr" defaultinput="bg" doc="Mix two EDF's according to an input mix amount.">
    <input name="fg" type="EDF" value="" />
    <input name="bg" type="EDF" value="" />
    <input name="mix" type="float" value="0.0" uimin="0.0" uimax="1.0" doc="Mixing weight, range [0, 1]." />
    <output name="out" type="EDF" />
  </nodedef>
  <nodedef name="ND_mix_vdf" node="mix" nodegroup="pbr" defaultinput="bg" doc="Mix two VDF's according to an input mix amount.">
    <input name="fg" type="VDF" value="" />
    <input name="bg" type="VDF" value="" />
    <input name="mix" type="float" value="0.0" uimin="0.0" uimax="1.0" doc="Mixing weight, range [0, 1]." />
    <output name="out" type="VDF" />
  </nodedef>

  <!--
    Node: <add>
  -->
  <nodedef name="ND_add_bsdf" node="add" nodegroup="pbr" defaultinput="bg" doc="A node for additive blending of BSDF's.">
    <input name="in1" type="BSDF" value="" doc="First BSDF." />
    <input name="in2" type="BSDF" value="" doc="Second BSDF." />
    <output name="out" type="BSDF" />
  </nodedef>
  <nodedef name="ND_add_edf" node="add" nodegroup="pbr" defaultinput="bg" doc="A node for additive blending of EDF's.">
    <input name="in1" type="EDF" value="" doc="First EDF." />
    <input name="in2" type="EDF" value="" doc="Second EDF." />
    <output name="out" type="EDF" />
  </nodedef>
  <nodedef name="ND_add_vdf" node="add" nodegroup="pbr" defaultinput="bg" doc="A node for additive blending of VDF's.">
    <input name="in1" type="VDF" value="" doc="First VDF." />
    <input name="in2" type="VDF" value="" doc="Second VDF." />
    <output name="out" type="VDF" />
  </nodedef>

  <!--
    Node: <multiply>
  -->
  <nodedef name="ND_multiply_bsdfC" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of a BSDF with a weight.">
    <input name="in1" type="BSDF" value="" doc="The BSDF to scale." />
    <input name="in2" type="color3" value="1.0, 1.0, 1.0" doc="Scaling weight." />
    <output name="out" type="BSDF" />
  </nodedef>
  <nodedef name="ND_multiply_bsdfF" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of a BSDF with a weight.">
    <input name="in1" type="BSDF" value="" doc="The BSDF to scale." />
    <input name="in2" type="float" value="1.0" doc="Scaling weight." />
    <output name="out" type="BSDF" />
  </nodedef>
  <nodedef name="ND_multiply_edfC" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of an EDF with a weight.">
    <input name="in1" type="EDF" value="" doc="The EDF to scale." />
    <input name="in2" type="color3" value="1.0, 1.0, 1.0" doc="Scaling weight." />
    <output name="out" type="EDF" />
  </nodedef>
  <nodedef name="ND_multiply_edfF" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of an EDF with a weight.">
    <input name="in1" type="EDF" value="" doc="The EDF to scale." />
    <input name="in2" type="float" value="1.0" doc="Scaling weight." />
    <output name="out" type="EDF" />
  </nodedef>
  <nodedef name="ND_multiply_vdfC" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of an VDF with a weight.">
    <input name="in1" type="VDF" value="" doc="The VDF to scale." />
    <input name="in2" type="color3" value="1.0, 1.0, 1.0" doc="Scaling weight." />
    <output name="out" type="VDF" />
  </nodedef>
  <nodedef name="ND_multiply_vdfF" node="multiply" nodegroup="pbr" defaultinput="in1" doc="A node for adjusting the contribution of an VDF with a weight.">
    <input name="in1" type="VDF" value="" doc="The VDF to scale." />
    <input name="in2" type="float" value="1.0" doc="Scaling weight." />
    <output name="out" type="VDF" />
  </nodedef>

  <!--
    Node: <roughness_anisotropy>
    Calculates anisotropic surface roughness from a scalar roughness and anisotropy parameterization.
  -->
  <nodedef name="ND_roughness_anisotropy" node="roughness_anisotropy" nodegroup="pbr" doc="Calculates anisotropic surface roughness from a scalar roughness/anisotropy parameterization.">
    <input name="roughness" type="float" value="0.0" />
    <input name="anisotropy" type="float" value="0.0" />
    <output name="out" type="vector2" />
  </nodedef>

  <!--
    Node: <roughness_dual>
    Calculates anisotropic surface roughness from a dual surface roughness parameterization.
  -->
  <nodedef name="ND_roughness_dual" node="roughness_dual" nodegroup="pbr" doc="Calculates anisotropic surface roughness from a dual surface roughness parameterization.">
    <input name="roughness" type="vector2" value="0.0, 0.0" />
    <output name="out" type="vector2" />
  </nodedef>

  <!--
    Node: <glossiness_anisotropy>
    Calculates anisotropic surface roughness from a scalar glossiness and anisotropy parameterization.
  -->
  <nodedef name="ND_glossiness_anisotropy" node="glossiness_anisotropy" nodegroup="pbr" doc="Calculates anisotropic surface roughness from a scalar glossiness/anisotropy parameterization.">
    <input name="glossiness" type="float" value="1.0" uimin="0.0" uimax="1.0" />
    <input name="anisotropy" type="float" value="0.0" uimin="0.0" uimax="1.0" />
    <output name="out" type="vector2" />
  </nodedef>

  <!--
    Node: <blackbody>
    Returns the radiant emittance of a blackbody radiator with the given temperature.
  -->
  <nodedef name="ND_blackbody" node="blackbody" nodegroup="pbr" doc="Returns the radiant emittance of a blackbody radiator with the given temperature.">
    <input name="temperature" type="float" value="5000.0" />
    <output name="out" type="color3" />
  </nodedef>

  <!--
    Node: <artistic_ior>
    Converts the artistic parameterization reflectivity and edge_color to  complex IOR values.
  -->
  <nodedef name="ND_artistic_ior" node="artistic_ior" nodegroup="pbr" doc="Converts the artistic parameterization reflectivity and edge_color to  complex IOR values.">
    <input name="reflectivity" type="color3" value="0.944, 0.776, 0.373" colorspace="lin_rec709" />
    <input name="edge_color" type="color3" value="0.998, 0.981, 0.751" colorspace="lin_rec709" />
    <output name="ior" type="color3" />
    <output name="extinction" type="color3" />
  </nodedef>

  <!--
    Node: <deon_hair_absorption_from_melanin>
    Calculates hair absorption from melanin parameters.
  -->
  <nodedef name="ND_deon_hair_absorption_from_melanin" node="deon_hair_absorption_from_melanin" nodegroup="pbr" doc="Calculates hair absorption from melanin parameters.">
    <input name="melanin_concentration" type="float" value="0.25" />
    <input name="melanin_redness" type="float" value="0.5" />
    <input name="eumelanin_color" type="color3" value="0.657704, 0.498077, 0.254107" colorspace="lin_rec709" doc="constant from d'Eon et al. 2011, converted to color via exp(-c)" uiadvanced="true"/>
    <input name="pheomelanin_color" type="color3" value="0.829444, 0.67032, 0.349938" colorspace="lin_rec709" doc="constant from d'Eon et al. 2011, converted to color via exp(-c)" uiadvanced="true"/>
    <output name="absorption" type="vector3" />
  </nodedef>

  <!--
    Node: <chiang_hair_absorption_from_color>
    Calculates hair absorption from a color.
  -->
  <nodedef name="ND_chiang_hair_absorption_from_color" node="chiang_hair_absorption_from_color" nodegroup="pbr" doc="Calculates hair absorption from a color.">
    <input name="color" type="color3" value="1.0, 1.0, 1.0" />
    <input name="azimuthal_roughness" type="float" value="0.2" />
    <output name="absorption" type="vector3" />
  </nodedef>

  <!--
    Node: <chiang_hair_roughness>
    Calculates hair roughness for R, TT and TRT component.
  -->
  <nodedef name="ND_chiang_hair_roughness" node="chiang_hair_roughness" nodegroup="pbr" doc="Calculates hair roughness for R, TT and TRT component.">
    <input name="longitudinal" type="float" value="0.1" />
    <input name="azimuthal" type="float" value="0.2" />
    <input name="scale_TT" type="float" value="0.5" uiadvanced="true" />
    <input name="scale_TRT" type="float" value="2.0" uiadvanced="true" />
    <output name="roughness_R" type="vector2" />
    <output name="roughness_TT" type="vector2" />
    <output name="roughness_TRT" type="vector2" />
  </nodedef>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <!-- <surface> -->
  <implementation name="IM_surface_genmsl" nodedef="ND_surface" target="genmsl" />

  <!-- <light> -->
  <implementation name="IM_light_genmsl" nodedef="ND_light" target="genmsl" />

</materialx>
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet_diffuse.glsl"

void mx_subsurface_bsdf(ClosureData closureData, float weight, vec3 color, vec3 radius, float anisotropy, vec3 N, inout BSDF bsdf)
{
    bsdf.throughput = vec3(0.0);

    if (weight < M_FLOAT_EPS)
    {
        return;
    }

    vec3 V = closureData.V;
    vec3 L = closureData.L;
    vec3 P = closureData.P;
    float occlusion = closureData.occlusion;

    N = mx_forward_facing_normal(N, V);

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        vec3 sss = mx_subsurface_scattering_approx(N, L, P, color, radius);
        float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
        float visibleOcclusion = 1.0 - NdotL * (1.0 - occlusion);
        bsdf.response = sss * visibleOcclusion * weight;
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        // For now, we render indirect subsurface as simple indirect diffuse.
        vec3 Li = mx_environment_irradiance(N);
        bsdf.response = Li * color * weight;
    }
}
void mx_displacement_vector3(vec3 disp, float scale, out displacementshader result)
{
    result.offset = disp;
    result.scale = scale;
}
#include "lib/mx_closure_type.glsl"

void mx_anisotropic_vdf(ClosureData closureData, vec3 absorption, vec3 scattering, float anisotropy, inout BSDF bsdf)
{
    // TODO: Add some approximation for volumetric light absorption.
}
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet_specular.glsl"

void mx_generalized_schlick_bsdf(ClosureData closureData, float weight, vec3 color0, vec3 color82, vec3 color90, float exponent, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
    if (weight < M_FLOAT_EPS)
    {
        return;
    }
    if (closureData.closureType != CLOSURE_TYPE_TRANSMISSION && scatter_mode == 1)
    {
        return;
    }

    vec3 V = closureData.V;
    vec3 L = closureData.L;

    N = mx_forward_facing_normal(N, V);
    float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);

    vec3 safeColor0 = max(color0, 0.0);
    vec3 safeColor82 = max(color82, 0.0);
    vec3 safeColor90 = max(color90, 0.0);
    FresnelData fd = mx_init_fresnel_schlick(safeColor0, safeColor82, safeColor90, exponent, thinfilm_thickness, thinfilm_ior);

    vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
    float avgAlpha = mx_average_alpha(safeAlpha);

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        X = normalize(X - dot(X, N) * N);
        vec3 Y = cross(N, X);
        vec3 H = normalize(L + V);

        float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
        float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);

        vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));

        vec3  F = mx_compute_fresnel(VdotH, fd);
        float D = mx_ggx_NDF(Ht, safeAlpha);
        float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);

        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
        vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
        float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
        bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);

        // Note: NdotL is cancelled out
        bsdf.response = D * F * G * comp * closureData.occlusion * weight / (4.0 * NdotV);
    }
    else if (closureData.closureType == CLOSURE_TYPE_TRANSMISSION)
    {
        vec3 F = mx_compute_fresnel(NdotV, fd);

        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
        vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
        float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
        bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);

        if (scatter_mode != 0)
        {
            float avgF0 = dot(safeColor0, vec3(1.0 / 3.0));
            fd.ior = vec3(mx_f0_to_ior(avgF0));
            bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, vec3(1.0)) * weight;
        }
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        vec3 F = mx_compute_fresnel(NdotV, fd);

        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
        vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
        float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
        bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);

        vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd);
        bsdf.response = Li * comp * weight;
    }
}
#include "lib/mx_closure_type.glsl"

void mx_multiply_edf_color3(ClosureData closureData, EDF in1, vec3 in2, out EDF result)
{
    result = in1 * in2;
}
void mx_displacement_float(float disp, float scale, out displacementshader result)
{
    result.offset = vec3(disp);
    result.scale = scale;
}
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet_specular.glsl"

// https://eugenedeon.com/pdfs/egsrhair.pdf
void mx_deon_hair_absorption_from_melanin(
    float melanin_concentration,
    float melanin_redness,
    // constants converted to color via exp(-c). the defaults are lin_rec709 colors, they may be
    // transformed to scene-linear rendering color space.
    vec3 eumelanin_color,    // default: (0.657704, 0.498077, 0.254106) == exp(-(0.419, 0.697, 1.37))
    vec3 pheomelanin_color,  // default: (0.829443, 0.670320, 0.349937) == exp(-(0.187, 0.4, 1.05))
    out vec3 absorption)
{
    float melanin = -log(max(1.0 - melanin_concentration, 0.0001));
    float eumelanin = melanin * (1.0 - melanin_redness);
    float pheomelanin = melanin * melanin_redness;
    absorption = max(
        eumelanin * -log(eumelanin_color) + pheomelanin * -log(pheomelanin_color), 
        vec3(0.0)
    );
}

// https://media.disneyanimation.com/uploads/production/publication_asset/152/asset/eurographics2016Fur_Smaller.pdf
void mx_chiang_hair_absorption_from_color(vec3 color, float betaN, out vec3 absorption)
{
    float b2 = betaN* betaN;
    float b4 = b2 * b2;
    float b_fac = 
        5.969 - 
        (0.215 * betaN) + 
        (2.532 * b2) -
        (10.73 * b2 * betaN) + 
        (5.574 * b4) +
        (0.245 * b4 * betaN);
    vec3 sigma = log(min(max(color, 0.001), vec3(1.0))) / b_fac;
    absorption = sigma * sigma;
}

void mx_chiang_hair_roughness(
    float longitudinal,
    float azimuthal,
    float scale_TT,   // empirical roughness scale from Marschner et al. (2003).
    float scale_TRT,  // default: scale_TT = 0.5, scale_TRT = 2.0
    out vec2 roughness_R,
    out vec2 roughness_TT,
    out vec2 roughness_TRT
)
{
    float lr = clamp(longitudinal, 0.001, 1.0);
    float ar = clamp(azimuthal, 0.001, 1.0);

    // longitudinal variance
    float v = 0.726 * lr + 0.812 * lr * lr + 3.7 * pow(lr, 20.0);
    v = v * v;

    float s = 0.265 * ar + 1.194 * ar * ar + 5.372 * pow(ar, 22.0);

    roughness_R = vec2(v, s);
    roughness_TT = vec2(v * scale_TT * scale_TT, s);
    roughness_TRT = vec2(v * scale_TRT * scale_TRT, s);
}

float mx_hair_transform_sin_cos(float x)
{
    return sqrt(max(1.0 - x * x, 0.0));
}

float mx_hair_I0(float x)
{
    float v = 1.0;
    float n = 1.0;
    float d = 1.0;
    float f = 1.0;
    float x2 = x * x;
    for (int i = 0; i < 9 ; ++i)
    {
        d *= 4.0 * (f * f);
        n *= x2;
        v += n / d;
        f += 1.0;
    }
    return v;
}

float mx_hair_log_I0(float x)
{
    if (x > 12.0)
        return x + 0.5 * (-log(2.0 * M_PI) + log(1.0 / x) + 1.0 / (8.0 * x));
    else
        return log(mx_hair_I0(x));
}

float mx_hair_logistic(float x, float s)
{
    if (x > 0.0)
        x = -x;
    float f = exp(x / s);
    return f / (s * (1.0 + f) * (1.0 + f));
}

float mx_hair_logistic_cdf(float x, float s)
{
    return 1.0 / (1.0 + exp(-x / s));
}

float mx_hair_trimmed_logistic(float x, float s, float a, float b)
{
    // the constant can be found in Chiang et al. (2016) Appendix A, eq. (12)
    s *= 0.626657;  // sqrt(M_PI/8)
    return mx_hair_logistic(x, s) / (mx_hair_logistic_cdf(b, s) - mx_hair_logistic_cdf(a, s));
}

float mx_hair_phi(int p, float gammaO, float gammaT)
{
    float fP = float(p);
    return 2.0 * fP * gammaT - 2.0 * gammaO + fP * M_PI;
}

float mx_hair_longitudinal_scattering(  // Mp
    float sinThetaI,
    float cosThetaI,
    float sinThetaO,
    float cosThetaO,
    float v
)
{
    float inv_v = 1.0 / v;
    float a = cosThetaO * cosThetaI * inv_v;
    float b = sinThetaO * sinThetaI * inv_v;
    if (v < 0.1)
        return exp(mx_hair_log_I0(a) - b - inv_v + 0.6931 + log(0.5 * inv_v));
    else
        return ((exp(-b) * mx_hair_I0(a)) / (2.0 * v * sinh(inv_v)));
}

float mx_hair_azimuthal_scattering(  // Np
    float phi,
    int p,
    float s,
    float gammaO,
    float gammaT
)
{
    if (p >= 3)
        return float(0.5 / M_PI);

    float dphi = phi - mx_hair_phi(p, gammaO, gammaT);
    if (isinf(dphi))
        return float(0.5 / M_PI);

    while (dphi > M_PI)    dphi -= (2.0 * M_PI);
    while (dphi < (-M_PI)) dphi += (2.0 * M_PI);

    return mx_hair_trimmed_logistic(dphi, s, -M_PI, M_PI);
}

void mx_hair_alpha_angles(
    float alpha,
    float sinThetaI,
    float cosThetaI,
    out vec2 angles[4]
)
{
    // 0:R, 1:TT, 2:TRT, 3:TRRT+
    for (int i = 0; i <= 3; ++i)
    {
        if (alpha == 0.0 || i == 3)
            angles[i] = vec2(sinThetaI, cosThetaI);
        else
        {
            float m = 2.0 - float(i) * 3.0;
            float sa = sin(m * alpha);
            float ca = cos(m * alpha);
            angles[i].x = sinThetaI * ca + cosThetaI * sa;
            angles[i].y = cosThetaI * ca - sinThetaI * sa;
        }
    }
}

void mx_hair_attenuation(float f, vec3 T, out vec3 Ap[4])  // Ap
{
    // 0:R, 1:TT, 2:TRT, 3:TRRT+
    Ap[0] = vec3(f);
    Ap[1] = (1.0 - f) * (1.0 - f) * T;
    Ap[2] = Ap[1] * T * f;
    Ap[3] = Ap[2] * T * f / (vec3(1.0) - T * f);
}

void mx_chiang_hair_bsdf(ClosureData closureData, vec3 tint_R, vec3 tint_TT, vec3 tint_TRT, float ior,
                         vec2 roughness_R, vec2 roughness_TT, vec2 roughness_TRT, float cuticle_angle,
                         vec3 absorption_coefficient, vec3 N, vec3 X, inout BSDF bsdf)
{
    vec3 V = closureData.V;
    vec3 L = closureData.L;

    N = mx_forward_facing_normal(N, V);

    bsdf.throughput = vec3(0.0);

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        X = normalize(X - dot(X, N) * N);
        vec3 Y = cross(N, X);

        float sinThetaO = dot(V, X);
        float sinThetaI = dot(L, X);
        float cosThetaO = mx_hair_transform_sin_cos(sinThetaO);
        float cosThetaI = mx_hair_transform_sin_cos(sinThetaI);

        float y1 = dot(L, N);
        float x1 = dot(L, Y);
        float y2 = dot(V, N);
        float x2 = dot(V, Y);
        float phi = mx_atan(y1 * x2 - y2 * x1, x1 * x2 + y1 * y2);

        vec3 k1_p = normalize(V - X * dot(V, X));
        float cosGammaO = dot(N, k1_p);
        float sinGammaO = mx_hair_transform_sin_cos(cosGammaO);
        if (dot(k1_p, Y) > 0.0)
            sinGammaO = -sinGammaO;
        float gammaO = asin(sinGammaO);

        float sinThetaT = sinThetaO / ior;
        float cosThetaT = mx_hair_transform_sin_cos(sinThetaT);
        float etaP = sqrt(max(ior * ior - sinThetaO * sinThetaO, 0.0)) / max(cosThetaO, M_FLOAT_EPS);
        float sinGammaT = max(min(sinGammaO / etaP, 1.0), -1.0);
        float cosGammaT = sqrt(1.0 - sinGammaT * sinGammaT);
        float gammaT = asin(sinGammaT);

        // attenuation
        vec3 Ap[4];
        float fresnel = mx_fresnel_dielectric(cosThetaO * cosGammaO, ior);
        vec3 T = exp(-absorption_coefficient * (2.0 * cosGammaT / cosThetaT));
        mx_hair_attenuation(fresnel, T, Ap);

        // parameters for each lobe
        vec2 angles[4];
        float alpha = cuticle_angle * M_PI - (M_PI / 2.0);  // remap [0, 1] to [-PI/2, PI/2]
        mx_hair_alpha_angles(alpha, sinThetaI, cosThetaI, angles);

        vec3 tint[4];
        tint[0] = tint_R;
        tint[1] = tint_TT;
        tint[2] = tint_TRT;
        tint[3] = tint_TRT;

        roughness_R = clamp(roughness_R, 0.001, 1.0);
        roughness_TT = clamp(roughness_TT, 0.001, 1.0);
        roughness_TRT = clamp(roughness_TRT, 0.001, 1.0);

        vec2 vs[4];
        vs[0] = roughness_R;
        vs[1] = roughness_TT;
        vs[2] = roughness_TRT;
        vs[3] = roughness_TRT;

        // R, TT, TRT, TRRT+
        vec3 F = vec3(0.0);
        for (int i = 0; i <= 3; ++i)
        {
            tint[i] = max(tint[i], vec3(0.0));
            float Mp = mx_hair_longitudinal_scattering(angles[i].x, angles[i].y, sinThetaO, cosThetaO, vs[i].x);
            float Np = (i == 3) ?  (1.0 / 2.0 * M_PI) : mx_hair_azimuthal_scattering(phi, i, vs[i].y, gammaO, gammaT);
            F += Mp * Np * tint[i] * Ap[i];
        }

        bsdf.response = F * closureData.occlusion * M_PI_INV;
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        // This indirect term is a *very* rough approximation.

        float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
        FresnelData fd = mx_init_fresnel_dielectric(ior, 0.0, 1.0);
        vec3 F = mx_compute_fresnel(NdotV, fd);

        vec2 roughness = (roughness_R + roughness_TT + roughness_TRT) / vec2(3.0);  // ?
        vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
        float avgAlpha = mx_average_alpha(safeAlpha);

        // Use GGX to match the behavior of mx_environment_radiance.
        float F0 = mx_ior_to_f0(ior);
        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
        vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;

        vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, 0, fd);
        vec3 tint = (tint_R + tint_TT + tint_TRT) / vec3(3.0);  // ?

        bsdf.response = Li * comp * tint;
    }
}
<?xml version="1.0"?>
<materialx version="1.39">

  <!-- <oren_nayar_diffuse_bsdf> -->
  <implementation name="IM_oren_nayar_diffuse_bsdf_genglsl" nodedef="ND_oren_nayar_diffuse_bsdf" file="mx_oren_nayar_diffuse_bsdf.glsl" function="mx_oren_nayar_diffuse_bsdf" target="genglsl" />

  <!-- <burley_diffuse_bsdf> -->
  <implementation name="IM_burley_diffuse_bsdf_genglsl" nodedef="ND_burley_diffuse_bsdf" file="mx_burley_diffuse_bsdf.glsl" function="mx_burley_diffuse_bsdf" target="genglsl" />

  <!-- <translucent_bsdf> -->
  <implementation name="IM_translucent_bsdf_genglsl" nodedef="ND_translucent_bsdf" file="mx_translucent_bsdf.glsl" function="mx_translucent_bsdf" target="genglsl" />

  <!-- <dielectric_bsdf> -->
  <implementation name="IM_dielectric_bsdf_genglsl" nodedef="ND_dielectric_bsdf" file="mx_dielectric_bsdf.glsl" function="mx_dielectric_bsdf" target="genglsl" />

  <!-- <conductor_bsdf> -->
  <implementation name="IM_conductor_bsdf_genglsl" nodedef="ND_conductor_bsdf" file="mx_conductor_bsdf.glsl" function="mx_conductor_bsdf" target="genglsl" />

  <!-- <generalized_schlick_bsdf> -->
  <implementation name="IM_generalized_schlick_bsdf_genglsl" nodedef="ND_generalized_schlick_bsdf" file="mx_generalized_schlick_bsdf.glsl" function="mx_generalized_schlick_bsdf" target="genglsl" />

  <!-- <subsurface_bsdf> -->
  <implementation name="IM_subsurface_bsdf_genglsl" nodedef="ND_subsurface_bsdf" file="mx_subsurface_bsdf.glsl" function="mx_subsurface_bsdf" target="genglsl" />

  <!-- <sheen_bsdf> -->
  <implementation name="IM_sheen_bsdf_genglsl" nodedef="ND_sheen_bsdf" file="mx_sheen_bsdf.glsl" function="mx_sheen_bsdf" target="genglsl" />

  <!-- <chiang_hair_bsdf> -->
  <implementation name="IM_chiang_hair_bsdf_genglsl" nodedef="ND_chiang_hair_bsdf" file="mx_chiang_hair_bsdf.glsl" function="mx_chiang_hair_bsdf" target="genglsl" />

  <!-- <anisotropic_vdf> -->
  <implementation name="IM_anisotropic_vdf_genglsl" nodedef="ND_anisotropic_vdf" file="mx_anisotropic_vdf.glsl" function="mx_anisotropic_vdf" target="genglsl" />

  <!-- <layer> -->
  <implementation name="IM_layer_bsdf_genglsl" nodedef="ND_layer_bsdf" file="mx_layer_bsdf.glsl" function="mx_layer_bsdf" target="genglsl" />
  <implementation name="IM_layer_vdf_genglsl" nodedef="ND_layer_vdf" file="mx_layer_vdf.glsl" function="mx_layer_vdf" target="genglsl" />

  <!-- <mix> -->
  <implementation name="IM_mix_bsdf_genglsl" nodedef="ND_mix_bsdf" file="mx_mix_bsdf.glsl" function="mx_mix_bsdf" target="genglsl" />
  <implementation name="IM_mix_edf_genglsl" nodedef="ND_mix_edf" file="mx_mix_edf.glsl" function="mx_mix_edf" target="genglsl" />

  <!-- <add> -->
  <implementation name="IM_add_bsdf_genglsl" nodedef="ND_add_bsdf" file="mx_add_bsdf.glsl" function="mx_add_bsdf" target="genglsl" />
  <implementation name="IM_add_edf_genglsl" nodedef="ND_add_edf" file="mx_add_edf.glsl" function="mx_add_edf" target="genglsl" />

  <!-- <multiply> -->
  <implementation name="IM_multiply_bsdfC_genglsl" nodedef="ND_multiply_bsdfC" file="mx_multiply_bsdf_color3.glsl" function="mx_multiply_bsdf_color3" target="genglsl" />
  <implementation name="IM_multiply_bsdfF_genglsl" nodedef="ND_multiply_bsdfF" file="mx_multiply_bsdf_float.glsl" function="mx_multiply_bsdf_float" target="genglsl" />
  <implementation name="IM_multiply_edfC_genglsl" nodedef="ND_multiply_edfC" file="mx_multiply_edf_color3.glsl" function="mx_multiply_edf_color3" target="genglsl" />
  <implementation name="IM_multiply_edfF_genglsl" nodedef="ND_multiply_edfF" file="mx_multiply_edf_float.glsl" function="mx_multiply_edf_float" target="genglsl" />

  <!-- <uniform_edf> -->
  <implementation name="IM_uniform_edf_genglsl" nodedef="ND_uniform_edf" file="mx_uniform_edf.glsl" function="mx_uniform_edf" target="genglsl" />

  <!-- <generalized_schlick_edf> -->
  <implementation name="IM_generalized_schlick_edf_genglsl" nodedef="ND_generalized_schlick_edf" file="mx_generalized_schlick_edf.glsl" function="mx_generalized_schlick_edf" target="genglsl" />

  <!-- <surface> -->
  <implementation name="IM_surface_genglsl" nodedef="ND_surface" target="genglsl" />

  <!-- <displacement> -->
  <implementation name="IM_displacement_float_genglsl" nodedef="ND_displacement_float" file="mx_displacement_float.glsl" function="mx_displacement_float" target="genglsl" />
  <implementation name="IM_displacement_vector3_genglsl" nodedef="ND_displacement_vector3" file="mx_displacement_vector3.glsl" function="mx_displacement_vector3" target="genglsl" />

  <!-- <light> -->
  <implementation name="IM_light_genglsl" nodedef="ND_light" target="genglsl" />

  <!-- <roughness_anisotropy> -->
  <implementation name="IM_roughness_anisotropy_genglsl" nodedef="ND_roughness_anisotropy" file="mx_roughness_anisotropy.glsl" function="mx_roughness_anisotropy" target="genglsl" />

  <!-- <roughness_dual> -->
  <implementation name="IM_roughness_dual_genglsl" nodedef="ND_roughness_dual" file="mx_roughness_dual.glsl" function="mx_roughness_dual" target="genglsl" />

  <!-- <artistic_ior> -->
  <implementation name="IM_artistic_ior_genglsl" nodedef="ND_artistic_ior" file="mx_artistic_ior.glsl" function="mx_artistic_ior" target="genglsl" />

  <!-- <blackbody> -->
  <implementation name="IM_blackbody_genglsl" nodedef="ND_blackbody" file="mx_blackbody.glsl" function="mx_blackbody" target="genglsl" />

  <!-- <deon_hair_absorption_from_melanin -->
  <implementation name="IM_deon_hair_absorption_from_melanin_genglsl" nodedef="ND_deon_hair_absorption_from_melanin" file="mx_chiang_hair_bsdf.glsl" function="mx_deon_hair_absorption_from_melanin" target="genglsl" />

  <!-- <chiang_hair_absorption_from_color -->
  <implementation name="IM_chiang_hair_absorption_from_color_genglsl" nodedef="ND_chiang_hair_absorption_from_color" file="mx_chiang_hair_bsdf.glsl" function="mx_chiang_hair_absorption_from_color" target="genglsl" />

  <!-- <chiang_hair_roughness -->
  <implementation name="IM_chiang_hair_roughness_genglsl" nodedef="ND_chiang_hair_roughness" file="mx_chiang_hair_bsdf.glsl" function="mx_chiang_hair_roughness" target="genglsl" />

</materialx>
#include "lib/mx_closure_type.glsl"

void mx_multiply_edf_float(ClosureData closureData, EDF in1, float in2, out EDF result)
{
    result = in1 * in2;
}
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet_diffuse.glsl"

void mx_burley_diffuse_bsdf(ClosureData closureData, float weight, vec3 color, float roughness, vec3 N, inout BSDF bsdf)
{
    bsdf.throughput = vec3(0.0);

    if (weight < M_FLOAT_EPS)
    {
        return;
    }

    vec3 V = closureData.V;
    vec3 L = closureData.L;

    N = mx_forward_facing_normal(N, V);
    float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
        float LdotH = clamp(dot(L, normalize(L + V)), M_FLOAT_EPS, 1.0);

        bsdf.response = color * closureData.occlusion * weight * NdotL * M_PI_INV;
        bsdf.response *= mx_burley_diffuse(NdotV, NdotL, LdotH, roughness);
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        vec3 Li = mx_environment_irradiance(N) *
                  mx_burley_diffuse_dir_albedo(NdotV, roughness);
        bsdf.response = Li * color * weight;
    }
}
#include "lib/mx_closure_type.glsl"

void mx_layer_bsdf(ClosureData closureData, BSDF top, BSDF base, out BSDF result)
{
    result.response = top.response + base.response * top.throughput;
    result.throughput = top.throughput * base.throughput;
}
#include "lib/mx_closure_type.glsl"

void mx_translucent_bsdf(ClosureData closureData, float weight, vec3 color, vec3 N, inout BSDF bsdf)
{
    bsdf.throughput = vec3(0.0);

    if (weight < M_FLOAT_EPS)
    {
        return;
    }

    vec3 V = closureData.V;
    vec3 L = closureData.L;

    // Invert normal since we're transmitting light from the other side
    N = -N;

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        float NdotL = clamp(dot(N, L), 0.0, 1.0);
        bsdf.response = color * weight * NdotL * M_PI_INV;
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        vec3 Li = mx_environment_irradiance(N);
        bsdf.response = Li * color * weight;
    }
}
void mx_artistic_ior(vec3 reflectivity, vec3 edge_color, out vec3 ior, out vec3 extinction)
{
    // "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
    // http://jcgt.org/published/0003/04/03/paper.pdf

    vec3 r = clamp(reflectivity, 0.0, 0.99);
    vec3 r_sqrt = sqrt(r);
    vec3 n_min = (1.0 - r) / (1.0 + r);
    vec3 n_max = (1.0 + r_sqrt) / (1.0 - r_sqrt);
    ior = mix(n_max, n_min, edge_color);

    vec3 np1 = ior + 1.0;
    vec3 nm1 = ior - 1.0;
    vec3 k2 = (np1*np1 * r - nm1*nm1) / (1.0 - r);
    k2 = max(k2, 0.0);
    extinction = sqrt(k2);
}
#include "lib/mx_closure_type.glsl"

void mx_layer_vdf(ClosureData closureData, BSDF top, BSDF base, out BSDF result)
{
    result.response = top.response + base.response;
    result.throughput = top.throughput + base.throughput;
}
#include "lib/mx_closure_type.glsl"

void mx_multiply_bsdf_float(ClosureData closureData, BSDF in1, float in2, out BSDF result)
{
    float weight = clamp(in2, 0.0, 1.0);
    result.response = in1.response * weight;
    result.throughput = in1.throughput;
}
#include "lib/mx_closure_type.glsl"

void mx_uniform_edf(ClosureData closureData, vec3 color, out EDF result)
{
    if (closureData.closureType == CLOSURE_TYPE_EMISSION)
    {
        result = color;
    }
}
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet_specular.glsl"

void mx_conductor_bsdf(ClosureData closureData, float weight, vec3 ior_n, vec3 ior_k, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, inout BSDF bsdf)
{
    bsdf.throughput = vec3(0.0);

    if (weight < M_FLOAT_EPS)
    {
        return;
    }

    vec3 V = closureData.V;
    vec3 L = closureData.L;

    N = mx_forward_facing_normal(N, V);
    float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);

    FresnelData fd = mx_init_fresnel_conductor(ior_n, ior_k, thinfilm_thickness, thinfilm_ior);

    vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
    float avgAlpha = mx_average_alpha(safeAlpha);

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        X = normalize(X - dot(X, N) * N);
        vec3 Y = cross(N, X);
        vec3 H = normalize(L + V);

        float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
        float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);

        vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));

        vec3 F = mx_compute_fresnel(VdotH, fd);
        float D = mx_ggx_NDF(Ht, safeAlpha);
        float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);

        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);

        // Note: NdotL is cancelled out
        bsdf.response = D * F * G * comp * closureData.occlusion * weight / (4.0 * NdotV);
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        vec3 F = mx_compute_fresnel(NdotV, fd);
        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
        vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd);
        bsdf.response = Li * comp * weight;
    }
}
void mx_roughness_dual(vec2 roughness, out vec2 result)
{
    if (roughness.y < 0.0)
    {
        roughness.y = roughness.x;
    }
    result.x = clamp(roughness.x * roughness.x, M_FLOAT_EPS, 1.0);
    result.y = clamp(roughness.y * roughness.y, M_FLOAT_EPS, 1.0);
}
#include "lib/mx_closure_type.glsl"

void mx_add_edf(ClosureData closureData, EDF in1, EDF in2, out EDF result)
{
    result = in1 + in2;
}
#include "lib/mx_closure_type.glsl"

void mx_multiply_bsdf_color3(ClosureData closureData, BSDF in1, vec3 in2, out BSDF result)
{
    vec3 tint = clamp(in2, 0.0, 1.0);
    result.response = in1.response * tint;
    result.throughput = in1.throughput;
}
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet_specular.glsl"

void mx_dielectric_bsdf(ClosureData closureData, float weight, vec3 tint, float ior, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
    if (weight < M_FLOAT_EPS)
    {
        return;
    }
    if (closureData.closureType != CLOSURE_TYPE_TRANSMISSION && scatter_mode == 1)
    {
        return;
    }

    vec3 V = closureData.V;
    vec3 L = closureData.L;

    N = mx_forward_facing_normal(N, V);
    float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);

    FresnelData fd = mx_init_fresnel_dielectric(ior, thinfilm_thickness, thinfilm_ior);
    float F0 = mx_ior_to_f0(ior);

    vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
    float avgAlpha = mx_average_alpha(safeAlpha);
    vec3 safeTint = max(tint, 0.0);

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        X = normalize(X - dot(X, N) * N);
        vec3 Y = cross(N, X);
        vec3 H = normalize(L + V);

        float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
        float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);

        vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));

        vec3 F = mx_compute_fresnel(VdotH, fd);
        float D = mx_ggx_NDF(Ht, safeAlpha);
        float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);

        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
        vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
        bsdf.throughput = 1.0 - dirAlbedo * weight;

        bsdf.response = D * F * G * comp * safeTint * closureData.occlusion * weight / (4.0 * NdotV);
    }
    else if (closureData.closureType == CLOSURE_TYPE_TRANSMISSION)
    {
        vec3 F = mx_compute_fresnel(NdotV, fd);

        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
        vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
        bsdf.throughput = 1.0 - dirAlbedo * weight;

        if (scatter_mode != 0)
        {
            bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, safeTint) * weight;
        }
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        vec3 F = mx_compute_fresnel(NdotV, fd);

        vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
        vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, F0, 1.0) * comp;
        bsdf.throughput = 1.0 - dirAlbedo * weight;

        vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd);
        bsdf.response = Li * safeTint * comp * weight;
    }
}
#include "lib/mx_closure_type.glsl"

void mx_mix_bsdf(ClosureData closureData, BSDF fg, BSDF bg, float mixValue, out BSDF result)
{
    result.response = mix(bg.response, fg.response, mixValue);
    result.throughput = mix(bg.throughput, fg.throughput, mixValue);
}
void mx_roughness_anisotropy(float roughness, float anisotropy, out vec2 result)
{
    float roughness_sqr = clamp(roughness*roughness, M_FLOAT_EPS, 1.0);
    if (anisotropy > 0.0)
    {
        float aspect = sqrt(1.0 - clamp(anisotropy, 0.0, 0.98));
        result.x = min(roughness_sqr / aspect, 1.0);
        result.y = roughness_sqr * aspect;
    }
    else
    {
        result.x = roughness_sqr;
        result.y = roughness_sqr;
    }
}
/// XYZ to Rec.709 RGB colorspace conversion
const mat3 XYZ_to_RGB = mat3( 3.2406, -0.9689, 0.0557,
                             -1.5372, 1.8758, -0.2040,
                             -0.4986, 0.0415, 1.0570);

void mx_blackbody(float temperatureKelvin, out vec3 colorValue)
{
    float xc, yc;
    float t, t2, t3, xc2, xc3;

    // if value outside valid range of approximation clamp to accepted temperature range
    temperatureKelvin = clamp(temperatureKelvin, 1667.0, 25000.0);

    t = 1000.0 / temperatureKelvin;
    t2 = t * t;
    t3 = t * t * t;

    // Cubic spline approximation for Kelvin temperature to sRGB conversion
    // (https://en.wikipedia.org/wiki/Planckian_locus#Approximation)
    if (temperatureKelvin < 4000.0) {  // 1667K <= temperatureKelvin < 4000K
      xc = -0.2661239 * t3 - 0.2343580 * t2 + 0.8776956 * t + 0.179910;
    }
    else {  // 4000K <= temperatureKelvin <= 25000K
      xc = -3.0258469 * t3 + 2.1070379 * t2 + 0.2226347 * t + 0.240390;
    }
    xc2 = xc * xc;
    xc3 = xc * xc * xc;

    if (temperatureKelvin < 2222.0) {  // 1667K <= temperatureKelvin < 2222K
      yc = -1.1063814 * xc3 - 1.34811020 * xc2 + 2.18555832 * xc - 0.20219683;
    }
    else if (temperatureKelvin < 4000.0) {  // 2222K <= temperatureKelvin < 4000K
      yc = -0.9549476 * xc3 - 1.37418593 * xc2 + 2.09137015 * xc - 0.16748867;
    }
    else {  // 4000K <= temperatureKelvin <= 25000K
      yc = 3.0817580 * xc3 - 5.87338670 * xc2 + 3.75112997 * xc - 0.37001483;
    }

    if (yc <= 0.0) {  // avoid division by zero
      colorValue = vec3(1.0);
      return;
    }

    vec3 XYZ = vec3(xc / yc, 1.0, (1.0 - xc - yc) / yc);

    colorValue = XYZ_to_RGB * XYZ;
    colorValue = max(colorValue, vec3(0.0));
}
#include "lib/mx_closure_type.glsl"

void mx_add_bsdf(ClosureData closureData, BSDF in1, BSDF in2, out BSDF result)
{
    result.response = in1.response + in2.response;

    // We derive the throughput for closure addition as follows:
    //   throughput_1 = 1 - dir_albedo_1
    //   throughput_2 = 1 - dir_albedo_2
    //   throughput_sum = 1 - (dir_albedo_1 + dir_albedo_2)
    //                  = 1 - ((1 - throughput_1) + (1 - throughput_2))
    //                  = throughput_1 + throughput_2 - 1
    result.throughput = max(in1.throughput + in2.throughput - 1.0, 0.0);
}
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet_diffuse.glsl"

void mx_oren_nayar_diffuse_bsdf(ClosureData closureData, float weight, vec3 color, float roughness, vec3 N, bool energy_compensation, inout BSDF bsdf)
{
    bsdf.throughput = vec3(0.0);

    if (weight < M_FLOAT_EPS)
    {
        return;
    }

    vec3 V = closureData.V;
    vec3 L = closureData.L;

    N = mx_forward_facing_normal(N, V);
    float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
        float LdotV = clamp(dot(L, V), M_FLOAT_EPS, 1.0);

        vec3 diffuse = energy_compensation ?
                       mx_oren_nayar_compensated_diffuse(NdotV, NdotL, LdotV, roughness, color) :
                       mx_oren_nayar_diffuse(NdotV, NdotL, LdotV, roughness) * color;
        bsdf.response = diffuse * closureData.occlusion * weight * NdotL * M_PI_INV;
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        vec3 diffuse = energy_compensation ?
                       mx_oren_nayar_compensated_diffuse_dir_albedo(NdotV, roughness, color) :
                       mx_oren_nayar_diffuse_dir_albedo(NdotV, roughness) * color;
        vec3 Li = mx_environment_irradiance(N);
        bsdf.response = Li * diffuse * weight;
    }
}
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet_sheen.glsl"

void mx_sheen_bsdf(ClosureData closureData, float weight, vec3 color, float roughness, vec3 N, int mode, inout BSDF bsdf)
{
    if (weight < M_FLOAT_EPS)
    {
        return;
    }

    vec3 V = closureData.V;
    vec3 L = closureData.L;

    N = mx_forward_facing_normal(N, V);
    float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);

    if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
    {
        float dirAlbedo;
        if (mode == 0)
        {
            vec3 H = normalize(L + V);

            float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
            float NdotH = clamp(dot(N, H), M_FLOAT_EPS, 1.0);

            vec3 fr = color * mx_imageworks_sheen_brdf(NdotL, NdotV, NdotH, roughness);
            dirAlbedo = mx_imageworks_sheen_dir_albedo(NdotV, roughness);

            // We need to include NdotL from the light integral here
            // as in this case it's not cancelled out by the BRDF denominator.
            bsdf.response = fr * NdotL * closureData.occlusion * weight;
        }
        else
        {
            roughness = clamp(roughness, 0.01, 1.0); // Clamp to range of original impl.

            vec3 fr = color * mx_zeltner_sheen_brdf(L, V, N, NdotV, roughness);
            dirAlbedo = mx_zeltner_sheen_dir_albedo(NdotV, roughness);
            bsdf.response = dirAlbedo * fr * closureData.occlusion * weight;
        }
        bsdf.throughput = vec3(1.0 - dirAlbedo * weight);
    }
    else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
    {
        float dirAlbedo;
        if (mode == 0)
        {
            dirAlbedo = mx_imageworks_sheen_dir_albedo(NdotV, roughness);
        }
        else
        {
            roughness = clamp(roughness, 0.01, 1.0); // Clamp to range of original impl.
            dirAlbedo = mx_zeltner_sheen_dir_albedo(NdotV, roughness);
        }

        vec3 Li = mx_environment_irradiance(N);
        bsdf.response = Li * color * dirAlbedo * weight;
        bsdf.throughput = vec3(1.0 - dirAlbedo * weight);
    }
}
#include "lib/mx_closure_type.glsl"
#include "lib/mx_microfacet.glsl"

void mx_generalized_schlick_edf(ClosureData closureData, vec3 color0, vec3 color90, float exponent, EDF base, out EDF result)
{
    if (closureData.closureType == CLOSURE_TYPE_EMISSION)
    {
        vec3 N = mx_forward_facing_normal(closureData.N, closureData.V);
        float NdotV = clamp(dot(N, closureData.V), M_FLOAT_EPS, 1.0);
        vec3 f = mx_fresnel_schlick(NdotV, color0, color90, exponent);
        result = base * f;
    }
}
#include "lib/mx_closure_type.glsl"

void mx_mix_edf(ClosureData closureData, EDF fg, EDF bg, float mixValue, out EDF result)
{
    result = mix(bg, fg, mixValue);
}
#include "mx_microfacet_specular.glsl"

// Return the alpha associated with the given mip level in a prefiltered environment.
float mx_latlong_lod_to_alpha(float lod)
{
    float lodBias = lod / float($envRadianceMips - 1);
    return (lodBias < 0.5) ? mx_square(lodBias) : 2.0 * (lodBias - 0.375);
}

// The inverse of mx_latlong_projection.
vec3 mx_latlong_map_projection_inverse(vec2 uv)
{
    float latitude = (uv.y - 0.5) * M_PI;
    float longitude = (uv.x - 0.5) * M_PI * 2.0;

    float x = -mx_cos(latitude) * mx_sin(longitude);
    float y = -mx_sin(latitude);
    float z = mx_cos(latitude) * mx_cos(longitude);

    return vec3(x, y, z);
}

vec3 mx_generate_prefilter_env()
{
    // The tangent view vector is aligned with the normal.
    vec3 V = vec3(0.0, 0.0, 1.0);
    float NdotV = 1.0;

    // Compute derived properties.
#ifdef HW_SEPARATE_SAMPLERS
    vec2 uv = gl_FragCoord.xy * pow(2.0, $envPrefilterMip) / vec2(textureSize(sampler2D($envRadiance_texture, $envRadiance_sampler), 0));
#else
    vec2 uv = gl_FragCoord.xy * pow(2.0, $envPrefilterMip) / vec2(textureSize($envRadiance, 0));
#endif
    vec3 worldN = mx_latlong_map_projection_inverse(uv);
    mat3 tangentToWorld = mx_orthonormal_basis(worldN);
    float alpha = mx_latlong_lod_to_alpha(float($envPrefilterMip));
    float G1V = mx_ggx_smith_G1(NdotV, alpha);

    // Integrate the LD term for the given environment and alpha.
    vec3 radiance = vec3(0.0, 0.0, 0.0);
    float weight = 0.0;
    int envRadianceSamples = 1024;
    for (int i = 0; i < envRadianceSamples; i++)
    {
        vec2 Xi = mx_spherical_fibonacci(i, envRadianceSamples);

        // Compute the half vector and incoming light direction.
        vec3 H = mx_ggx_importance_sample_VNDF(Xi, V, vec2(alpha));
        vec3 L = -V + 2.0 * H.z * H;

        // Compute dot products for this sample.
        float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);

        // Compute the geometric term.
        float G = mx_ggx_smith_G2(NdotL, NdotV, alpha);

        // Sample the environment light from the given direction.
        vec3 Lw = tangentToWorld * L;
        float pdf = mx_ggx_NDF(H, vec2(alpha)) * G1V / (4.0 * NdotV);
        float lod = mx_latlong_compute_lod(Lw, pdf, float($envRadianceMips - 1), envRadianceSamples);
#ifdef HW_SEPARATE_SAMPLERS
        vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance_texture, $envRadiance_sampler);
#else
        vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance);
#endif

        // Add the radiance contribution of this sample.
        radiance += G * sampleColor;
        weight += G;
    }

    return radiance / weight;
}
#include "mx_microfacet_specular.glsl"

vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 roughness, int distribution, FresnelData fd)
{
    return vec3(0.0);
}

vec3 mx_environment_irradiance(vec3 N)
{
    return vec3(0.0);
}
#include "mx_microfacet_specular.glsl"

// Return the mip level associated with the given alpha in a prefiltered environment.
float mx_latlong_alpha_to_lod(float alpha)
{
    float lodBias = (alpha < 0.25) ? sqrt(alpha) : 0.5 * alpha + 0.375;
    return lodBias * float($envRadianceMips - 1);
}

vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
    N = mx_forward_facing_normal(N, V);
    vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, N, fd.ior.x) : -reflect(V, N);

    float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);

    float avgAlpha = mx_average_alpha(alpha);
    vec3 F = mx_compute_fresnel(NdotV, fd);
    float G = mx_ggx_smith_G2(NdotV, NdotV, avgAlpha);
    vec3 FG = fd.refraction ? vec3(1.0) - (F * G) : F * G;

#ifdef HW_SEPARATE_SAMPLERS
    vec3 Li = mx_latlong_map_lookup(L, $envMatrix, mx_latlong_alpha_to_lod(avgAlpha), $envRadiance_texture, $envRadiance_sampler);
#else
    vec3 Li = mx_latlong_map_lookup(L, $envMatrix, mx_latlong_alpha_to_lod(avgAlpha), $envRadiance);
#endif
    return Li * FG * $envLightIntensity;
}

vec3 mx_environment_irradiance(vec3 N)
{
#ifdef HW_SEPARATE_SAMPLERS
    vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance_texture, $envIrradiance_sampler);
#else
    vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance);
#endif
    return Li * $envLightIntensity;
}
#include "mx_microfacet_sheen.glsl"
#include "mx_microfacet_specular.glsl"

vec3 mx_generate_dir_albedo_table()
{
    vec2 uv = gl_FragCoord.xy / $albedoTableSize;
    vec2 ggxDirAlbedo = mx_ggx_dir_albedo(uv.x, uv.y, vec3(1, 0, 0), vec3(0, 1, 0)).xy;
    float sheenDirAlbedo = mx_imageworks_sheen_dir_albedo(uv.x, uv.y);
    return vec3(ggxDirAlbedo, sheenDirAlbedo);
}
#define M_PI 3.1415926535897932
#define M_PI_INV (1.0 / M_PI)

float mx_pow5(float x)
{
    return mx_square(mx_square(x)) * x;
}

float mx_pow6(float x)
{
    float x2 = mx_square(x);
    return mx_square(x2) * x2;
}

// Standard Schlick Fresnel
float mx_fresnel_schlick(float cosTheta, float F0)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    float x5 = mx_pow5(x);
    return F0 + (1.0 - F0) * x5;
}
vec3 mx_fresnel_schlick(float cosTheta, vec3 F0)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    float x5 = mx_pow5(x);
    return F0 + (1.0 - F0) * x5;
}

// Generalized Schlick Fresnel
float mx_fresnel_schlick(float cosTheta, float F0, float F90)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    float x5 = mx_pow5(x);
    return mix(F0, F90, x5);
}
vec3 mx_fresnel_schlick(float cosTheta, vec3 F0, vec3 F90)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    float x5 = mx_pow5(x);
    return mix(F0, F90, x5);
}

// Generalized Schlick Fresnel with a variable exponent
float mx_fresnel_schlick(float cosTheta, float F0, float F90, float exponent)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    return mix(F0, F90, pow(x, exponent));
}
vec3 mx_fresnel_schlick(float cosTheta, vec3 F0, vec3 F90, float exponent)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    return mix(F0, F90, pow(x, exponent));
}

// Enforce that the given normal is forward-facing from the specified view direction.
vec3 mx_forward_facing_normal(vec3 N, vec3 V)
{
    return (dot(N, V) < 0.0) ? -N : N;
}

// https://www.graphics.rwth-aachen.de/publication/2/jgt.pdf
float mx_golden_ratio_sequence(int i)
{
    const float GOLDEN_RATIO = 1.6180339887498948;
    return fract((float(i) + 1.0) * GOLDEN_RATIO);
}

// https://people.irisa.fr/Ricardo.Marques/articles/2013/SF_CGF.pdf
vec2 mx_spherical_fibonacci(int i, int numSamples)
{
    return vec2((float(i) + 0.5) / float(numSamples), mx_golden_ratio_sequence(i));
}

// Generate a uniform-weighted sample on the unit hemisphere.
vec3 mx_uniform_sample_hemisphere(vec2 Xi)
{
    float phi = 2.0 * M_PI * Xi.x;
    float cosTheta = 1.0 - Xi.y;
    float sinTheta = sqrt(1.0 - mx_square(cosTheta));
    return vec3(mx_cos(phi) * sinTheta,
                mx_sin(phi) * sinTheta,
                cosTheta);
}

// Generate a cosine-weighted sample on the unit hemisphere.
vec3 mx_cosine_sample_hemisphere(vec2 Xi)
{
    float phi = 2.0 * M_PI * Xi.x;
    float cosTheta = sqrt(Xi.y);
    float sinTheta = sqrt(1.0 - Xi.y);
    return vec3(mx_cos(phi) * sinTheta,
                mx_sin(phi) * sinTheta,
                cosTheta);
}

// Construct an orthonormal basis from a unit vector.
// https://graphics.pixar.com/library/OrthonormalB/paper.pdf
mat3 mx_orthonormal_basis(vec3 N)
{
    float sign = (N.z < 0.0) ? -1.0 : 1.0;
    float a = -1.0 / (sign + N.z);
    float b = N.x * N.y * a;
    vec3 X = vec3(1.0 + sign * N.x * N.x * a, sign * b, -sign * N.x);
    vec3 Y = vec3(b, sign + N.y * N.y * a, -N.y);
    return mat3(X, Y, N);
}
#include "mx_microfacet.glsl"

// https://fpsunflower.github.io/ckulla/data/s2017_pbs_imageworks_sheen.pdf
// Equation 2
float mx_imageworks_sheen_NDF(float NdotH, float roughness)
{
    float invRoughness = 1.0 / max(roughness, 0.005);
    float cos2 = NdotH * NdotH;
    float sin2 = 1.0 - cos2;
    return (2.0 + invRoughness) * pow(sin2, invRoughness * 0.5) / (2.0 * M_PI);
}

float mx_imageworks_sheen_brdf(float NdotL, float NdotV, float NdotH, float roughness)
{
    // Microfacet distribution.
    float D = mx_imageworks_sheen_NDF(NdotH, roughness);

    // Fresnel and geometry terms are ignored.
    float F = 1.0;
    float G = 1.0;

    // We use a smoother denominator, as in:
    // https://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
    return D * F * G / (4.0 * (NdotL + NdotV - NdotL*NdotV));
}

// Rational quadratic fit to Monte Carlo data for Imageworks sheen directional albedo.
float mx_imageworks_sheen_dir_albedo_analytic(float NdotV, float roughness)
{
    vec2 r = vec2(13.67300, 1.0) +
             vec2(-68.78018, 61.57746) * NdotV +
             vec2(799.08825, 442.78211) * roughness +
             vec2(-905.00061, 2597.49308) * NdotV * roughness +
             vec2(60.28956, 121.81241) * mx_square(NdotV) +
             vec2(1086.96473, 3045.55075) * mx_square(roughness);
    return r.x / r.y;
}

float mx_imageworks_sheen_dir_albedo_table_lookup(float NdotV, float roughness)
{
#if DIRECTIONAL_ALBEDO_METHOD == 1
    if (textureSize($albedoTable, 0).x > 1)
    {
        return texture($albedoTable, vec2(NdotV, roughness)).b;
    }
#endif
    return 0.0;
}

float mx_imageworks_sheen_dir_albedo_monte_carlo(float NdotV, float roughness)
{
    NdotV = clamp(NdotV, M_FLOAT_EPS, 1.0);
    vec3 V = vec3(sqrt(1.0f - mx_square(NdotV)), 0, NdotV);

    float radiance = 0.0;
    const int SAMPLE_COUNT = 64;
    for (int i = 0; i < SAMPLE_COUNT; i++)
    {
        vec2 Xi = mx_spherical_fibonacci(i, SAMPLE_COUNT);

        // Compute the incoming light direction and half vector.
        vec3 L = mx_uniform_sample_hemisphere(Xi);
        vec3 H = normalize(L + V);
        
        // Compute dot products for this sample.
        float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
        float NdotH = clamp(H.z, M_FLOAT_EPS, 1.0);

        // Compute sheen reflectance.
        float reflectance = mx_imageworks_sheen_brdf(NdotL, NdotV, NdotH, roughness);

        // Add the radiance contribution of this sample.
        //   uniform_pdf = 1 / (2 * PI)
        //   radiance = reflectance * NdotL / uniform_pdf;
        radiance += reflectance * NdotL * 2.0 * M_PI;
    }

    // Return the final directional albedo.
    return radiance / float(SAMPLE_COUNT);
}

float mx_imageworks_sheen_dir_albedo(float NdotV, float roughness)
{
#if DIRECTIONAL_ALBEDO_METHOD == 0
    float dirAlbedo = mx_imageworks_sheen_dir_albedo_analytic(NdotV, roughness);
#elif DIRECTIONAL_ALBEDO_METHOD == 1
    float dirAlbedo = mx_imageworks_sheen_dir_albedo_table_lookup(NdotV, roughness);
#else
    float dirAlbedo = mx_imageworks_sheen_dir_albedo_monte_carlo(NdotV, roughness);
#endif
    return clamp(dirAlbedo, 0.0, 1.0);
}

// The following functions are adapted from https://github.com/tizian/ltc-sheen.
// "Practical Multiple-Scattering Sheen Using Linearly Transformed Cosines", Zeltner et al.

// Gaussian fit to directional albedo table.
float mx_zeltner_sheen_dir_albedo(float x, float y)
{
    float s = y*(0.0206607 + 1.58491*y)/(0.0379424 + y*(1.32227 + y));
    float m = y*(-0.193854 + y*(-1.14885 + y*(1.7932 - 0.95943*y*y)))/(0.046391 + y);
    float o = y*(0.000654023 + (-0.0207818 + 0.119681*y)*y)/(1.26264 + y*(-1.92021 + y));
    return exp(-0.5*mx_square((x - m)/s))/(s*sqrt(2.0*M_PI)) + o;
}

// Rational fits to LTC matrix coefficients.
float mx_zeltner_sheen_ltc_aInv(float x, float y)
{
    return (2.58126*x + 0.813703*y)*y/(1.0 + 0.310327*x*x + 2.60994*x*y);
}

float mx_zeltner_sheen_ltc_bInv(float x, float y)
{
    return sqrt(1.0 - x)*(y - 1.0)*y*y*y/(0.0000254053 + 1.71228*x - 1.71506*x*y + 1.34174*y*y);
}

// V and N are assumed to be unit vectors.
mat3 mx_orthonormal_basis_ltc(vec3 V, vec3 N, float NdotV)
{
    // Generate a tangent vector in the plane of V and N.
    // This required to correctly orient the LTC lobe.
    vec3 X = V - N*NdotV;
    float lenSqr = dot(X, X);
    if (lenSqr > 0.0)
    {
        X *= mx_inversesqrt(lenSqr);
        vec3 Y = cross(N, X);
        return mat3(X, Y, N);
    }

    // If lenSqr == 0, then V == N, so any orthonormal basis will do.
    return mx_orthonormal_basis(N);
}

// Multiplication by directional albedo is handled by the calling function.
float mx_zeltner_sheen_brdf(vec3 L, vec3 V, vec3 N, float NdotV, float roughness)
{
    mat3 toLTC = transpose(mx_orthonormal_basis_ltc(V, N, NdotV));
    vec3 w = toLTC * L;

    float aInv = mx_zeltner_sheen_ltc_aInv(NdotV, roughness);
    float bInv = mx_zeltner_sheen_ltc_bInv(NdotV, roughness);

    // Transform w to original configuration (clamped cosine).
    //                 |aInv    0 bInv|
    // wo = M^-1 . w = |   0 aInv    0| . w
    //                 |   0    0    1|
    vec3 wo = vec3(aInv*w.x + bInv*w.z, aInv * w.y, w.z);
    float lenSqr = dot(wo, wo);

    // D(w) = Do(M^-1.w / ||M^-1.w||) . |M^-1| / ||M^-1.w||^3
    //      = Do(M^-1.w) . |M^-1| / ||M^-1.w||^4
    //      = Do(wo) . |M^-1| / dot(wo, wo)^2
    //      = Do(wo) . aInv^2 / dot(wo, wo)^2
    //      = Do(wo) . (aInv / dot(wo, wo))^2
    return max(wo.z, 0.0) * M_PI_INV * mx_square(aInv / lenSqr);
}

vec3 mx_zeltner_sheen_importance_sample(vec2 Xi, vec3 V, vec3 N, float roughness, out float pdf)
{
    float NdotV = clamp(dot(N, V), 0.0, 1.0);
    roughness = clamp(roughness, 0.01, 1.0); // Clamp to range of original impl.

    vec3 wo = mx_cosine_sample_hemisphere(Xi);

    float aInv = mx_zeltner_sheen_ltc_aInv(NdotV, roughness);
    float bInv = mx_zeltner_sheen_ltc_bInv(NdotV, roughness);

    // Transform wo from original configuration (clamped cosine).
    //              |1/aInv      0 -bInv/aInv|
    // w = M . wo = |     0 1/aInv          0| . wo
    //              |     0      0          1|    
    vec3 w = vec3(wo.x/aInv - wo.z*bInv/aInv, wo.y / aInv, wo.z);

    float lenSqr = dot(w, w);
    w *= mx_inversesqrt(lenSqr);

    // D(w) = Do(wo) . ||M.wo||^3 / |M|
    //      = Do(wo / ||M.wo||) . ||M.wo||^4 / |M| 
    //      = Do(w) . ||M.wo||^4 / |M| (possible because M doesn't change z component)
    //      = Do(w) . dot(w, w)^2 * aInv^2
    //      = Do(w) . (aInv * dot(w, w))^2
    pdf = max(w.z, 0.0) * M_PI_INV * mx_square(aInv * lenSqr);

    mat3 fromLTC = mx_orthonormal_basis_ltc(V, N, NdotV);
    w = fromLTC * w;

    return w;
}
// These are defined based on the HwShaderGenerator::ClosureContextType enum
// if that changes - these need to be updated accordingly.

#define CLOSURE_TYPE_DEFAULT 0
#define CLOSURE_TYPE_REFLECTION 1
#define CLOSURE_TYPE_TRANSMISSION 2
#define CLOSURE_TYPE_INDIRECT 3
#define CLOSURE_TYPE_EMISSION 4

struct ClosureData {
    int closureType;
    vec3 L;
    vec3 V;
    vec3 N;
    vec3 P;
    float occlusion;
};
#include "mx_microfacet_specular.glsl"

vec3 mx_surface_transmission(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd, vec3 tint)
{
    return tint;
}
#include "mx_microfacet.glsl"

const float FUJII_CONSTANT_1 = 0.5 - 2.0 / (3.0 * M_PI);
const float FUJII_CONSTANT_2 = 2.0 / 3.0 - 28.0 / (15.0 * M_PI);

// Qualitative Oren-Nayar diffuse with simplified math:
// https://www1.cs.columbia.edu/CAVE/publications/pdfs/Oren_SIGGRAPH94.pdf
float mx_oren_nayar_diffuse(float NdotV, float NdotL, float LdotV, float roughness)
{
    float s = LdotV - NdotL * NdotV;
    float stinv = (s > 0.0) ? s / max(NdotL, NdotV) : 0.0;

    float sigma2 = mx_square(roughness);
    float A = 1.0 - 0.5 * (sigma2 / (sigma2 + 0.33));
    float B = 0.45 * sigma2 / (sigma2 + 0.09);

    return A + B * stinv;
}

// Rational quadratic fit to Monte Carlo data for Oren-Nayar directional albedo.
float mx_oren_nayar_diffuse_dir_albedo_analytic(float NdotV, float roughness)
{
    vec2 r = vec2(1.0, 1.0) +
             vec2(-0.4297, -0.6076) * roughness +
             vec2(-0.7632, -0.4993) * NdotV * roughness +
             vec2(1.4385, 2.0315) * mx_square(roughness);
    return r.x / r.y;
}

float mx_oren_nayar_diffuse_dir_albedo_table_lookup(float NdotV, float roughness)
{
#if DIRECTIONAL_ALBEDO_METHOD == 1
    if (textureSize($albedoTable, 0).x > 1)
    {
        return texture($albedoTable, vec2(NdotV, roughness)).b;
    }
#endif
    return 0.0;
}

float mx_oren_nayar_diffuse_dir_albedo_monte_carlo(float NdotV, float roughness)
{
    NdotV = clamp(NdotV, M_FLOAT_EPS, 1.0);
    vec3 V = vec3(sqrt(1.0 - mx_square(NdotV)), 0, NdotV);

    float radiance = 0.0;
    const int SAMPLE_COUNT = 64;
    for (int i = 0; i < SAMPLE_COUNT; i++)
    {
        vec2 Xi = mx_spherical_fibonacci(i, SAMPLE_COUNT);

        // Compute the incoming light direction.
        vec3 L = mx_uniform_sample_hemisphere(Xi);
        
        // Compute dot products for this sample.
        float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
        float LdotV = clamp(dot(L, V), M_FLOAT_EPS, 1.0);

        // Compute diffuse reflectance.
        float reflectance = mx_oren_nayar_diffuse(NdotV, NdotL, LdotV, roughness);

        // Add the radiance contribution of this sample.
        //   uniform_pdf = 1 / (2 * PI)
        //   radiance = (reflectance * NdotL) / (uniform_pdf * PI);
        radiance += reflectance * NdotL;
    }

    // Apply global components and normalize.
    radiance *= 2.0 / float(SAMPLE_COUNT);

    // Return the final directional albedo.
    return radiance;
}

float mx_oren_nayar_diffuse_dir_albedo(float NdotV, float roughness)
{
#if DIRECTIONAL_ALBEDO_METHOD == 2
    float dirAlbedo = mx_oren_nayar_diffuse_dir_albedo_monte_carlo(NdotV, roughness);
#else
    float dirAlbedo = mx_oren_nayar_diffuse_dir_albedo_analytic(NdotV, roughness);
#endif
    return clamp(dirAlbedo, 0.0, 1.0);
}

// Improved Oren-Nayar diffuse from Fujii:
// https://mimosa-pudica.net/improved-oren-nayar.html
float mx_oren_nayar_fujii_diffuse_dir_albedo(float cosTheta, float roughness)
{
    float A = 1.0 / (1.0 + FUJII_CONSTANT_1 * roughness);
    float B = roughness * A;
    float Si = sqrt(max(0.0, 1.0 - mx_square(cosTheta)));
    float G = Si * (mx_acos(clamp(cosTheta, -1.0, 1.0)) - Si * cosTheta) +
              2.0 * ((Si / cosTheta) * (1.0 - Si * Si * Si) - Si) / 3.0;
    return A + (B * G * M_PI_INV);
}

float mx_oren_nayar_fujii_diffuse_avg_albedo(float roughness)
{
    float A = 1.0 / (1.0 + FUJII_CONSTANT_1 * roughness);
    return A * (1.0 + FUJII_CONSTANT_2 * roughness);
}   

// Energy-compensated Oren-Nayar diffuse from OpenPBR Surface:
// https://academysoftwarefoundation.github.io/OpenPBR/
vec3 mx_oren_nayar_compensated_diffuse(float NdotV, float NdotL, float LdotV, float roughness, vec3 color)
{
    float s = LdotV - NdotL * NdotV;
    float stinv = (s > 0.0) ? s / max(NdotL, NdotV) : s;

    // Compute the single-scatter lobe.
    float A = 1.0 / (1.0 + FUJII_CONSTANT_1 * roughness);
    vec3 lobeSingleScatter = color * A * (1.0 + roughness * stinv);

    // Compute the multi-scatter lobe.
    float dirAlbedoV = mx_oren_nayar_fujii_diffuse_dir_albedo(NdotV, roughness);
    float dirAlbedoL = mx_oren_nayar_fujii_diffuse_dir_albedo(NdotL, roughness);
    float avgAlbedo = mx_oren_nayar_fujii_diffuse_avg_albedo(roughness);
    vec3 colorMultiScatter = mx_square(color) * avgAlbedo /
                             (vec3(1.0) - color * max(0.0, 1.0 - avgAlbedo));
    vec3 lobeMultiScatter = colorMultiScatter *
                            max(M_FLOAT_EPS, 1.0 - dirAlbedoV) *
                            max(M_FLOAT_EPS, 1.0 - dirAlbedoL) /
                            max(M_FLOAT_EPS, 1.0 - avgAlbedo);

    // Return the sum.
    return lobeSingleScatter + lobeMultiScatter;
}

vec3 mx_oren_nayar_compensated_diffuse_dir_albedo(float cosTheta, float roughness, vec3 color)
{
    float dirAlbedo = mx_oren_nayar_fujii_diffuse_dir_albedo(cosTheta, roughness);
    float avgAlbedo = mx_oren_nayar_fujii_diffuse_avg_albedo(roughness);
    vec3 colorMultiScatter = mx_square(color) * avgAlbedo /
                             (vec3(1.0) - color * max(0.0, 1.0 - avgAlbedo));
    return mix(colorMultiScatter, color, dirAlbedo);
}
  
// https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf
// Section 5.3
float mx_burley_diffuse(float NdotV, float NdotL, float LdotH, float roughness)
{
    float F90 = 0.5 + (2.0 * roughness * mx_square(LdotH));
    float refL = mx_fresnel_schlick(NdotL, 1.0, F90);
    float refV = mx_fresnel_schlick(NdotV, 1.0, F90);
    return refL * refV;
}

// Compute the directional albedo component of Burley diffuse for the given
// view angle and roughness.  Curve fit provided by Stephen Hill.
float mx_burley_diffuse_dir_albedo(float NdotV, float roughness)
{
    float x = NdotV;
    float fit0 = 0.97619 - 0.488095 * mx_pow5(1.0 - x);
    float fit1 = 1.55754 + (-2.02221 + (2.56283 - 1.06244 * x) * x) * x;
    return mix(fit0, fit1, roughness);
}

// Evaluate the Burley diffusion profile for the given distance and diffusion shape.
// Based on https://graphics.pixar.com/library/ApproxBSSRDF/
vec3 mx_burley_diffusion_profile(float dist, vec3 shape)
{
    vec3 num1 = exp(-shape * dist);
    vec3 num2 = exp(-shape * dist / 3.0);
    float denom = max(dist, M_FLOAT_EPS);
    return (num1 + num2) / denom;
}

// Integrate the Burley diffusion profile over a sphere of the given radius.
// Inspired by Eric Penner's presentation in http://advances.realtimerendering.com/s2011/
vec3 mx_integrate_burley_diffusion(vec3 N, vec3 L, float radius, vec3 mfp)
{
    float theta = mx_acos(dot(N, L));

    // Estimate the Burley diffusion shape from mean free path.
    vec3 shape = vec3(1.0) / max(mfp, 0.1);

    // Integrate the profile over the sphere.
    vec3 sumD = vec3(0.0);
    vec3 sumR = vec3(0.0);
    const int SAMPLE_COUNT = 32;
    const float SAMPLE_WIDTH = (2.0 * M_PI) / float(SAMPLE_COUNT);
    for (int i = 0; i < SAMPLE_COUNT; i++)
    {
        float x = -M_PI + (float(i) + 0.5) * SAMPLE_WIDTH;
        float dist = radius * abs(2.0 * mx_sin(x * 0.5));
        vec3 R = mx_burley_diffusion_profile(dist, shape);
        sumD += R * max(mx_cos(theta + x), 0.0);
        sumR += R;
    }

    return sumD / sumR;
}

vec3 mx_subsurface_scattering_approx(vec3 N, vec3 L, vec3 P, vec3 albedo, vec3 mfp)
{
    float curvature = length(fwidth(N)) / length(fwidth(P));
    float radius = 1.0 / max(curvature, 0.01);
    return albedo * mx_integrate_burley_diffusion(N, L, radius, mfp) / vec3(M_PI);
}
#include "mx_microfacet_specular.glsl"

vec3 mx_environment_radiance(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd)
{
    // Generate tangent frame.
    X = normalize(X - dot(X, N) * N);
    vec3 Y = cross(N, X);
    mat3 tangentToWorld = mat3(X, Y, N);

    // Transform the view vector to tangent space.
    V = vec3(dot(V, X), dot(V, Y), dot(V, N));

    // Compute derived properties.
    float NdotV = clamp(V.z, M_FLOAT_EPS, 1.0);
    float avgAlpha = mx_average_alpha(alpha);
    float G1V = mx_ggx_smith_G1(NdotV, avgAlpha);
    
    // Integrate outgoing radiance using filtered importance sampling.
    // http://cgg.mff.cuni.cz/~jaroslav/papers/2008-egsr-fis/2008-egsr-fis-final-embedded.pdf
    vec3 radiance = vec3(0.0);
    int envRadianceSamples = $envRadianceSamples;
    for (int i = 0; i < envRadianceSamples; i++)
    {
        vec2 Xi = mx_spherical_fibonacci(i, envRadianceSamples);

        // Compute the half vector and incoming light direction.
        vec3 H = mx_ggx_importance_sample_VNDF(Xi, V, alpha);
        vec3 L = fd.refraction ? mx_refraction_solid_sphere(-V, H, fd.ior.x) : -reflect(V, H);
        
        // Compute dot products for this sample.
        float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
        float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);

        // Sample the environment light from the given direction.
        vec3 Lw = tangentToWorld * L;
        float pdf = mx_ggx_NDF(H, alpha) * G1V / (4.0 * NdotV);
        float lod = mx_latlong_compute_lod(Lw, pdf, float($envRadianceMips - 1), envRadianceSamples);
#ifdef HW_SEPARATE_SAMPLERS 
        vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance_texture, $envRadiance_sampler);
#else
        vec3 sampleColor = mx_latlong_map_lookup(Lw, $envMatrix, lod, $envRadiance);
#endif

        // Compute the Fresnel term.
        vec3 F = mx_compute_fresnel(VdotH, fd);

        // Compute the geometric term.
        float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);

        // Compute the combined FG term, which simplifies to inverted Fresnel for refraction.
        vec3 FG = fd.refraction ? vec3(1.0) - F : F * G;

        // Add the radiance contribution of this sample.
        // From https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
        //   incidentLight = sampleColor * NdotL
        //   microfacetSpecular = D * F * G / (4 * NdotL * NdotV)
        //   pdf = D * G1V / (4 * NdotV);
        //   radiance = incidentLight * microfacetSpecular / pdf
        radiance += sampleColor * FG;
    }

    // Apply the global component of the geometric term and normalize.
    radiance /= G1V * float(envRadianceSamples);

    // Return the final radiance.
    return radiance * $envLightIntensity;
}

vec3 mx_environment_irradiance(vec3 N)
{
#ifdef HW_SEPARATE_SAMPLERS
    vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance_texture, $envIrradiance_sampler);
#else
    vec3 Li = mx_latlong_map_lookup(N, $envMatrix, 0.0, $envIrradiance);
#endif
    return Li * $envLightIntensity;
}
// https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-8-summed-area-variance-shadow-maps
float mx_variance_shadow_occlusion(vec2 moments, float fragmentDepth)
{
    const float MIN_VARIANCE = 0.00001;

    // One-tailed inequality valid if fragmentDepth > moments.x.
    float p = (fragmentDepth <= moments.x) ? 1.0 : 0.0;

    // Compute variance.
    float variance = moments.y - mx_square(moments.x);
    variance = max(variance, MIN_VARIANCE);

    // Compute probabilistic upper bound.
    float d = fragmentDepth - moments.x;
    float pMax = variance / (variance + mx_square(d));
    return max(p, pMax);
}

vec2 mx_compute_depth_moments()
{
    float depth = gl_FragCoord.z;
    return vec2(depth, mx_square(depth));
}
#include "mx_microfacet_specular.glsl"

vec3 mx_surface_transmission(vec3 N, vec3 V, vec3 X, vec2 alpha, int distribution, FresnelData fd, vec3 tint)
{
    // Approximate the appearance of surface transmission as glossy
    // environment map refraction, ignoring any scene geometry that might
    // be visible through the surface.
    fd.refraction = true;
    if ($refractionTwoSided)
    {
        tint = mx_square(tint);
    }
    return mx_environment_radiance(N, V, X, alpha, distribution, fd) * tint;
}
#include "mx_microfacet.glsl"

const int FRESNEL_MODEL_DIELECTRIC = 0;
const int FRESNEL_MODEL_CONDUCTOR = 1;
const int FRESNEL_MODEL_SCHLICK = 2;

// Parameters for Fresnel calculations
struct FresnelData
{
    // Fresnel model
    int model;
    bool airy;

    // Physical Fresnel
    vec3 ior;
    vec3 extinction;

    // Generalized Schlick Fresnel
    vec3 F0;
    vec3 F82;
    vec3 F90;
    float exponent;

    // Thin film
    float tf_thickness;
    float tf_ior;

    // Refraction
    bool refraction;
};

// https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf
// Appendix B.2 Equation 13
float mx_ggx_NDF(vec3 H, vec2 alpha)
{
    vec2 He = H.xy / alpha;
    float denom = dot(He, He) + mx_square(H.z);
    return 1.0 / (M_PI * alpha.x * alpha.y * mx_square(denom));
}

// https://ggx-research.github.io/publication/2023/06/09/publication-ggx.html
vec3 mx_ggx_importance_sample_VNDF(vec2 Xi, vec3 V, vec2 alpha)
{
    // Transform the view direction to the hemisphere configuration.
    V = normalize(vec3(V.xy * alpha, V.z));

    // Sample a spherical cap in (-V.z, 1].
    float phi = 2.0 * M_PI * Xi.x;
    float z = (1.0 - Xi.y) * (1.0 + V.z) - V.z;
    float sinTheta = sqrt(clamp(1.0 - z * z, 0.0, 1.0));
    float x = sinTheta * mx_cos(phi);
    float y = sinTheta * mx_sin(phi);
    vec3 c = vec3(x, y, z);

    // Compute the microfacet normal.
    vec3 H = c + V;

    // Transform the microfacet normal back to the ellipsoid configuration.
    H = normalize(vec3(H.xy * alpha, max(H.z, 0.0)));

    return H;
}

// https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
// Equation 34
float mx_ggx_smith_G1(float cosTheta, float alpha)
{
    float cosTheta2 = mx_square(cosTheta);
    float tanTheta2 = (1.0 - cosTheta2) / cosTheta2;
    return 2.0 / (1.0 + sqrt(1.0 + mx_square(alpha) * tanTheta2));
}

// Height-correlated Smith masking-shadowing
// http://jcgt.org/published/0003/02/03/paper.pdf
// Equations 72 and 99
float mx_ggx_smith_G2(float NdotL, float NdotV, float alpha)
{
    float alpha2 = mx_square(alpha);
    float lambdaL = sqrt(alpha2 + (1.0 - alpha2) * mx_square(NdotL));
    float lambdaV = sqrt(alpha2 + (1.0 - alpha2) * mx_square(NdotV));
    return 2.0 * NdotL * NdotV / (lambdaL * NdotV + lambdaV * NdotL);
}

// Rational quadratic fit to Monte Carlo data for GGX directional albedo.
vec3 mx_ggx_dir_albedo_analytic(float NdotV, float alpha, vec3 F0, vec3 F90)
{
    float x = NdotV;
    float y = alpha;
    float x2 = mx_square(x);
    float y2 = mx_square(y);
    vec4 r = vec4(0.1003, 0.9345, 1.0, 1.0) +
             vec4(-0.6303, -2.323, -1.765, 0.2281) * x +
             vec4(9.748, 2.229, 8.263, 15.94) * y +
             vec4(-2.038, -3.748, 11.53, -55.83) * x * y +
             vec4(29.34, 1.424, 28.96, 13.08) * x2 +
             vec4(-8.245, -0.7684, -7.507, 41.26) * y2 +
             vec4(-26.44, 1.436, -36.11, 54.9) * x2 * y +
             vec4(19.99, 0.2913, 15.86, 300.2) * x * y2 +
             vec4(-5.448, 0.6286, 33.37, -285.1) * x2 * y2;
    vec2 AB = clamp(r.xy / r.zw, 0.0, 1.0);
    return F0 * AB.x + F90 * AB.y;
}

vec3 mx_ggx_dir_albedo_table_lookup(float NdotV, float alpha, vec3 F0, vec3 F90)
{
#if DIRECTIONAL_ALBEDO_METHOD == 1
    if (textureSize($albedoTable, 0).x > 1)
    {
        vec2 AB = texture($albedoTable, vec2(NdotV, alpha)).rg;
        return F0 * AB.x + F90 * AB.y;
    }
#endif
    return vec3(0.0);
}

// https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
vec3 mx_ggx_dir_albedo_monte_carlo(float NdotV, float alpha, vec3 F0, vec3 F90)
{
    NdotV = clamp(NdotV, M_FLOAT_EPS, 1.0);
    vec3 V = vec3(sqrt(1.0 - mx_square(NdotV)), 0, NdotV);

    vec2 AB = vec2(0.0);
    const int SAMPLE_COUNT = 64;
    for (int i = 0; i < SAMPLE_COUNT; i++)
    {
        vec2 Xi = mx_spherical_fibonacci(i, SAMPLE_COUNT);

        // Compute the half vector and incoming light direction.
        vec3 H = mx_ggx_importance_sample_VNDF(Xi, V, vec2(alpha));
        vec3 L = -reflect(V, H);
        
        // Compute dot products for this sample.
        float NdotL = clamp(L.z, M_FLOAT_EPS, 1.0);
        float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);

        // Compute the Fresnel term.
        float Fc = mx_fresnel_schlick(VdotH, 0.0, 1.0);

        // Compute the per-sample geometric term.
        // https://hal.inria.fr/hal-00996995v2/document, Algorithm 2
        float G2 = mx_ggx_smith_G2(NdotL, NdotV, alpha);
        
        // Add the contribution of this sample.
        AB += vec2(G2 * (1.0 - Fc), G2 * Fc);
    }

    // Apply the global component of the geometric term and normalize.
    AB /= mx_ggx_smith_G1(NdotV, alpha) * float(SAMPLE_COUNT);

    // Return the final directional albedo.
    return F0 * AB.x + F90 * AB.y;
}

vec3 mx_ggx_dir_albedo(float NdotV, float alpha, vec3 F0, vec3 F90)
{
#if DIRECTIONAL_ALBEDO_METHOD == 0
    return mx_ggx_dir_albedo_analytic(NdotV, alpha, F0, F90);
#elif DIRECTIONAL_ALBEDO_METHOD == 1
    return mx_ggx_dir_albedo_table_lookup(NdotV, alpha, F0, F90);
#else
    return mx_ggx_dir_albedo_monte_carlo(NdotV, alpha, F0, F90);
#endif
}

float mx_ggx_dir_albedo(float NdotV, float alpha, float F0, float F90)
{
    return mx_ggx_dir_albedo(NdotV, alpha, vec3(F0), vec3(F90)).x;
}

// https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf
// Equations 14 and 16
vec3 mx_ggx_energy_compensation(float NdotV, float alpha, vec3 Fss)
{
    float Ess = mx_ggx_dir_albedo(NdotV, alpha, 1.0, 1.0);
    return 1.0 + Fss * (1.0 - Ess) / Ess;
}

float mx_ggx_energy_compensation(float NdotV, float alpha, float Fss)
{
    return mx_ggx_energy_compensation(NdotV, alpha, vec3(Fss)).x;
}

// Compute the average of an anisotropic alpha pair.
float mx_average_alpha(vec2 alpha)
{
    return sqrt(alpha.x * alpha.y);
}

// Convert a real-valued index of refraction to normal-incidence reflectivity.
float mx_ior_to_f0(float ior)
{
    return mx_square((ior - 1.0) / (ior + 1.0));
}

// Convert normal-incidence reflectivity to real-valued index of refraction.
float mx_f0_to_ior(float F0)
{
    float sqrtF0 = sqrt(clamp(F0, 0.01, 0.99));
    return (1.0 + sqrtF0) / (1.0 - sqrtF0);
}
vec3 mx_f0_to_ior(vec3 F0)
{
    vec3 sqrtF0 = sqrt(clamp(F0, 0.01, 0.99));
    return (vec3(1.0) + sqrtF0) / (vec3(1.0) - sqrtF0);
}

// https://renderwonk.com/publications/wp-generalization-adobe/gen-adobe.pdf
vec3 mx_fresnel_hoffman_schlick(float cosTheta, FresnelData fd)
{
    const float COS_THETA_MAX = 1.0 / 7.0;
    const float COS_THETA_FACTOR = 1.0 / (COS_THETA_MAX * pow(1.0 - COS_THETA_MAX, 6.0));

    float x = clamp(cosTheta, 0.0, 1.0);
    vec3 a = mix(fd.F0, fd.F90, pow(1.0 - COS_THETA_MAX, fd.exponent)) * (vec3(1.0) - fd.F82) * COS_THETA_FACTOR;
    return mix(fd.F0, fd.F90, pow(1.0 - x, fd.exponent)) - a * x * mx_pow6(1.0 - x);
}

// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/
float mx_fresnel_dielectric(float cosTheta, float ior)
{
    float c = cosTheta;
    float g2 = ior*ior + c*c - 1.0;
    if (g2 < 0.0)
    {
        // Total internal reflection
        return 1.0;
    }

    float g = sqrt(g2);
    return 0.5 * mx_square((g - c) / (g + c)) *
                (1.0 + mx_square(((g + c) * c - 1.0) / ((g - c) * c + 1.0)));
}

// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/
vec2 mx_fresnel_dielectric_polarized(float cosTheta, float ior)
{
    float cosTheta2 = mx_square(clamp(cosTheta, 0.0, 1.0));
    float sinTheta2 = 1.0 - cosTheta2;

    float t0 = max(ior * ior - sinTheta2, 0.0);
    float t1 = t0 + cosTheta2;
    float t2 = 2.0 * sqrt(t0) * cosTheta;
    float Rs = (t1 - t2) / (t1 + t2);

    float t3 = cosTheta2 * t0 + sinTheta2 * sinTheta2;
    float t4 = t2 * sinTheta2;
    float Rp = Rs * (t3 - t4) / (t3 + t4);

    return vec2(Rp, Rs);
}

// https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/
void mx_fresnel_conductor_polarized(float cosTheta, vec3 n, vec3 k, out vec3 Rp, out vec3 Rs)
{
    float cosTheta2 = mx_square(clamp(cosTheta, 0.0, 1.0));
    float sinTheta2 = 1.0 - cosTheta2;
    vec3 n2 = n * n;
    vec3 k2 = k * k;

    vec3 t0 = n2 - k2 - vec3(sinTheta2);
    vec3 a2plusb2 = sqrt(t0 * t0 + 4.0 * n2 * k2);
    vec3 t1 = a2plusb2 + vec3(cosTheta2);
    vec3 a = sqrt(max(0.5 * (a2plusb2 + t0), 0.0));
    vec3 t2 = 2.0 * a * cosTheta;
    Rs = (t1 - t2) / (t1 + t2);

    vec3 t3 = cosTheta2 * a2plusb2 + vec3(sinTheta2 * sinTheta2);
    vec3 t4 = t2 * sinTheta2;
    Rp = Rs * (t3 - t4) / (t3 + t4);
}

vec3 mx_fresnel_conductor(float cosTheta, vec3 n, vec3 k)
{
    vec3 Rp, Rs;
    mx_fresnel_conductor_polarized(cosTheta, n, k, Rp, Rs);
    return 0.5 * (Rp  + Rs);
}

// https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html
void mx_fresnel_conductor_phase_polarized(float cosTheta, float eta1, vec3 eta2, vec3 kappa2, out vec3 phiP, out vec3 phiS)
{
    vec3 k2 = kappa2 / eta2;
    vec3 sinThetaSqr = vec3(1.0) - cosTheta * cosTheta;
    vec3 A = eta2*eta2*(vec3(1.0)-k2*k2) - eta1*eta1*sinThetaSqr;
    vec3 B = sqrt(A*A + mx_square(2.0*eta2*eta2*k2));
    vec3 U = sqrt((A+B)/2.0);
    vec3 V = max(vec3(0.0), sqrt((B-A)/2.0));

    phiS = mx_atan(2.0*eta1*V*cosTheta, U*U + V*V - mx_square(eta1*cosTheta));
    phiP = mx_atan(2.0*eta1*eta2*eta2*cosTheta * (2.0*k2*U - (vec3(1.0)-k2*k2) * V),
                   mx_square(eta2*eta2*(vec3(1.0)+k2*k2)*cosTheta) - eta1*eta1*(U*U+V*V));
}

// https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html
vec3 mx_eval_sensitivity(float opd, vec3 shift)
{
    // Use Gaussian fits, given by 3 parameters: val, pos and var
    float phase = 2.0*M_PI * opd;
    vec3 val = vec3(5.4856e-13, 4.4201e-13, 5.2481e-13);
    vec3 pos = vec3(1.6810e+06, 1.7953e+06, 2.2084e+06);
    vec3 var = vec3(4.3278e+09, 9.3046e+09, 6.6121e+09);
    vec3 xyz = val * sqrt(2.0*M_PI * var) * mx_cos(pos * phase + shift) * exp(- var * phase*phase);
    xyz.x   += 9.7470e-14 * sqrt(2.0*M_PI * 4.5282e+09) * mx_cos(2.2399e+06 * phase + shift[0]) * exp(- 4.5282e+09 * phase*phase);
    return xyz / 1.0685e-7;
}

// A Practical Extension to Microfacet Theory for the Modeling of Varying Iridescence
// https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html
vec3 mx_fresnel_airy(float cosTheta, FresnelData fd)
{
    // XYZ to CIE 1931 RGB color space (using neutral E illuminant)
    const mat3 XYZ_TO_RGB = mat3(2.3706743, -0.5138850, 0.0052982, -0.9000405, 1.4253036, -0.0146949, -0.4706338, 0.0885814, 1.0093968);

    // Assume vacuum on the outside
    float eta1 = 1.0;
    float eta2 = max(fd.tf_ior, eta1);
    vec3 eta3 = (fd.model == FRESNEL_MODEL_SCHLICK) ? mx_f0_to_ior(fd.F0) : fd.ior;
    vec3 kappa3 = (fd.model == FRESNEL_MODEL_SCHLICK) ? vec3(0.0) : fd.extinction;
    float cosThetaT = sqrt(1.0 - (1.0 - mx_square(cosTheta)) * mx_square(eta1 / eta2));

    // First interface
    vec2 R12 = mx_fresnel_dielectric_polarized(cosTheta, eta2 / eta1);
    if (cosThetaT <= 0.0)
    {
        // Total internal reflection
        R12 = vec2(1.0);
    }
    vec2 T121 = vec2(1.0) - R12;

    // Second interface
    vec3 R23p, R23s;
    if (fd.model == FRESNEL_MODEL_SCHLICK)
    {
        vec3 f = mx_fresnel_hoffman_schlick(cosThetaT, fd);
        R23p = 0.5 * f;
        R23s = 0.5 * f;
    }
    else
    {
        mx_fresnel_conductor_polarized(cosThetaT, eta3 / eta2, kappa3 / eta2, R23p, R23s);
    }

    // Phase shift
    float cosB = mx_cos(mx_atan(eta2 / eta1));
    vec2 phi21 = vec2(cosTheta < cosB ? 0.0 : M_PI, M_PI);
    vec3 phi23p, phi23s;
    if (fd.model == FRESNEL_MODEL_SCHLICK)
    {
        phi23p = vec3((eta3[0] < eta2) ? M_PI : 0.0,
                      (eta3[1] < eta2) ? M_PI : 0.0,
                      (eta3[2] < eta2) ? M_PI : 0.0);
        phi23s = phi23p;
    }
    else
    {
        mx_fresnel_conductor_phase_polarized(cosThetaT, eta2, eta3, kappa3, phi23p, phi23s);
    }
    vec3 r123p = max(sqrt(R12.x*R23p), 0.0);
    vec3 r123s = max(sqrt(R12.y*R23s), 0.0);

    // Iridescence term
    vec3 I = vec3(0.0);
    vec3 Cm, Sm;

    // Optical path difference
    float distMeters = fd.tf_thickness * 1.0e-9;
    float opd = 2.0 * eta2 * cosThetaT * distMeters;

    // Iridescence term using spectral antialiasing for Parallel polarization

    // Reflectance term for m=0 (DC term amplitude)
    vec3 Rs = (mx_square(T121.x) * R23p) / (vec3(1.0) - R12.x*R23p);
    I += R12.x + Rs;

    // Reflectance term for m>0 (pairs of diracs)
    Cm = Rs - T121.x;
    for (int m=1; m<=2; m++)
    {
        Cm *= r123p;
        Sm  = 2.0 * mx_eval_sensitivity(float(m) * opd, float(m)*(phi23p+vec3(phi21.x)));
        I  += Cm*Sm;
    }

    // Iridescence term using spectral antialiasing for Perpendicular polarization

    // Reflectance term for m=0 (DC term amplitude)
    vec3 Rp = (mx_square(T121.y) * R23s) / (vec3(1.0) - R12.y*R23s);
    I += R12.y + Rp;

    // Reflectance term for m>0 (pairs of diracs)
    Cm = Rp - T121.y;
    for (int m=1; m<=2; m++)
    {
        Cm *= r123s;
        Sm  = 2.0 * mx_eval_sensitivity(float(m) * opd, float(m)*(phi23s+vec3(phi21.y)));
        I  += Cm*Sm;
    }

    // Average parallel and perpendicular polarization
    I *= 0.5;

    // Convert back to RGB reflectance
    I = clamp(XYZ_TO_RGB * I, 0.0, 1.0);

    return I;
}

FresnelData mx_init_fresnel_dielectric(float ior, float tf_thickness, float tf_ior)
{
    FresnelData fd;
    fd.model = FRESNEL_MODEL_DIELECTRIC;
    fd.airy = tf_thickness > 0.0;
    fd.ior = vec3(ior);
    fd.extinction = vec3(0.0);
    fd.F0 = vec3(0.0);
    fd.F82 = vec3(0.0);
    fd.F90 = vec3(0.0);
    fd.exponent = 0.0;
    fd.tf_thickness = tf_thickness;
    fd.tf_ior = tf_ior;
    fd.refraction = false;
    return fd;
}

FresnelData mx_init_fresnel_conductor(vec3 ior, vec3 extinction, float tf_thickness, float tf_ior)
{
    FresnelData fd;
    fd.model = FRESNEL_MODEL_CONDUCTOR;
    fd.airy = tf_thickness > 0.0;
    fd.ior = ior;
    fd.extinction = extinction;
    fd.F0 = vec3(0.0);
    fd.F82 = vec3(0.0);
    fd.F90 = vec3(0.0);
    fd.exponent = 0.0;
    fd.tf_thickness = tf_thickness;
    fd.tf_ior = tf_ior;
    fd.refraction = false;
    return fd;
}

FresnelData mx_init_fresnel_schlick(vec3 F0, vec3 F82, vec3 F90, float exponent, float tf_thickness, float tf_ior)
{
    FresnelData fd;
    fd.model = FRESNEL_MODEL_SCHLICK;
    fd.airy = tf_thickness > 0.0;
    fd.ior = vec3(0.0);
    fd.extinction = vec3(0.0);
    fd.F0 = F0;
    fd.F82 = F82;
    fd.F90 = F90;
    fd.exponent = exponent;
    fd.tf_thickness = tf_thickness;
    fd.tf_ior = tf_ior;
    fd.refraction = false;
    return fd;
}

vec3 mx_compute_fresnel(float cosTheta, FresnelData fd)
{
    if (fd.airy)
    {
         return mx_fresnel_airy(cosTheta, fd);
    }
    else if (fd.model == FRESNEL_MODEL_DIELECTRIC)
    {
        return vec3(mx_fresnel_dielectric(cosTheta, fd.ior.x));
    }
    else if (fd.model == FRESNEL_MODEL_CONDUCTOR)
    {
        return mx_fresnel_conductor(cosTheta, fd.ior, fd.extinction);
    }
    else
    {
        return mx_fresnel_hoffman_schlick(cosTheta, fd);
    }
}

// Compute the refraction of a ray through a solid sphere.
vec3 mx_refraction_solid_sphere(vec3 R, vec3 N, float ior)
{
    R = refract(R, N, 1.0 / ior);
    vec3 N1 = normalize(R * dot(R, N) - N * 0.5);
    return refract(R, N1, ior);
}

vec2 mx_latlong_projection(vec3 dir)
{
    float latitude = -mx_asin(dir.y) * M_PI_INV + 0.5;
    float longitude = mx_atan(dir.x, -dir.z) * M_PI_INV * 0.5 + 0.5;
    return vec2(longitude, latitude);
}

#ifdef HW_SEPARATE_SAMPLERS
vec3 mx_latlong_map_lookup(vec3 dir, mat4 transform, float lod, texture2D env_texture, sampler env_sampler)
{
    vec3 envDir = normalize((transform * vec4(dir,0.0)).xyz);
    vec2 uv = mx_latlong_projection(envDir);
    return textureLod(sampler2D(env_texture, env_sampler), uv, lod).rgb;
}
#else
vec3 mx_latlong_map_lookup(vec3 dir, mat4 transform, float lod, sampler2D envSampler)
{
    vec3 envDir = normalize((transform * vec4(dir,0.0)).xyz);
    vec2 uv = mx_latlong_projection(envDir);
    return textureLod(envSampler, uv, lod).rgb;
}
#endif

// Return the mip level with the appropriate coverage for a filtered importance sample.
// https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html
// Section 20.4 Equation 13
float mx_latlong_compute_lod(vec3 dir, float pdf, float maxMipLevel, int envSamples)
{
    const float MIP_LEVEL_OFFSET = 1.5;
    float effectiveMaxMipLevel = maxMipLevel - MIP_LEVEL_OFFSET;
    float distortion = sqrt(1.0 - mx_square(dir.y));
    return max(effectiveMaxMipLevel - 0.5 * log2(float(envSamples) * pdf * distortion), 0.0);
}
<?xml version="1.0"?>
<materialx version="1.39">

  <!-- <oren_nayar_diffuse_bsdf> -->
  <implementation name="IM_oren_nayar_diffuse_bsdf_genosl" nodedef="ND_oren_nayar_diffuse_bsdf" sourcecode="{{weight}} * oren_nayar_diffuse_bsdf({{normal}}, {{color}}, {{roughness}})" target="genosl" />

  <!-- <burley_diffuse_bsdf> -->
  <implementation name="IM_burley_diffuse_bsdf_genosl" nodedef="ND_burley_diffuse_bsdf" sourcecode="{{weight}} * burley_diffuse_bsdf({{normal}}, {{color}}, {{roughness}})" target="genosl" />

  <!-- <translucent_bsdf> -->
  <implementation name="IM_translucent_bsdf_genosl" nodedef="ND_translucent_bsdf" sourcecode="{{weight}} * translucent_bsdf({{normal}}, {{color}})" target="genosl" />

  <!-- <dielectric_bsdf> -->
  <implementation name="IM_dielectric_bsdf_genosl" nodedef="ND_dielectric_bsdf" file="mx_dielectric_bsdf.osl" function="mx_dielectric_bsdf" target="genosl" />

  <!-- <conductor_bsdf> -->
  <implementation name="IM_conductor_bsdf_genosl" nodedef="ND_conductor_bsdf" sourcecode="{{weight}} * conductor_bsdf({{normal}}, {{tangent}}, {{roughness}}.x, {{roughness}}.y, {{ior}}, {{extinction}}, {{distribution}}, &quot;thinfilm_thickness&quot;, {{thinfilm_thickness}}, &quot;thinfilm_ior&quot;, {{thinfilm_ior}})" target="genosl" />

  <!-- <generalized_schlick_bsdf> -->
  <implementation name="IM_generalized_schlick_bsdf_genosl" nodedef="ND_generalized_schlick_bsdf" file="mx_generalized_schlick_bsdf.osl" function="mx_generalized_schlick_bsdf" target="genosl" />

  <!-- <subsurface_bsdf> -->
  <implementation name="IM_subsurface_bsdf_genosl" nodedef="ND_subsurface_bsdf" file="mx_subsurface_bsdf.osl" function="mx_subsurface_bsdf" target="genosl" />

  <!-- <chiang_hair_bsdf> -->
  <implementation name="IM_chiang_hair_bsdf_genosl" nodedef="ND_chiang_hair_bsdf" file="mx_chiang_hair_bsdf.osl" function="mx_chiang_hair_bsdf" target="genosl" />

  <!-- <sheen_bsdf> -->
  <implementation name="IM_sheen_bsdf_genosl" nodedef="ND_sheen_bsdf" sourcecode="{{weight}} * sheen_bsdf({{normal}}, {{color}}, {{roughness}})" target="genosl" />

  <!-- <anisotropic_vdf> -->
  <implementation name="IM_anisotropic_vdf_genosl" nodedef="ND_anisotropic_vdf" file="mx_anisotropic_vdf.osl" function="mx_anisotropic_vdf" target="genosl" />

  <!-- <uniform_edf> -->
  <implementation name="IM_uniform_edf_genosl" nodedef="ND_uniform_edf" sourcecode="uniform_edf({{color}})" target="genosl" />

  <!-- <generalized_schlick_edf> -->
  <implementation name="IM_generalized_schlick_edf_genosl" nodedef="ND_generalized_schlick_edf" file="mx_generalized_schlick_edf.osl" function="mx_generalized_schlick_edf" target="genosl" />

  <!-- <layer> -->
  <implementation name="IM_layer_bsdf_genosl" nodedef="ND_layer_bsdf" sourcecode="layer({{top}}, {{base}})" target="genosl" />
  <implementation name="IM_layer_vdf_genosl" nodedef="ND_layer_vdf" sourcecode="layer({{top}}, {{base}})" target="genosl" />

  <!-- <mix> -->
  <implementation name="IM_mix_bsdf_genosl" nodedef="ND_mix_bsdf" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" target="genosl" />
  <implementation name="IM_mix_edf_genosl" nodedef="ND_mix_edf" sourcecode="mix({{bg}}, {{fg}}, {{mix}})" target="genosl" />

  <!-- <add> -->
  <implementation name="IM_add_bsdf_genosl" nodedef="ND_add_bsdf" sourcecode="({{in1}} + {{in2}})" target="genosl" />
  <implementation name="IM_add_edf_genosl" nodedef="ND_add_edf" sourcecode="({{in1}} + {{in2}})" target="genosl" />

  <!-- <multiply> -->
  <implementation name="IM_multiply_bsdfC_genosl" nodedef="ND_multiply_bsdfC" sourcecode="({{in2}} * {{in1}})" target="genosl" />
  <implementation name="IM_multiply_bsdfF_genosl" nodedef="ND_multiply_bsdfF" sourcecode="({{in2}} * {{in1}})" target="genosl" />
  <implementation name="IM_multiply_edfC_genosl" nodedef="ND_multiply_edfC" sourcecode="({{in2}} * {{in1}})" target="genosl" />
  <implementation name="IM_multiply_edfF_genosl" nodedef="ND_multiply_edfF" sourcecode="({{in2}} * {{in1}})" target="genosl" />

  <!-- <surface> -->
  <implementation name="IM_surface_genosl" nodedef="ND_surface" file="mx_surface.osl" function="mx_surface" target="genosl" />

  <!-- <displacement> -->
  <implementation name="IM_displacement_float_genosl" nodedef="ND_displacement_float" sourcecode="vector({{displacement}} * {{scale}})" target="genosl" />
  <implementation name="IM_displacement_vector3_genosl" nodedef="ND_displacement_vector3" sourcecode="({{displacement}} * {{scale}})" target="genosl" />

  <!-- <roughness_anisotropy> -->
  <implementation name="IM_roughness_anisotropy_genosl" nodedef="ND_roughness_anisotropy" file="mx_roughness_anisotropy.osl" function="mx_roughness_anisotropy" target="genosl" />

  <!-- <roughness_dual> -->
  <implementation name="IM_roughness_dual_genosl" nodedef="ND_roughness_dual" file="mx_roughness_dual.osl" function="mx_roughness_dual" target="genosl" />

  <!-- <artistic_ior> -->
  <implementation name="IM_artistic_ior_genosl" nodedef="ND_artistic_ior" file="mx_artistic_ior.osl" function="mx_artistic_ior" target="genosl" />

  <!-- <blackbody> -->
  <implementation name="IM_blackbody_genosl" nodedef="ND_blackbody" file="mx_blackbody.osl" function="mx_blackbody" target="genosl" />

  <!-- <deon_hair_absorption_from_melanin> -->
  <implementation name="IM_deon_hair_absorption_from_melanin_genosl" nodedef="ND_deon_hair_absorption_from_melanin" sourcecode="vector(1.0)" target="genosl" />

  <!-- <chiang_hair_absorption_from_color> -->
  <implementation name="IM_chiang_hair_absorption_from_color_genosl" nodedef="ND_chiang_hair_absorption_from_color" sourcecode="vector(1.0)" target="genosl" />

  <!-- <chiang_hair_roughness> -->
  <implementation name="IM_chiang_hair_roughness_genosl" nodedef="ND_chiang_hair_roughness" file="mx_chiang_hair_roughness.osl" function="mx_chiang_hair_roughness" target="genosl" />

</materialx>
void mx_subsurface_bsdf(float weight, color albedo, color radius, float anisotropy, normal N, output BSDF bsdf)
{
#if OSL_VERSION_MAJOR >= 1 && OSL_VERSION_MINOR >= 14
    bsdf = weight * subsurface_bssrdf(N, albedo, radius, anisotropy);
#else
    bsdf = weight * subsurface_bssrdf(N, albedo, 1.0, radius, anisotropy);
#endif
}
void mx_anisotropic_vdf(color absorption, color scattering, float anisotropy, output VDF vdf)
{
    // Convert from absorption and scattering coefficients to
    // extinction coefficient and single-scattering albedo.
    color extinction = absorption + scattering;
    color albedo = scattering / extinction;
    vdf = anisotropic_vdf(albedo, extinction, anisotropy);
}
void mx_surface(BSDF bsdf, EDF edf, float opacity, int thin_walled, output surfaceshader result)
{
    result.bsdf    = bsdf;
    result.edf     = edf;
    result.opacity = clamp(opacity, 0.0, 1.0);
}
void mx_artistic_ior(color reflectivity, color edge_color, output vector ior, output vector extinction)
{
    // "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
    // http://jcgt.org/published/0003/04/03/paper.pdf

    color r = clamp(reflectivity, 0.0, 0.99);
    color r_sqrt = sqrt(r);
    color n_min = (1.0 - r) / (1.0 + r);
    color n_max = (1.0 + r_sqrt) / (1.0 - r_sqrt);
    ior = mix(n_max, n_min, edge_color);

    color np1 = ior + 1.0;
    color nm1 = ior - 1.0;
    color k2 = (np1*np1 * r - nm1*nm1) / (1.0 - r);
    k2 = max(k2, 0.0);
    extinction = sqrt(k2);
}
void mx_dielectric_bsdf(float weight, color tint, float ior, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
{
    color reflection_tint = (scatter_mode == "T") ? color(0.0) : tint;
    color transmission_tint = (scatter_mode == "R") ? color(0.0) : tint;
    bsdf = weight * dielectric_bsdf(N, U, reflection_tint, transmission_tint, roughness.x, roughness.y, ior, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior);
}
void mx_chiang_hair_roughness(float longitudinal, float azimuthal, float scale_TT, float scale_TRT, output vector2 roughness_R, output vector2 roughness_TT, output vector2 roughness_TRT)
{
    // TODO: Write OSL implementation of this node.
    roughness_R = vector2(0.0, 0.0);
    roughness_TT = vector2(0.0, 0.0);
    roughness_TRT = vector2(0.0, 0.0);
}
void mx_roughness_dual(vector2 roughness, output vector2 result)
{
    result.x = clamp(roughness.x * roughness.x, M_FLOAT_EPS, 1.0);
    if (roughness.y < 0.0)
    {
        result.y = result.x;
    }
    else
    {
        result.y = clamp(roughness.y * roughness.y, M_FLOAT_EPS, 1.0);
    }
}
void mx_chiang_hair_bsdf(color tint_R, color tint_TT, color tint_TRT, float ior,
                         vector2 roughness_R, vector2 roughness_TT, vector2 roughness_TRT,
                         float cuticle_angle, vector absorption_coefficient, normal N, vector U, output BSDF bsdf)
{
#if OSL_VERSION_MAJOR >= 1 && OSL_VERSION_MINOR >= 14
    bsdf = chiang_hair_bsdf(N, U, tint_R, tint_TT, tint_TRT, ior,
                            roughness_R.x, roughness_TT.x, roughness_TRT.x, roughness_R.y, roughness_TT.y, roughness_TRT.y,
                            cuticle_angle, absorption_coefficient);
#else
    bsdf = dielectric_bsdf(N, U, color(1), color(0), 0.1, 0.1, ior, "ggx");
#endif
}
void mx_blackbody(float temp, output color color_value)
{
    float xc, yc;
    float t, t2, t3, xc2, xc3;

    // if value outside valid range of approximation clamp to accepted temperature range
    float temperature = clamp(temp, 1667.0, 25000.0);

    t = 1000.0 / temperature;
    t2 = t * t;
    t3 = t * t * t;

    // Cubic spline approximation for Kelvin temperature to sRGB conversion
    // (https://en.wikipedia.org/wiki/Planckian_locus#Approximation)
    if (temperature < 4000.0) {  // 1667K <= temperature < 4000K
      xc = -0.2661239 * t3 - 0.2343580 * t2 + 0.8776956 * t + 0.179910;
    }
    else {  // 4000K <= temperature <= 25000K
      xc = -3.0258469 * t3 + 2.1070379 * t2 + 0.2226347 * t + 0.240390;
    }
    xc2 = xc * xc;
    xc3 = xc * xc * xc;

    if (temperature < 2222.0) {  // 1667K <= temperature < 2222K
      yc = -1.1063814 * xc3 - 1.34811020 * xc2 + 2.18555832 * xc - 0.20219683;
    }
    else if (temperature < 4000.0) {  // 2222K <= temperature < 4000K
      yc = -0.9549476 * xc3 - 1.37418593 * xc2 + 2.09137015 * xc - 0.16748867;
    }
    else {  // 4000K <= temperature <= 25000K
      yc = 3.0817580 * xc3 - 5.87338670 * xc2 + 3.75112997 * xc - 0.37001483;
    }

    if (yc <= 0.0) {  // avoid division by zero
      color_value = color(1.0);
      return;
    }

    vector XYZ = vector(xc / yc, 1.0, (1 - xc - yc) / yc);

    /// XYZ to Rec.709 RGB colorspace conversion
    matrix XYZ_to_RGB = matrix( 3.2406, -0.9689,  0.0557, 0.0,
                               -1.5372,  1.8758, -0.2040, 0.0,
                               -0.4986,  0.0415,  1.0570, 0.0,
                                   0.0,     0.0,     0.0, 1.0);

    color_value = transform(XYZ_to_RGB, XYZ);
    color_value = max(color_value, vector(0.0));
}
#include "lib/mx_microfacet.osl"

void mx_generalized_schlick_edf(color color0, color color90, float exponent, EDF base, output EDF result)
{
    float NdotV = fabs(dot(N,-I));
    color f = mx_fresnel_schlick(NdotV, color0, color90, exponent);
    result = base * f;
}
void mx_generalized_schlick_bsdf(float weight, color color0, color color82, color color90, float exponent, vector2 roughness, float thinfilm_thickness, float thinfilm_ior, normal N, vector U, string distribution, string scatter_mode, output BSDF bsdf)
{
    color reflection_tint = (scatter_mode == "T") ? color(0.0) : color(1.0);
    color transmission_tint = (scatter_mode == "R") ? color(0.0) : color(1.0);
    bsdf = weight * generalized_schlick_bsdf(N, U, reflection_tint, transmission_tint, roughness.x, roughness.y, color0, color90, exponent, distribution, "thinfilm_thickness", thinfilm_thickness, "thinfilm_ior", thinfilm_ior);
}
void mx_roughness_anisotropy(float roughness, float anisotropy, output vector2 result)
{
    float roughness_sqr = clamp(roughness*roughness, M_FLOAT_EPS, 1.0);
    if (anisotropy > 0.0)
    {
        float aspect = sqrt(1.0 - clamp(anisotropy, 0.0, 0.98));
        result.x = min(roughness_sqr / aspect, 1.0);
        result.y = roughness_sqr * aspect;
    }
    else
    {
        result.x = roughness_sqr;
        result.y = roughness_sqr;
    }
}
float mx_square(float x)
{
    return x*x;
}

vector2 mx_square(vector2 x)
{
    return x*x;
}

vector mx_square(vector x)
{
    return x*x;
}

vector4 mx_square(vector4 x)
{
    return x*x;
}

float mx_pow5(float x)
{
    return mx_square(mx_square(x)) * x;
}

color mx_fresnel_conductor(float cosTheta, vector n, vector k)
{
   float c2 = cosTheta*cosTheta;
   vector n2_k2 = n*n + k*k;
   vector nc2 = 2.0 * n * cosTheta;

   vector rs_a = n2_k2 + c2;
   vector rp_a = n2_k2 * c2 + 1.0;
   vector rs = (rs_a - nc2) / (rs_a + nc2);
   vector rp = (rp_a - nc2) / (rp_a + nc2);

   return 0.5 * (rs + rp);
}

// Standard Schlick Fresnel
float mx_fresnel_schlick(float cosTheta, float F0)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    float x5 = mx_pow5(x);
    return F0 + (1.0 - F0) * x5;
}
color mx_fresnel_schlick(float cosTheta, color F0)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    float x5 = mx_pow5(x);
    return F0 + (1.0 - F0) * x5;
}

// Generalized Schlick Fresnel
float mx_fresnel_schlick(float cosTheta, float F0, float F90)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    float x5 = mx_pow5(x);
    return mix(F0, F90, x5);
}
color mx_fresnel_schlick(float cosTheta, color F0, color F90)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    float x5 = mx_pow5(x);
    return mix(F0, F90, x5);
}

// Generalized Schlick Fresnel with a variable exponent
color mx_fresnel_schlick(float cosTheta, float f0, float f90, float exponent)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    return mix(f0, f90, pow(x, exponent));
}
color mx_fresnel_schlick(float cosTheta, color f0, color f90, float exponent)
{
    float x = clamp(1.0 - cosTheta, 0.0, 1.0);
    return mix(f0, f90, pow(x, exponent));
}
<?xml version="1.0"?>
<materialx version="1.39">

  <!-- <oren_nayar_diffuse_bsdf> -->
  <implementation name="IM_oren_nayar_diffuse_bsdf_genmdl" nodedef="ND_oren_nayar_diffuse_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_oren_nayar_diffuse_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_energy_compensation:{{energy_compensation}})" target="genmdl" />

  <!-- <burley_diffuse_bsdf> -->
  <implementation name="IM_burley_diffuse_bsdf_genmdl" nodedef="ND_burley_diffuse_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_burley_diffuse_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}})" target="genmdl" />

  <!-- <translucent_bsdf> -->
  <implementation name="IM_translucent_bsdf_genmdl" nodedef="ND_translucent_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_translucent_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_normal:{{normal}})" target="genmdl" />

  <!-- <dielectric_bsdf> -->
  <implementation name="IM_dielectric_bsdf_genmdl" nodedef="ND_dielectric_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_dielectric_bsdf(mxp_weight:{{weight}}, mxp_tint:{{tint}}, mxp_ior:{{ior}}, mxp_roughness:{{roughness}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}}, mxp_top_weight:{{top_weight}})" target="genmdl" />

  <!-- <conductor_bsdf> -->
  <implementation name="IM_conductor_bsdf_genmdl" nodedef="ND_conductor_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_conductor_bsdf(mxp_weight:{{weight}}, mxp_ior:{{ior}}, mxp_extinction:{{extinction}}, mxp_roughness:{{roughness}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}})" target="genmdl" />

  <!-- <generalized_schlick_bsdf> -->
  <implementation name="IM_generalized_schlick_bsdf_genmdl" nodedef="ND_generalized_schlick_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_generalized_schlick_bsdf(mxp_weight:{{weight}}, mxp_color0:{{color0}}, mxp_color82:{{color82}}, mxp_color90:{{color90}}, mxp_exponent:{{exponent}},mxp_roughness:{{roughness}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}}, mxp_top_weight:{{top_weight}})" target="genmdl" />

  <!-- <subsurface_bsdf> -->
  <implementation name="IM_subsurface_bsdf_genmdl" nodedef="ND_subsurface_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_subsurface_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_radius:{{radius}}, mxp_anisotropy:{{anisotropy}}, mxp_normal:{{normal}})" target="genmdl" />

  <!-- <sheen_bsdf> -->
  <implementation name="IM_sheen_bsdf_genmdl" nodedef="ND_sheen_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_sheen_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_mode:{{mode}}, mxp_base:{{base}})" target="genmdl" />

  <!-- <chiang_hair_bsdf> -->
  <implementation name="IM_chiang_hair_bsdf_genmdl" nodedef="ND_chiang_hair_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_chiang_hair_bsdf(mxp_tint_R:{{tint_R}}, mxp_tint_TT:{{tint_TT}}, mxp_tint_TRT:{{tint_TRT}}, mxp_ior:{{ior}}, mxp_roughness_R:{{roughness_R}}, mxp_roughness_TT:{{roughness_TT}}, mxp_roughness_TRT:{{roughness_TRT}}, mxp_cuticle_angle:{{cuticle_angle}}, mxp_absorption_coefficient:{{absorption_coefficient}}, mxp_curve_direction:{{curve_direction}})" target="genmdl" />

  <!-- <uniform_edf> -->
  <implementation name="IM_uniform_edf_genmdl" nodedef="ND_uniform_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_uniform_edf(mxp_color:{{color}})" target="genmdl" />

  <!-- <conical_edf> -->
  <implementation name="IM_conical_edf_genmdl" nodedef="ND_conical_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_conical_edf(mxp_color:{{color}}, mxp_normal:{{normal}}, mxp_inner_angle:{{inner_angle}}, mxp_outer_angle:{{outer_angle}})" target="genmdl" />

  <!-- <measured_edf> -->
  <implementation name="IM_measured_edf_genmdl" nodedef="ND_measured_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_measured_edf(mxp_color:{{color}}, mxp_normal:{{normal}}, mxp_file:{{file}}" target="genmdl" />

  <!-- <generalized_schlick_edf> -->
  <implementation name="IM_generalized_schlick_edf_genmdl" nodedef="ND_generalized_schlick_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_generalized_schlick_edf(mxp_color0:{{color0}}, mxp_color90:{{color90}}, mxp_exponent:{{exponent}}, mxp_base:{{base}})" target="genmdl" />

  <!-- <absorption_vdf> -->
  <implementation name="IM_absorption_vdf_genmdl" nodedef="ND_absorption_vdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_absorption_vdf(mxp_absorption:{{absorption}})" target="genmdl" />

  <!-- <anisotropic_vdf> -->
  <implementation name="IM_anisotropic_vdf_genmdl" nodedef="ND_anisotropic_vdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_anisotropic_vdf(mxp_absorption:{{absorption}}, mxp_scattering:{{scattering}}, mxp_anisotropy:{{anisotropy}})" target="genmdl" />

  <!-- <surface> -->
  <implementation name="IM_surface_genmdl" nodedef="ND_surface" target="genmdl" />

  <!-- <volume> -->
  <implementation name="IM_volume_genmdl" nodedef="ND_volume" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_volume(mxp_vdf:{{vdf}}, mxp_edf:{{edf}})" target="genmdl" />

  <!-- <light> -->
  <implementation name="IM_light_genmdl" nodedef="ND_light" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_light(mxp_edf:{{edf}}, mxp_intensity:{{intensity}}, mxp_exposure:{{exposure}})" target="genmdl" />

  <!-- <displacement> -->
  <implementation name="IM_displacement_float_genmdl" nodedef="ND_displacement_float" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_displacement_float(mxp_displacement:{{displacement}}, mxp_scale:{{scale}})" target="genmdl" />
  <implementation name="IM_displacement_vector3_genmdl" nodedef="ND_displacement_vector3" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_displacement_vector3(mxp_displacement:{{displacement}}, mxp_scale:{{scale}})" target="genmdl" />

  <!-- <layer> -->
  <implementation name="IM_layer_bsdf_genmdl" nodedef="ND_layer_bsdf" target="genmdl" />
  <implementation name="IM_layer_vdf_genmdl" nodedef="ND_layer_vdf" target="genmdl" />

  <!-- <mix> -->
  <implementation name="IM_mix_bsdf_genmdl" nodedef="ND_mix_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_mix_bsdf(mxp_fg:{{fg}}, mxp_bg:{{bg}}, mxp_mix:{{mix}})" target="genmdl" />
  <implementation name="IM_mix_edf_genmdl" nodedef="ND_mix_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_mix_edf(mxp_fg:{{fg}}, mxp_bg:{{bg}}, mxp_mix:{{mix}})" target="genmdl" />
  <implementation name="IM_mix_vdf_genmdl" nodedef="ND_mix_vdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_mix_vdf(mxp_fg:{{fg}}, mxp_bg:{{bg}}, mxp_mix:{{mix}})" target="genmdl" />

  <!-- <add> -->
  <implementation name="IM_add_bsdf_genmdl" nodedef="ND_add_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_add_bsdf(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
  <implementation name="IM_add_edf_genmdl" nodedef="ND_add_edf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_add_edf(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
  <implementation name="IM_add_vdf_genmdl" nodedef="ND_add_vdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_add_vdf(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />

  <!-- <multiply> -->
  <implementation name="IM_multiply_bsdfC_genmdl" nodedef="ND_multiply_bsdfC" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_bsdf_color3(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
  <implementation name="IM_multiply_bsdfF_genmdl" nodedef="ND_multiply_bsdfF" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_bsdf_float(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
  <implementation name="IM_multiply_edfC_genmdl" nodedef="ND_multiply_edfC" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_edf_color3(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
  <implementation name="IM_multiply_edfF_genmdl" nodedef="ND_multiply_edfF" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_edf_float(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
  <implementation name="IM_multiply_vdfC_genmdl" nodedef="ND_multiply_vdfC" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_vdf_color3(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />
  <implementation name="IM_multiply_vdfF_genmdl" nodedef="ND_multiply_vdfF" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_multiply_vdf_float(mxp_in1:{{in1}}, mxp_in2:{{in2}})" target="genmdl" />

  <!-- <roughness_anisotropy> -->
  <implementation name="IM_roughness_anisotropy_genmdl" nodedef="ND_roughness_anisotropy" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_roughness_anisotropy(mxp_roughness:{{roughness}}, mxp_anisotropy:{{anisotropy}})" target="genmdl" />

  <!-- <roughness_dual> -->
  <implementation name="IM_roughness_dual_genmdl" nodedef="ND_roughness_dual" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_roughness_dual(mxp_roughness:{{roughness}})" target="genmdl" />

  <!-- <artistic_ior> -->
  <implementation name="IM_artistic_ior_genmdl" nodedef="ND_artistic_ior" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_artistic_ior(mxp_reflectivity:{{reflectivity}}, mxp_edge_color:{{edge_color}})" target="genmdl" />

  <!-- <blackbody> -->
  <implementation name="IM_blackbody_genmdl" nodedef="ND_blackbody" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_blackbody(mxp_temperature:{{temperature}})" target="genmdl" />

  <!-- <deon_hair_absorption_from_melanin> -->
  <implementation name="IM_deon_hair_absorption_from_melanin_genmdl" nodedef="ND_deon_hair_absorption_from_melanin" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_deon_hair_absorption_from_melanin(mxp_melanin_concentration:{{melanin_concentration}}, mxp_melanin_redness:{{melanin_redness}}, mxp_eumelanin_color:{{eumelanin_color}}, mxp_pheomelanin_color:{{pheomelanin_color}})" function="mx_deon_hair_absorption_from_melanin" target="genmdl" />

  <!-- <chiang_hair_absorption_from_color> -->
  <implementation name="IM_chiang_hair_absorption_from_color_genmdl" nodedef="ND_chiang_hair_absorption_from_color" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_chiang_hair_absorption_from_color(mxp_color:{{color}}, mxp_azimuthal_roughness:{{azimuthal_roughness}})" function="mx_chiang_hair_absorption_from_color" target="genmdl" />

  <!-- <chiang_hair_roughness> -->
  <implementation name="IM_chiang_hair_roughness_genmdl" nodedef="ND_chiang_hair_roughness" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_chiang_hair_roughness(mxp_longitudinal:{{longitudinal}}, mxp_azimuthal:{{azimuthal}}, mxp_scale_TT:{{scale_TT}}, mxp_scale_TRT:{{scale_TRT}})" target="genmdl" />

</materialx>
<?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">

  <!-- ======================================================================== -->
  <!-- USD Preview Surface node definitions                                     -->
  <!-- ======================================================================== -->

  <!-- Node: UsdPreviewSurface -->
  <nodedef name="ND_UsdPreviewSurface_surfaceshader" node="UsdPreviewSurface" nodegroup="pbr" doc="UsdPreviewSurface shader" version="2.6" isdefaultversion="true">
    <input name="diffuseColor" type="color3" value="0.18, 0.18, 0.18" uimin="0,0,0" uimax="1,1,1" uiname="Diffuse Color" />
    <input name="emissiveColor" type="color3" value="0, 0, 0" uimin="0,0,0" uisoftmax="1,1,1" uiname="Emissive Color" />
    <input name="useSpecularWorkflow" type="integer" value="0" uimin="0" uimax="1" uistep="1" uiname="Use Specular Workflow" />
    <input name="specularColor" type="color3" value="0, 0, 0" uimin="0,0,0" uimax="1,1,1" uiname="Specular Color" />
    <input name="metallic" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Metallic" />
    <input name="roughness" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Roughness" />
    <input name="clearcoat" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Clearcoat" />
    <input name="clearcoatRoughness" type="float" value="0.01" uimin="0.0" uimax="1.0" uiname="Clearcoat Roughness" />
    <input name="opacity" type="float" value="1" uimin="0.0" uimax="1.0" uiname="Opacity" />
    <input name="opacityMode" type="integer" enum="transparent,presence" enumvalues="0,1" value="0" uiname="Opacity Mode" />
    <input name="opacityThreshold" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Opacity Threshold" />
    <input name="ior" type="float" value="1.5" uimin="0.0" uisoftmin="1.0" uisoftmax="3.0" uiname="Index of Refraction" />
    <input name="normal" type="vector3" value="0, 0, 1" uimin="-1.0,-1.0,-1.0" uimax="1.0,1.0,1.0" uiname="Normal" />
    <input name="displacement" type="float" value="0" uiname="Displacement" />
    <input name="occlusion" type="float" value="1" uimin="0.0" uimax="1.0" uiname="Occlusion" />
    <output name="out" type="surfaceshader" />
  </nodedef>

  <!-- Node: UsdUVTexture -->
  <nodedef name="ND_UsdUVTexture" node="UsdUVTexture" nodegroup="texture2d" version="2.2" inherit="ND_UsdUVTexture_23">
    <output name="r" type="float" />
    <output name="g" type="float" />
    <output name="b" type="float" />
    <output name="a" type="float" />
    <output name="rgb" type="color3" />
    <output name="rgba" type="color4" />
  </nodedef>

  <nodedef name="ND_UsdUVTexture_23" node="UsdUVTexture" nodegroup="texture2d" version="2.3" isdefaultversion="true">
    <input name="file" type="filename" value="" uniform="true" />
    <input name="st" type="vector2" defaultgeomprop="UV0" />
    <input name="wrapS" type="string" value="periodic" enum="black,clamp,periodic,mirror" uniform="true" />
    <input name="wrapT" type="string" value="periodic" enum="black,clamp,periodic,mirror" uniform="true" />
    <input name="fallback" type="color4" value="0, 0, 0, 1" />
    <input name="scale" type="color4" value="1, 1, 1, 1" uniform="true" />
    <input name="bias" type="color4" value="0, 0, 0, 0" uniform="true" />
    <output name="r" type="float" />
    <output name="g" type="float" />
    <output name="b" type="float" />
    <output name="a" type="float" />
    <output name="rgb" type="color3" />
  </nodedef>

  <!-- Node: UsdPrimvarReader -->
  <nodedef name="ND_UsdPrimvarReader_integer" nodegroup="geometric" node="UsdPrimvarReader">
    <input name="varname" type="string" value="" uniform="true" />
    <input name="fallback" type="integer" value="0" />
    <output name="out" type="integer" />
  </nodedef>
  <nodedef name="ND_UsdPrimvarReader_boolean" nodegroup="geometric" node="UsdPrimvarReader">
    <input name="varname" type="string" value="" uniform="true" />
    <input name="fallback" type="boolean" value="false" />
    <output name="out" type="boolean" />
  </nodedef>
  <nodedef name="ND_UsdPrimvarReader_string" nodegroup="geometric" node="UsdPrimvarReader">
    <input name="varname" type="string" value="" uniform="true" />
    <input name="fallback" type="string" value="" uniform="true" />
    <output name="out" type="string" uniform="true"/>
  </nodedef>
  <nodedef name="ND_UsdPrimvarReader_filename" nodegroup="geometric" node="UsdPrimvarReader">
    <input name="varname" type="string" value="" uniform="true" />
    <input name="fallback" type="filename" value="" uniform="true" />
    <output name="out" type="filename" uniform="true"/>
  </nodedef>
  <nodedef name="ND_UsdPrimvarReader_float" nodegroup="geometric" node="UsdPrimvarReader">
    <input name="varname" type="string" value="" uniform="true" />
    <input name="fallback" type="float" value="0" />
    <output name="out" type="float" />
  </nodedef>
  <nodedef name="ND_UsdPrimvarReader_vector2" nodegroup="geometric" node="UsdPrimvarReader">
    <input name="varname" type="string" value="" uniform="true" />
    <input name="fallback" type="vector2" value="0, 0" />
    <output name="out" type="vector2" />
  </nodedef>
  <nodedef name="ND_UsdPrimvarReader_vector3" nodegroup="geometric" node="UsdPrimvarReader">
    <input name="varname" type="string" value="" uniform="true" />
    <input name="fallback" type="vector3" value="0, 0, 0" />
    <output name="out" type="vector3" />
  </nodedef>
  <nodedef name="ND_UsdPrimvarReader_vector4" nodegroup="geometric" node="UsdPrimvarReader">
    <input name="varname" type="string" value="" uniform="true" />
    <input name="fallback" type="vector4" value="0, 0, 0, 0" />
    <output name="out" type="vector4" />
  </nodedef>
  <!-- TODO: Getting primvar of matrix type is not supported in MaterialX standard library.
  <nodedef name="ND_UsdPrimvarReader_matrix44" node="UsdPrimvarReader">
    <input name="varname" type="string" />
    <input name="fallback" type="matrix44" value="1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1" />
    <output name="out" type="matrix44" />
  </nodedef>
  -->

  <!-- Node: UsdTransform2d -->
  <nodedef name="ND_UsdTransform2d" nodegroup="math" node="UsdTransform2d">
    <input name="in" type="vector2" value="0, 0" />
    <input name="rotation" type="float" value="0" />
    <input name="scale" type="vector2" value="1, 1" />
    <input name="translation" type="vector2" value="0, 0" />
    <output name="out" type="vector2" />
  </nodedef>

  <!-- ======================================================================== -->
  <!-- USD Preview Surface nodegraph implementations                            -->
  <!-- ======================================================================== -->

  <!-- Node: UsdPreviewSurface -->
  <nodegraph name="IMP_UsdPreviewSurface_surfaceshader" nodedef="ND_UsdPreviewSurface_surfaceshader">

    <convert name="use_specular_workflow_float" type="float">
      <input name="in" type="integer" interfacename="useSpecularWorkflow" />
    </convert>

    <!-- Compute the surface normal -->
    <multiply name="scale_normal" type="vector3">
      <input name="in1" type="vector3" interfacename="normal" />
      <input name="in2" type="float" value="0.5" />
    </multiply>
    <add name="bias_normal" type="vector3">
      <input name="in1" type="vector3" nodename="scale_normal" />
      <input name="in2" type="float" value="0.5" />
    </add>
    <normalmap name="surface_normal" type="vector3">
      <input name="in" type="vector3" nodename="bias_normal" />
    </normalmap>

    <!-- Diffuse Layer -->
    <subtract name="inverse_metalness" type="float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" interfacename="metallic" />
    </subtract>
    <mix name="diffuse_bsdf_weight" type="float">
      <input name="fg" type="float" value="1.0" />
      <input name="bg" type="float" nodename="inverse_metalness" />
      <input name="mix" type="float" nodename="use_specular_workflow_float" />
    </mix>
    <oren_nayar_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
      <input name="weight" type="float" nodename="diffuse_bsdf_weight" />
      <input name="color" type="color3" interfacename="diffuseColor" />
      <input name="roughness" type="float" value="0" />
      <input name="normal" type="vector3" nodename="surface_normal" />
    </oren_nayar_diffuse_bsdf>

    <!-- Transmission Layer -->
    <dielectric_bsdf name="transmission_bsdf" type="BSDF">
      <input name="weight" type="float" value="1" />
      <input name="tint" type="color3" value="1, 1, 1" />
      <input name="ior" type="float" interfacename="ior" />
      <input name="roughness" type="vector2" value="0.0, 0.0" />
      <input name="normal" type="vector3" nodename="surface_normal" />
      <input name="scatter_mode" type="string" value="T" />
    </dielectric_bsdf>
    <ifgreater name="transmission_mix_amount" type="float">
      <input name="value1" type="float" interfacename="opacityThreshold" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" interfacename="opacity" />
    </ifgreater>
    <mix name="transmission_mix" type="BSDF">
      <input name="fg" type="BSDF" nodename="diffuse_bsdf" />
      <input name="bg" type="BSDF" nodename="transmission_bsdf" />
      <input name="mix" type="float" nodename="transmission_mix_amount" />
    </mix>

    <!-- Specular Workflow -->
    <roughness_anisotropy name="specular_roughness" type="vector2">
      <input name="roughness" type="float" interfacename="roughness" />
      <input name="anisotropy" type="float" value="0" />
    </roughness_anisotropy>
    <generalized_schlick_bsdf name="specular_bsdf1" type="BSDF">
      <input name="weight" type="float" value="1" />
      <input name="color0" type="color3" interfacename="specularColor" />
      <input name="color90" type="color3" value="1, 1, 1" />
      <input name="roughness" type="vector2" nodename="specular_roughness" />
      <input name="normal" type="vector3" nodename="surface_normal" />
    </generalized_schlick_bsdf>
    <layer name="specular_workflow_bsdf" type="BSDF">
      <input name="top" type="BSDF" nodename="specular_bsdf1" />
      <input name="base" type="BSDF" nodename="transmission_mix" />
    </layer>

    <!-- Metalness Workflow -->
    <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="R" type="float">
      <input name="in1" type="float" nodename="one_minus_ior" />
      <input name="in2" type="float" nodename="one_plus_ior" />
    </divide>
    <multiply name="R_sq" type="float">
      <input name="in1" type="float" nodename="R" />
      <input name="in2" type="float" nodename="R" />
    </multiply>
    <mix name="specular_color_metallic" type="color3">
      <input name="fg" type="color3" interfacename="diffuseColor" />
      <input name="bg" type="color3" value="1, 1, 1" />
      <input name="mix" type="float" interfacename="metallic" />
    </mix>
    <multiply name="specular_color_metallic_R_sq" type="color3">
      <input name="in1" type="color3" nodename="specular_color_metallic" />
      <input name="in2" type="float" nodename="R_sq" />
    </multiply>
    <mix name="F0" type="color3">
      <input name="fg" type="color3" nodename="specular_color_metallic" />
      <input name="bg" type="color3" nodename="specular_color_metallic_R_sq" />
      <input name="mix" type="float" interfacename="metallic" />
    </mix>
    <generalized_schlick_bsdf name="specular_bsdf2" type="BSDF">
      <input name="weight" type="float" value="1" />
      <input name="color0" type="color3" nodename="F0" />
      <input name="color90" type="color3" nodename="specular_color_metallic" />
      <input name="roughness" type="vector2" nodename="specular_roughness" />
      <input name="normal" type="vector3" nodename="surface_normal" />
    </generalized_schlick_bsdf>
    <layer name="metalness_specular_bsdf" type="BSDF">
      <input name="top" type="BSDF" nodename="specular_bsdf2" />
      <input name="base" type="BSDF" nodename="transmission_mix" />
    </layer>
    <artistic_ior name="artistic_ior" type="multioutput">
      <input name="reflectivity" type="color3" interfacename="diffuseColor" />
      <input name="edge_color" type="color3" interfacename="diffuseColor" />
    </artistic_ior>
    <conductor_bsdf name="metalness_metal_bsdf" type="BSDF">
      <input name="weight" type="float" value="1" />
      <input name="ior" type="color3" nodename="artistic_ior" output="ior" />
      <input name="extinction" type="color3" nodename="artistic_ior" output="extinction" />
      <input name="roughness" type="vector2" nodename="specular_roughness" />
      <input name="normal" type="vector3" nodename="surface_normal" />
    </conductor_bsdf>
    <mix name="metalness_workflow_bsdf" type="BSDF">
      <input name="fg" type="BSDF" nodename="metalness_metal_bsdf" />
      <input name="bg" type="BSDF" nodename="metalness_specular_bsdf" />
      <input name="mix" type="float" interfacename="metallic" />
    </mix>

    <!-- Select Specular/Metalness workflow -->
    <mix name="workflow_selector_bsdf" type="BSDF">
      <input name="fg" type="BSDF" nodename="specular_workflow_bsdf" />
      <input name="bg" type="BSDF" nodename="metalness_workflow_bsdf" />
      <input name="mix" type="float" nodename="use_specular_workflow_float" />
    </mix>

    <!-- Clearcoat Layer -->
    <roughness_anisotropy name="coat_roughness" type="vector2">
      <input name="roughness" type="float" interfacename="clearcoatRoughness" />
      <input name="anisotropy" type="float" value="0" />
    </roughness_anisotropy>
    <convert name="coat_F0" type="color3">
      <input name="in" type="float" nodename="R_sq" />
    </convert>
    <generalized_schlick_bsdf name="coat_dielectric_bsdf" type="BSDF">
      <input name="weight" type="float" interfacename="clearcoat" />
      <input name="color0" type="color3" nodename="coat_F0" />
      <input name="color90" type="color3" value="1, 1, 1" />
      <input name="roughness" type="vector2" nodename="coat_roughness" />
      <input name="normal" type="vector3" nodename="surface_normal" />
    </generalized_schlick_bsdf>
    <layer name="coat_bsdf" type="BSDF">
      <input name="top" type="BSDF" nodename="coat_dielectric_bsdf" />
      <input name="base" type="BSDF" nodename="workflow_selector_bsdf" />
    </layer>

    <!-- Emission Layer -->
    <uniform_edf name="emission_edf" type="EDF">
      <input name="color" type="color3" interfacename="emissiveColor" />
    </uniform_edf>

    <!-- Surface Shader Constructor -->
    <ifgreatereq name="cutout_opacity" type="float">
      <input name="value1" type="float" interfacename="opacity" />
      <input name="value2" type="float" interfacename="opacityThreshold" />
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" value="0" />
    </ifgreatereq>
    <ifequal name="opacity_presence" type="float">
      <input name="value1" type="float" interfacename="opacity" />
      <input name="value2" type="float" value="0.0" />
      <input name="in1" type="float" value="0.0" />
      <input name="in2" type="float" nodename="cutout_opacity" />
    </ifequal>
    <switch name="opacity_switch" type="float">
      <input name="in1" type="float" nodename="cutout_opacity" />
      <input name="in2" type="float" nodename="opacity_presence" />
      <input name="which" type="integer" interfacename="opacityMode" />
    </switch>
    <surface name="surface_constructor" type="surfaceshader">
      <input name="bsdf" type="BSDF" nodename="coat_bsdf" />
      <input name="edf" type="EDF" nodename="emission_edf" />
      <input name="opacity" type="float" nodename="opacity_switch" />
    </surface>

    <!-- Output -->
    <output name="out" type="surfaceshader" nodename="surface_constructor" />
  </nodegraph>

  <!-- Node: UsdUVTexture -->
  <nodegraph name="IMP_UsdUVTexture_22" nodedef="ND_UsdUVTexture">
    <image name="image_reader" type="color4">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="color4" interfacename="fallback" />
      <input name="texcoord" type="vector2" interfacename="st" />
      <input name="uaddressmode" type="string" interfacename="wrapS" />
      <input name="vaddressmode" type="string" interfacename="wrapT" />
    </image>
    <multiply name="image_scale" type="color4">
      <input name="in1" type="color4" nodename="image_reader" />
      <input name="in2" type="color4" interfacename="scale" />
    </multiply>
    <add name="image_bias" type="color4">
      <input name="in1" type="color4" nodename="image_scale" />
      <input name="in2" type="color4" interfacename="bias" />
    </add>
    <separate4 name="image_bias_separate" type="multioutput">
      <input name="in" type="color4" nodename="image_bias" />
    </separate4>
    <convert name="image_bias_color3" type="color3">
      <input name="in" type="color4" nodename="image_bias" />
    </convert>
    <output name="r" type="float" nodename="image_bias_separate" output="outr" />
    <output name="g" type="float" nodename="image_bias_separate" output="outg" />
    <output name="b" type="float" nodename="image_bias_separate" output="outb" />
    <output name="a" type="float" nodename="image_bias_separate" output="outa" />
    <output name="rgb" type="color3" nodename="image_bias_color3" />
    <output name="rgba" type="color4" nodename="image_bias" />
  </nodegraph>

  <nodegraph name="IMP_UsdUVTexture_23" nodedef="ND_UsdUVTexture_23">
    <image name="image_reader" type="color4">
      <input name="file" type="filename" interfacename="file" />
      <input name="default" type="color4" interfacename="fallback" />
      <input name="texcoord" type="vector2" interfacename="st" />
      <input name="uaddressmode" type="string" interfacename="wrapS" />
      <input name="vaddressmode" type="string" interfacename="wrapT" />
    </image>
    <multiply name="image_scale" type="color4">
      <input name="in1" type="color4" nodename="image_reader" />
      <input name="in2" type="color4" interfacename="scale" />
    </multiply>
    <add name="image_bias" type="color4">
      <input name="in1" type="color4" nodename="image_scale" />
      <input name="in2" type="color4" interfacename="bias" />
    </add>
    <separate4 name="image_bias_separate" type="multioutput">
      <input name="in" type="color4" nodename="image_bias" />
    </separate4>
    <convert name="image_bias_color3" type="color3">
      <input name="in" type="color4" nodename="image_bias" />
    </convert>
    <output name="r" type="float" nodename="image_bias_separate" output="outr" />
    <output name="g" type="float" nodename="image_bias_separate" output="outg" />
    <output name="b" type="float" nodename="image_bias_separate" output="outb" />
    <output name="a" type="float" nodename="image_bias_separate" output="outa" />
    <output name="rgb" type="color3" nodename="image_bias_color3" />
  </nodegraph>

  <!-- Node: UsdPrimvarReader -->
  <nodegraph name="IMP_UsdPrimvarReader_integer" nodedef="ND_UsdPrimvarReader_integer">
    <geompropvalue name="primvar" type="integer">
      <input name="geomprop" type="string" interfacename="varname" />
      <input name="default" type="integer" interfacename="fallback" />
    </geompropvalue>
    <output name="out" type="integer" nodename="primvar" />
  </nodegraph>
  <nodegraph name="IMP_UsdPrimvarReader_boolean" nodedef="ND_UsdPrimvarReader_boolean">
    <geompropvalue name="primvar" type="boolean">
      <input name="geomprop" type="string" interfacename="varname" />
      <input name="default" type="boolean" interfacename="fallback" />
    </geompropvalue>
    <output name="out" type="boolean" nodename="primvar" />
  </nodegraph>
  <nodegraph name="IMP_UsdPrimvarReader_string" nodedef="ND_UsdPrimvarReader_string">
    <geompropvalueuniform name="primvar" type="string">
      <input name="geomprop" type="string" interfacename="varname" />
      <input name="default" type="string" interfacename="fallback" />
    </geompropvalueuniform>
    <output name="out" type="string" nodename="primvar" uniform="true" />
  </nodegraph>
  <nodegraph name="IMP_UsdPrimvarReader_filename" nodedef="ND_UsdPrimvarReader_filename">
    <geompropvalueuniform name="primvar" type="filename">
      <input name="geomprop" type="string" interfacename="varname" />
      <input name="default" type="filename" interfacename="fallback" />
    </geompropvalueuniform>
    <output name="out" type="filename" nodename="primvar" uniform="true" />
  </nodegraph>
  <nodegraph name="IMP_UsdPrimvarReader_float" nodedef="ND_UsdPrimvarReader_float">
    <geompropvalue name="primvar" type="float">
      <input name="geomprop" type="string" interfacename="varname" />
      <input name="default" type="float" interfacename="fallback" />
    </geompropvalue>
    <output name="out" type="float" nodename="primvar" />
  </nodegraph>
  <nodegraph name="IMP_UsdPrimvarReader_vector2" nodedef="ND_UsdPrimvarReader_vector2">
    <geompropvalue name="primvar" type="vector2">
      <input name="geomprop" type="string" interfacename="varname" />
      <input name="default" type="vector2" interfacename="fallback" />
    </geompropvalue>
    <output name="out" type="vector2" nodename="primvar" />
  </nodegraph>
  <nodegraph name="IMP_UsdPrimvarReader_vector3" nodedef="ND_UsdPrimvarReader_vector3">
    <geompropvalue name="primvar" type="vector3">
      <input name="geomprop" type="string" interfacename="varname" />
      <input name="default" type="vector3" interfacename="fallback" />
    </geompropvalue>
    <output name="out" type="vector3" nodename="primvar" />
  </nodegraph>
  <nodegraph name="IMP_UsdPrimvarReader_vector4" nodedef="ND_UsdPrimvarReader_vector4">
    <geompropvalue name="primvar" type="vector4">
      <input name="geomprop" type="string" interfacename="varname" />
      <input name="default" type="vector4" interfacename="fallback" />
    </geompropvalue>
    <output name="out" type="vector4" nodename="primvar" />
  </nodegraph>

  <!-- Node: UsdTransform2d -->
  <nodegraph name="IMP_UsdTransform2d" nodedef="ND_UsdTransform2d">
    <place2d name="placement" type="vector2">
      <input name="texcoord" type="vector2" interfacename="in" />
      <input name="scale" type="vector2" interfacename="scale" />
      <input name="rotate" type="float" interfacename="rotation" />
      <input name="offset" type="vector2" interfacename="translation" />
    </place2d>
    <output name="out" type="vector2" nodename="placement" />
  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <nodedef name="ND_gltf_pbr_surfaceshader" node="gltf_pbr" nodegroup="pbr" doc="glTF PBR" version="2.0.1" isdefaultversion="true">
    <input name="base_color" type="color3" value="1, 1, 1" uimin="0, 0, 0" uimax="1, 1, 1" uiname="Base Color" uifolder="Base" />
    <input name="metallic" type="float" value="1" uimin="0" uimax="1" uiname="Metallic" uifolder="Base" />
    <input name="roughness" type="float" value="1" uimin="0" uimax="1" uiname="Roughness" uifolder="Base" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Base" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" uiname="Tangent" uifolder="Base" />
    <input name="occlusion" type="float" value="1" uimin="0" uimax="1" uiname="Occlusion" uifolder="Base" />
    <input name="transmission" type="float" value="0" uimin="0" uimax="1" uiname="Transmission" uifolder="Base" />
    <input name="specular" type="float" value="1" uimin="0" uimax="1" uiname="Specular" uifolder="Base" />
    <input name="specular_color" type="color3" value="1, 1, 1" uimin="0, 0, 0" uisoftmax="1, 1, 1" uiname="Specular Color" uifolder="Base" />
    <input name="ior" uniform="true" type="float" value="1.5" uimin="1" uisoftmax="3" uiname="Index of Refraction" uifolder="Base" />
    <input name="alpha" type="float" value="1" uimin="0" uimax="1" uiname="Alpha" uifolder="Alpha" />
    <input name="alpha_mode" uniform="true" type="integer" enum="OPAQUE, MASK, BLEND" enumvalues="0, 1, 2" value="0" uiname="Alpha Mode" uifolder="Alpha" />
    <input name="alpha_cutoff" uniform="true" type="float" value="0.5" uimin="0" uimax="1" uiname="Alpha Cutoff" uifolder="Alpha" />
    <input name="iridescence" type="float" value="0" uimin="0" uimax="1" uiname="Iridescence" uifolder="Iridescence" />
    <input name="iridescence_ior" uniform="true" type="float" value="1.3" uimin="1" uisoftmax="3" uiname="Iridescence Index of Refraction" uifolder="Iridescence" />
    <input name="iridescence_thickness" type="float" value="100" uimin="0" uisoftmin="100" uisoftmax="400" uiname="Iridescence Thickness" uifolder="Iridescence" />
    <input name="sheen_color" type="color3" value="0, 0, 0" uimin="0, 0, 0" uimax="1, 1, 1" uiname="Sheen Color" uifolder="Sheen" />
    <input name="sheen_roughness" type="float" value="0" uimin="0" uimax="1" uiname="Sheen Roughness" uifolder="Sheen" />
    <input name="clearcoat" type="float" value="0" uimin="0" uimax="1" uiname="Clearcoat" uifolder="Clearcoat" />
    <input name="clearcoat_roughness" type="float" value="0" uimin="0" uimax="1" uiname="Clearcoat Roughness" uifolder="Clearcoat" />
    <input name="clearcoat_normal" type="vector3" defaultgeomprop="Nworld" uiname="Clearcoat Normal" uifolder="Clearcoat" />
    <input name="emissive" type="color3" value="0, 0, 0" uimin="0, 0, 0" uimax="1, 1, 1" uiname="Emissive" uifolder="Emission" />
    <input name="emissive_strength" uniform="true" type="float" value="1" uimin="0" uiname="Emissive Strength" uifolder="Emission" />
    <input name="thickness" uniform="false" type="float" value="0" uimin="0" uiname="Thickness" uifolder="Volume" />
    <input name="attenuation_distance" uniform="true" type="float" uimin="0" uiname="Attenuation Distance" uifolder="Volume" />
    <input name="attenuation_color" uniform="true" type="color3" value="1, 1, 1" uimin="0, 0, 0" uimax="1, 1, 1" uiname="Attenuation Color" uifolder="Volume" />
    <input name="anisotropy_strength" type="float" value="0" uimin="0" uimax="1" uiname="Anisotropy Strength" uifolder="Anisotropy" />
    <input name="anisotropy_rotation" type="float" value="0" uimin="0" uimax="6.283185" uiname="Anisotropy Rotation" uifolder="Anisotropy" />
    <output name="out" type="surfaceshader" />
  </nodedef>

  <nodegraph name="IMPL_gltf_pbr_surfaceshader" nodedef="ND_gltf_pbr_surfaceshader">

    <!-- 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 -->

    <oren_nayar_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
      <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" value="1" />
      <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>

    <generalized_schlick_bsdf name="reflection_bsdf" type="BSDF">
      <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>

    <mix name="transmission_mix" type="BSDF">
      <input name="bg" type="BSDF" nodename="diffuse_bsdf" />
      <input name="fg" type="BSDF" nodename="transmission_bsdf" />
      <input name="mix" type="float" interfacename="transmission" />
    </mix>

    <layer name="dielectric_bsdf" type="BSDF">
      <input name="top" type="BSDF" nodename="reflection_bsdf" />
      <input name="base" type="BSDF" nodename="transmission_mix" />
    </layer>

    <!-- Thin-film + Dielectric
         Note: Due to limitations in codegen, the base layer BSDF is duplicated (#1035). -->

    <generalized_schlick_bsdf name="tf_reflection_bsdf" type="BSDF">
      <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>


    <layer name="tf_dielectric_bsdf" type="BSDF">
      <input name="top" type="BSDF" nodename="tf_reflection_bsdf" />
      <input name="base" type="BSDF" nodename="transmission_mix" />
    </layer>

    <mix name="mix_iridescent_dielectric_bsdf" type="BSDF">
      <input name="bg" type="BSDF" nodename="dielectric_bsdf" />
      <input name="fg" type="BSDF" nodename="tf_dielectric_bsdf" />
      <input name="mix" type="float" interfacename="iridescence" />
    </mix>

    <!-- Metal -->

    <generalized_schlick_bsdf name="metal_bsdf" type="BSDF">
      <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>

    <!-- Thin-film + Metal
         Note: Due to limitations in codegen, the base layer BSDF is duplicated (#1035). -->

    <generalized_schlick_bsdf name="tf_metal_bsdf" type="BSDF">
      <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>

    <mix name="mix_iridescent_metal_bsdf" type="BSDF">
      <input name="bg" type="BSDF" nodename="metal_bsdf" />
      <input name="fg" type="BSDF" nodename="tf_metal_bsdf" />
      <input name="mix" type="float" interfacename="iridescence" />
    </mix>

    <!-- Dielectric/metal mix -->

    <mix name="base_mix" type="BSDF">
      <input name="bg" type="BSDF" nodename="mix_iridescent_dielectric_bsdf" />
      <input name="fg" type="BSDF" nodename="mix_iridescent_metal_bsdf" />
      <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>

  <!--
    Node: <gltf_colorimage> Supplemental Node
    Multiply a color4 image modulated by uniform color and geometry color. Default uniform and geometry colors are 1,1,1,1 which results in no change to the image.
  -->
  <nodedef name="ND_gltf_colorimage" node="gltf_colorimage" version="1.0" isdefaultversion="true" nodegroup="texture2d">
    <input name="file" type="filename" uniform="true" value="" uifolder="Image" />
    <input name="default" type="color4" value="0, 0, 0, 0" uifolder="Image" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uifolder="Image" />
    <input name="pivot" type="vector2" value="0, 1" uifolder="Image" />
    <input name="scale" type="vector2" value="1, 1" uifolder="Image" />
    <input name="rotate" type="float" value="0" unit="degree" unittype="angle" uimin="0" uimax="360" uifolder="Image" />
    <input name="offset" type="vector2" value="0, 0" uifolder="Image" />
    <input name="operationorder" type="integer" value="1" uifolder="Image" />
    <input name="uaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" uifolder="Image" />
    <input name="vaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" uifolder="Image" />
    <input name="filtertype" type="string" uniform="true" value="linear" enum="closest,linear,cubic" uifolder="Image" />
    <input name="color" type="color4" value="1, 1, 1, 1" uifolder="Color" />
    <input name="geomcolor" type="color4" value="1, 1, 1, 1" uifolder="Color" uiname="Geometry Color" />
    <output name="outcolor" type="color3" value="0, 0, 0" />
    <output name="outa" type="float" value="0" />
  </nodedef>

  <nodegraph name="NG_gltf_colorimage" nodedef="ND_gltf_colorimage">
    <gltf_image name="image" type="color4">
      <input name="file" type="filename" uniform="true" interfacename="file" />
      <input name="default" type="color4" interfacename="default" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
      <input name="pivot" type="vector2" interfacename="pivot" />
      <input name="scale" type="vector2" interfacename="scale" />
      <input name="rotate" type="float" interfacename="rotate" />
      <input name="offset" type="vector2" interfacename="offset" />
      <input name="operationorder" type="integer" value="0" />
      <input name="uaddressmode" type="string" uniform="true" value="periodic" />
      <input name="vaddressmode" type="string" uniform="true" value="periodic" />
      <input name="filtertype" type="string" uniform="true" interfacename="filtertype" />
    </gltf_image>
    <multiply name="modulate_color" type="color4">
      <input name="in1" type="color4" interfacename="color" />
      <input name="in2" type="color4" nodename="image" />
    </multiply>
    <multiply name="modulate_geomcolor" type="color4">
      <input name="in1" type="color4" nodename="modulate_color" />
      <input name="in2" type="color4" interfacename="geomcolor" />
    </multiply>
    <separate4 name="separate_color" type="multioutput">
      <input name="in" type="color4" nodename="modulate_geomcolor" />
    </separate4>
    <combine3 name="combine_color" type="color3">
      <input name="in1" type="float" nodename="separate_color" output="outr" />
      <input name="in2" type="float" nodename="separate_color" output="outg" />
      <input name="in3" type="float" nodename="separate_color" output="outb" />
    </combine3>
    <dot name="separate_alpha" type="float">
      <input name="in" type="float" nodename="separate_color" output="outa" />
    </dot>
    <output name="outcolor" type="color3" nodename="combine_color" />
    <output name="outa" type="float" nodename="separate_alpha" />
  </nodegraph>

  <!---
    Node: <gltf_image>
    color3 image lookup which matches glTF
  -->
  <nodedef name="ND_gltf_image_color3_color3_1_0" node="gltf_image" version="1.0" isdefaultversion="true" nodegroup="texture2d">
    <input name="file" type="filename" uniform="true" value="" />
    <input name="factor" type="color3" value="1,1,1" />
    <input name="default" type="color3" value="0, 0, 0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="pivot" type="vector2" value="0, 1" />
    <input name="scale" type="vector2" value="1, 1" />
    <input name="rotate" type="float" value="0" unit="degree" unittype="angle" uimin="0" uimax="360" />
    <input name="offset" type="vector2" value="0, 0" />
    <input name="operationorder" type="integer" value="0" />
    <input name="uaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="vaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="filtertype" type="string" uniform="true" value="linear" enum="closest,linear,cubic" />
    <output name="out" type="color3" value="0, 0, 0" />
  </nodedef>
  <nodegraph name="NG_NG_gltf_image_color3_color3_1_0" nodedef="ND_gltf_image_color3_color3_1_0">
    <image name="image" type="color3">
      <input name="file" type="filename" uniform="true" interfacename="file" />
      <input name="default" type="color3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="place2d" />
      <input name="uaddressmode" type="string" uniform="true" interfacename="uaddressmode" />
      <input name="vaddressmode" type="string" uniform="true" interfacename="vaddressmode" />
      <input name="filtertype" type="string" uniform="true" interfacename="filtertype" />
    </image>
    <divide name="invert_scale" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" interfacename="scale" />
    </divide>
    <multiply name="negate_rotate" type="float">
      <input name="in1" type="float" interfacename="rotate" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <multiply name="negate_offset" type="vector2">
      <input name="in1" type="vector2" interfacename="offset" />
      <input name="in2" type="vector2" value="-1.0, 1.0" />
    </multiply>
    <place2d name="place2d" type="vector2">
      <input name="texcoord" type="vector2" interfacename="texcoord" />
      <input name="pivot" type="vector2" interfacename="pivot" />
      <input name="scale" type="vector2" nodename="invert_scale" />
      <input name="rotate" type="float" nodename="negate_rotate" />
      <input name="offset" type="vector2" nodename="negate_offset" />
      <input name="operationorder" type="integer" interfacename="operationorder" />
    </place2d>
    <multiply name="scale_image" type="color3">
      <input name="in1" type="color3" interfacename="factor" />
      <input name="in2" type="color3" nodename="image" />
    </multiply>
    <output name="out" type="color3" nodename="scale_image" />
  </nodegraph>

  <!---
    Node: <gltf_image>
    color4 image lookup which matches glTF
  -->
  <nodedef name="ND_gltf_image_color4_color4_1_0" node="gltf_image" version="1.0" isdefaultversion="true" nodegroup="texture2d">
    <input name="file" type="filename" uniform="true" value="" />
    <input name="factor" type="color4" value="1,1,1,1" />
    <input name="default" type="color4" value="0, 0, 0, 0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="pivot" type="vector2" value="0, 1" />
    <input name="scale" type="vector2" value="1, 1" />
    <input name="rotate" type="float" value="0" unit="degree" unittype="angle" uimin="0" uimax="360" />
    <input name="offset" type="vector2" value="0, 0" />
    <input name="operationorder" type="integer" value="1" />
    <input name="uaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="vaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="filtertype" type="string" uniform="true" value="linear" enum="closest,linear,cubic" />
    <output name="out" type="color4" value="0, 0, 0, 0" />
  </nodedef>
  <nodegraph name="NG_gltf_image_color4_color4_1_0" nodedef="ND_gltf_image_color4_color4_1_0">
    <image name="image" type="color4">
      <input name="file" type="filename" uniform="true" interfacename="file" />
      <input name="default" type="color4" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="place2d" />
      <input name="uaddressmode" type="string" uniform="true" interfacename="uaddressmode" />
      <input name="vaddressmode" type="string" uniform="true" interfacename="vaddressmode" />
      <input name="filtertype" type="string" uniform="true" interfacename="filtertype" />
    </image>
    <divide name="invert_scale" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" interfacename="scale" />
    </divide>
    <multiply name="negate_rotate" type="float">
      <input name="in1" type="float" interfacename="rotate" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <multiply name="negate_offset" type="vector2">
      <input name="in1" type="vector2" interfacename="offset" />
      <input name="in2" type="vector2" value="-1.0, 1.0" />
    </multiply>
    <place2d name="place2d" type="vector2">
      <input name="texcoord" type="vector2" interfacename="texcoord" />
      <input name="pivot" type="vector2" interfacename="pivot" />
      <input name="scale" type="vector2" nodename="invert_scale" />
      <input name="rotate" type="float" nodename="negate_rotate" />
      <input name="offset" type="vector2" nodename="negate_offset" />
      <input name="operationorder" type="integer" interfacename="operationorder" />
    </place2d>
    <multiply name="scale_image" type="color4">
      <input name="in1" type="color4" interfacename="factor" />
      <input name="in2" type="color4" nodename="image" />
    </multiply>
    <output name="out" type="color4" nodename="scale_image" />
  </nodegraph>

  <!---
    Node: <gltf_image>
    float image lookup which matches glTF
  -->
  <nodedef name="ND_gltf_image_float_float_1_0" node="gltf_image" version="1.0" isdefaultversion="true" nodegroup="texture2d">
    <input name="file" type="filename" uniform="true" value="" />
    <input name="factor" type="float" value="1" />
    <input name="default" type="float" value="0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="pivot" type="vector2" value="0, 1" />
    <input name="scale" type="vector2" value="1, 1" />
    <input name="rotate" type="float" value="0" unit="degree" unittype="angle" uimin="0" uimax="360" />
    <input name="offset" type="vector2" value="0, 0" />
    <input name="operationorder" type="integer" value="0" />
    <input name="uaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="vaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="filtertype" type="string" uniform="true" value="linear" enum="closest,linear,cubic" />
    <output name="out" type="float" value="0" />
  </nodedef>
  <nodegraph name="NG_gltf_image_float_float_1_0" nodedef="ND_gltf_image_float_float_1_0">
    <image name="image" type="float">
      <input name="file" type="filename" uniform="true" interfacename="file" />
      <input name="default" type="float" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="place2d" />
      <input name="uaddressmode" type="string" uniform="true" interfacename="uaddressmode" />
      <input name="vaddressmode" type="string" uniform="true" interfacename="vaddressmode" />
      <input name="filtertype" type="string" uniform="true" interfacename="filtertype" />
    </image>
    <divide name="invert_scale" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" interfacename="scale" />
    </divide>
    <multiply name="negate_rotate" type="float">
      <input name="in1" type="float" interfacename="rotate" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <multiply name="negate_offset" type="vector2">
      <input name="in1" type="vector2" interfacename="offset" />
      <input name="in2" type="vector2" value="-1.0, 1.0" />
    </multiply>
    <place2d name="place2d" type="vector2">
      <input name="texcoord" type="vector2" interfacename="texcoord" />
      <input name="pivot" type="vector2" interfacename="pivot" />
      <input name="scale" type="vector2" nodename="invert_scale" />
      <input name="rotate" type="float" nodename="negate_rotate" />
      <input name="offset" type="vector2" nodename="negate_offset" />
      <input name="operationorder" type="integer" interfacename="operationorder" />
    </place2d>
    <multiply name="scale_image" type="float">
      <input name="in1" type="float" interfacename="factor" />
      <input name="in2" type="float" nodename="image" />
    </multiply>
    <output name="out" type="float" nodename="scale_image" />
  </nodegraph>

  <!---
    Node: <gltf_image>
    vector3 image lookup which matches glTF
  -->
  <nodedef name="ND_gltf_image_vector3_vector3_1_0" node="gltf_image" version="1.0" isdefaultversion="true" nodegroup="texture2d">
    <input name="file" type="filename" uniform="true" value="" />
    <input name="default" type="vector3" value="0, 0, 0" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="pivot" type="vector2" value="0, 1" />
    <input name="scale" type="vector2" value="1, 1" />
    <input name="rotate" type="float" value="0" unit="degree" unittype="angle" uimin="0" uimax="360" />
    <input name="offset" type="vector2" value="0, 0" />
    <input name="operationorder" type="integer" value="0" />
    <input name="uaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="vaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="filtertype" type="string" uniform="true" value="linear" enum="closest,linear,cubic" />
    <output name="out" type="vector3" value="0, 0, 0" />
  </nodedef>
  <nodegraph name="NG_gltf_image_vector3_vector3_1_0" nodedef="ND_gltf_image_vector3_vector3_1_0">
    <image name="image" type="vector3">
      <input name="file" type="filename" uniform="true" interfacename="file" />
      <input name="default" type="vector3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="place2d" />
      <input name="uaddressmode" type="string" uniform="true" interfacename="uaddressmode" />
      <input name="vaddressmode" type="string" uniform="true" interfacename="vaddressmode" />
      <input name="filtertype" type="string" uniform="true" interfacename="filtertype" />
    </image>
    <divide name="invert_scale" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" interfacename="scale" />
    </divide>
    <multiply name="negate_rotate" type="float">
      <input name="in1" type="float" interfacename="rotate" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <multiply name="negate_offset" type="vector2">
      <input name="in1" type="vector2" interfacename="offset" />
      <input name="in2" type="vector2" value="-1.0, 1.0" />
    </multiply>
    <place2d name="place2d" type="vector2">
      <input name="texcoord" type="vector2" interfacename="texcoord" />
      <input name="pivot" type="vector2" interfacename="pivot" />
      <input name="scale" type="vector2" nodename="invert_scale" />
      <input name="rotate" type="float" nodename="negate_rotate" />
      <input name="offset" type="vector2" nodename="negate_offset" />
      <input name="operationorder" type="integer" interfacename="operationorder" />
    </place2d>
    <output name="out" type="vector3" nodename="image" />
  </nodegraph>

  <!---
    Node: <gltf_normalmap>
    normalmap image lookup which matches glTF
  -->
  <nodedef name="ND_gltf_normalmap_vector3_1_0" node="gltf_normalmap" version="1.0" isdefaultversion="true" nodegroup="texture2d">
    <input name="file" type="filename" uniform="true" value="" />
    <input name="default" type="vector3" value="0.5, 0.5, 1" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" />
    <input name="pivot" type="vector2" value="0, 1" />
    <input name="scale" type="vector2" value="1, 1" />
    <input name="rotate" type="float" value="0" unit="degree" unittype="angle" uimin="0" uimax="360" />
    <input name="offset" type="vector2" value="0, 0" />
    <input name="operationorder" type="integer" value="0" />
    <input name="uaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="vaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" />
    <input name="filtertype" type="string" uniform="true" value="linear" enum="closest,linear,cubic" />
    <output name="out" type="vector3" value="0, 0, 0" />
  </nodedef>
  <nodegraph name="NG_gltf_normalmap_vector3_1_0" nodedef="ND_gltf_normalmap_vector3_1_0">
    <image name="image" type="vector3">
      <input name="file" type="filename" uniform="true" interfacename="file" />
      <input name="default" type="vector3" interfacename="default" />
      <input name="texcoord" type="vector2" nodename="place2d" />
      <input name="uaddressmode" type="string" uniform="true" interfacename="uaddressmode" />
      <input name="vaddressmode" type="string" uniform="true" interfacename="vaddressmode" />
      <input name="filtertype" type="string" uniform="true" interfacename="filtertype" />
    </image>
    <normalmap name="normalmap" type="vector3">
      <input name="in" type="vector3" nodename="image" />
    </normalmap>
    <divide name="invert_scale" type="vector2">
      <input name="in1" type="vector2" value="1.0, 1.0" />
      <input name="in2" type="vector2" interfacename="scale" />
    </divide>
    <multiply name="negate_rotate" type="float">
      <input name="in1" type="float" interfacename="rotate" />
      <input name="in2" type="float" value="-1.0" />
    </multiply>
    <multiply name="negate_offset" type="vector2">
      <input name="in1" type="vector2" interfacename="offset" />
      <input name="in2" type="vector2" value="-1.0, 1.0" />
    </multiply>
    <place2d name="place2d" type="vector2" nodedef="ND_place2d_vector2">
      <input name="texcoord" type="vector2" interfacename="texcoord" />
      <input name="pivot" type="vector2" interfacename="pivot" />
      <input name="scale" type="vector2" nodename="invert_scale" />
      <input name="rotate" type="float" nodename="negate_rotate" />
      <input name="offset" type="vector2" nodename="negate_offset" />
      <input name="operationorder" type="integer" interfacename="operationorder" />
    </place2d>
    <output name="out" type="vector3" nodename="normalmap" />
  </nodegraph>

  <!--
    Node: <gltf_iridescence>
    normalmap image lookup which matches glTF
  -->
  <nodedef name="ND_gltf_iridescence_thickness_float_1_0" node="gltf_iridescence_thickness" version="1.0" isdefaultversion="true" nodegroup="texture2d">
    <input name="file" type="filename" uniform="true" value="" uifolder="Image" />
    <input name="default" type="vector3" value="0, 0, 0" uifolder="Image" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uifolder="Image" />
    <input name="pivot" type="vector2" value="0, 0" uifolder="Image" />
    <input name="scale" type="vector2" value="1, 1" uifolder="Image" />
    <input name="rotate" type="float" value="0" uifolder="Image" />
    <input name="offset" type="vector2" value="0, 0" uifolder="Image" />
    <input name="uaddressmode" type="string" uniform="true" value="periodic" uifolder="Image" enum="constant,clamp,periodic,mirror" />
    <input name="vaddressmode" type="string" uniform="true" value="periodic" uifolder="Image" enum="constant,clamp,periodic,mirror" />
    <input name="filtertype" type="string" uniform="true" value="linear" enum="closest,linear,cubic" uifolder="Image" />
    <input name="thicknessMin" type="float" value="100" uifolder="Thickness" />
    <input name="thicknessMax" type="float" value="400" uifolder="Thickness" />
    <output name="out" type="float" value="0" />
  </nodedef>
  <nodegraph name="NG_gltf_iridescence_thickness_float_1_0" nodedef="ND_gltf_iridescence_thickness_float_1_0">
    <mix name="mixThickness" type="float" nodedef="ND_mix_float">
      <input name="fg" type="float" interfacename="thicknessMin" />
      <input name="bg" type="float" interfacename="thicknessMax" />
      <input name="mix" type="float" nodename="extract" />
    </mix>
    <gltf_image name="thickness_image" type="vector3">
      <input name="file" type="filename" uniform="true" interfacename="file" />
      <input name="default" type="vector3" interfacename="default" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
      <input name="pivot" type="vector2" interfacename="pivot" />
      <input name="scale" type="vector2" interfacename="scale" />
      <input name="rotate" type="float" interfacename="rotate" />
      <input name="offset" type="vector2" interfacename="offset" />
      <input name="uaddressmode" type="string" uniform="true" interfacename="uaddressmode" />
      <input name="vaddressmode" type="string" uniform="true" interfacename="vaddressmode" />
      <input name="filtertype" type="string" uniform="true" interfacename="filtertype" />
    </gltf_image>
    <extract name="extract" type="float">
      <input name="in" type="vector3" nodename="thickness_image" />
      <input name="index" type="integer" uniform="true" value="1" />
    </extract>
    <output name="out" type="float" nodename="mixThickness" />
  </nodegraph>

  <!--
    Node: <gltf_anisotropy_image>
  -->
  <nodedef name="ND_gltf_anisotropy_image" node="gltf_anisotropy_image" version="1.0" isdefaultversion="true" nodegroup="texture2d">
    <input name="file" type="filename" uniform="true" value="" uifolder="Image" />
    <input name="default" type="vector3" value="1.0, 0.5, 1" uifolder="Image" />
    <input name="texcoord" type="vector2" defaultgeomprop="UV0" uifolder="Image" />
    <input name="pivot" type="vector2" value="0, 1" uifolder="Image" />
    <input name="scale" type="vector2" value="1, 1" uifolder="Image" />
    <input name="rotate" type="float" value="0" unit="degree" unittype="angle" uimin="0" uimax="360" uifolder="Image" />
    <input name="offset" type="vector2" value="0, 0" uifolder="Image" />
    <input name="operationorder" type="integer" value="0" uifolder="Image" />
    <input name="uaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" uifolder="Image" />
    <input name="vaddressmode" type="string" uniform="true" value="periodic" enum="constant,clamp,periodic,mirror" uifolder="Image" />
    <input name="filtertype" type="string" uniform="true" value="linear" enum="closest,linear,cubic" uifolder="Image" />
    <input name="anisotropy_strength" type="float" value="1" uimin="0" uimax="1" uifolder="Anisotropy" uiname="Anisotropy Strength" />
    <input name="anisotropy_rotation" type="float" value="0" uimin="0" uimax="6.283185" uifolder="Anisotropy" uiname="Anisotropy Rotation" />
    <output name="anisotropy_strength_out" type="float" value="0" />
    <output name="anisotropy_rotation_out" type="float" value="0" />
  </nodedef>

  <nodegraph name="NG_gltf_anisotropy_image_1_0" nodedef="ND_gltf_anisotropy_image">
    <gltf_image name="gltf_anisotropy_image_src" type="vector3" nodedef="ND_gltf_image_vector3_vector3_1_0">
      <input name="file" type="filename" uniform="true" interfacename="file" />
      <input name="default" type="vector3" interfacename="default" />
      <input name="texcoord" type="vector2" interfacename="texcoord" />
      <input name="pivot" type="vector2" interfacename="pivot" />
      <input name="scale" type="vector2" interfacename="scale" />
      <input name="rotate" type="float" interfacename="rotate" />
      <input name="offset" type="vector2" interfacename="offset" />
      <input name="operationorder" type="integer" value="0" />
      <input name="uaddressmode" type="string" uniform="true" value="periodic" />
      <input name="vaddressmode" type="string" uniform="true" value="periodic" />
      <input name="filtertype" type="string" uniform="true" interfacename="filtertype" />
    </gltf_image>
    <separate3 name="separate3" type="multioutput">
      <input name="in" type="vector3" nodename="gltf_anisotropy_image_src" />
    </separate3>
    <multiply name="strength_multiply" type="float">
      <input name="in1" type="float" interfacename="anisotropy_strength" />
      <input name="in2" type="float" nodename="separate3" output="outz" />
    </multiply>
    <atan2 name="direction_to_rotation" type="float">
      <input name="iny" type="float" nodename="subtract_y" />
      <input name="inx" type="float" nodename="subtract_x" />
    </atan2>
    <add name="rotation_add" type="float">
      <input name="in1" type="float" interfacename="anisotropy_rotation" />
      <input name="in2" type="float" nodename="direction_to_rotation" />
    </add>
    <multiply name="multiply_x" type="float">
      <input name="in1" type="float" nodename="separate3" output="outx" />
      <input name="in2" type="float" value="2.0" />
    </multiply>
    <subtract name="subtract_x" type="float">
      <input name="in1" type="float" nodename="multiply_x" />
      <input name="in2" type="float" value="1.0" />
    </subtract>
    <subtract name="subtract_y" type="float">
      <input name="in1" type="float" nodename="multiply_y" />
      <input name="in2" type="float" value="1.0" />
    </subtract>
    <multiply name="multiply_y" type="float">
      <input name="in1" type="float" nodename="separate3" output="outy" />
      <input name="in2" type="float" value="2.0" />
    </multiply>
    <output name="anisotropy_strength_out" type="float" nodename="strength_multiply" />
    <output name="anisotropy_rotation_out" type="float" nodename="rotation_add" />
  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Autodesk Standard Surface node definition.
  -->
  <nodedef name="ND_standard_surface_surfaceshader" node="standard_surface" nodegroup="pbr" version="1.0.1" isdefaultversion="true" inherit="ND_standard_surface_surfaceshader_100"
           doc="Autodesk standard surface shader">
    <input name="base" type="float" value="1.0" uimin="0.0" uimax="1.0" uiname="Base" uifolder="Base"
           doc="Multiplier on the intensity of the diffuse reflection." />
    <input name="base_color" type="color3" value="0.8, 0.8, 0.8" uimin="0,0,0" uimax="1,1,1" uiname="Base Color" uifolder="Base"
           doc="Color of the diffuse reflection." />
  </nodedef>

  <nodedef name="ND_standard_surface_surfaceshader_100" node="standard_surface" nodegroup="pbr" version="1.0.0"
           doc="Autodesk standard surface shader">
    <input name="base" type="float" value="0.8" uimin="0.0" uimax="1.0" uiname="Base" uifolder="Base"
           doc="Multiplier on the intensity of the diffuse reflection." />
    <input name="base_color" type="color3" value="1.0, 1.0, 1.0" uimin="0,0,0" uimax="1,1,1" uiname="Base Color" uifolder="Base"
           doc="Color of the diffuse reflection." />
    <input name="diffuse_roughness" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Diffuse Roughness" uifolder="Base" uiadvanced="true"
           doc="Roughness of the diffuse reflection. Higher values cause the surface to appear flatter and darker." />
    <input name="metalness" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Metalness" uifolder="Base"
           doc="Specifies how metallic the material appears. At its maximum, the surface behaves like a metal, using fully specular reflection and complex fresnel." />
    <input name="specular" type="float" value="1" uimin="0.0" uimax="1.0" uiname="Specular" uifolder="Specular"
           doc="Multiplier on the intensity of the specular reflection." />
    <input name="specular_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Specular Color" uifolder="Specular"
           doc="Color tint on the specular reflection." />
    <input name="specular_roughness" type="float" value="0.2" uimin="0.0" uimax="1.0" uiname="Specular Roughness" uifolder="Specular"
           doc="The roughness of the specular reflection. Lower numbers produce sharper reflections, higher numbers produce blurrier reflections." />
    <input name="specular_IOR" type="float" value="1.5" uimin="0.0" uisoftmin="1.0" uisoftmax="3.0" uiname="Index of Refraction" uifolder="Specular"
           doc="Index of refraction for specular reflection." />
    <input name="specular_anisotropy" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Specular Anisotropy" uifolder="Specular" uiadvanced="true"
           doc="The directional bias of reflected and transmitted light resulting in materials appearing rougher or glossier in certain directions." />
    <input name="specular_rotation" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Specular Rotation" uifolder="Specular" uiadvanced="true"
           doc="Rotation of the axis of specular anisotropy around the surface normal." />
    <input name="transmission" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Transmission" uifolder="Transmission" uiadvanced="true"
           doc="Transmission of light through the surface for materials such as glass or water. The greater the value the more transparent the material." />
    <input name="transmission_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Transmission Color" uifolder="Transmission" uiadvanced="true"
           doc="Color tint on the transmitted light." />
    <input name="transmission_depth" type="float" value="0" uimin="0.0" uisoftmax="100.0" uiname="Transmission Depth" uifolder="Transmission" uiadvanced="true"
           doc="Specifies the distance light travels inside the material before its becomes exactly the transmission color according to Beer's law." />
    <input name="transmission_scatter" type="color3" value="0, 0, 0" uimin="0,0,0" uimax="1,1,1" uiname="Transmission Scatter" uifolder="Transmission" uiadvanced="true"
           doc="Scattering coefficient of the interior medium. Suitable for a large body of liquid or one that is fairly thick, such as an ocean, honey, ice, or frosted glass." />
    <input name="transmission_scatter_anisotropy" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Transmission Anisotropy" uifolder="Transmission" uiadvanced="true"
           doc="The amount of directional bias, or anisotropy, of the scattering." />
    <input name="transmission_dispersion" type="float" value="0" uimin="0.0" uisoftmax="100.0" uiname="Transmission Dispersion" uifolder="Transmission" uiadvanced="true"
           doc="Dispersion amount, describing how much the index of refraction varies across wavelengths." />
    <input name="transmission_extra_roughness" type="float" value="0" uimin="-1.0" uisoftmin="0.0" uimax="1.0" uiname="Transmission Roughness" uifolder="Transmission" uiadvanced="true"
           doc="Additional roughness on top of specular roughness. Positive values blur refractions more than reflections, and negative values blur refractions less." />
    <input name="subsurface" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Subsurface" uifolder="Subsurface" uiadvanced="true"
           doc="The blend between diffuse reflection and subsurface scattering. A value of 1.0 indicates full subsurface scattering and a value 0 for diffuse reflection only." />
    <input name="subsurface_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Subsurface Color" uifolder="Subsurface" uiadvanced="true"
           doc="The color of the subsurface scattering effect." />
    <input name="subsurface_radius" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Subsurface Radius" uifolder="Subsurface" uiadvanced="true"
           doc="The mean free path. The distance which light can travel before being scattered inside the surface." />
    <input name="subsurface_scale" type="float" value="1" uimin="0.0" uisoftmax="10.0" uiname="Subsurface Scale" uifolder="Subsurface" uiadvanced="true"
           doc="Scalar weight for the subsurface radius value." />
    <input name="subsurface_anisotropy" type="float" value="0" uimin="-1.0" uimax="1.0" uiname="Subsurface Anisotropy" uifolder="Subsurface" uiadvanced="true"
           doc="The direction of subsurface scattering. 0 scatters light evenly, positive values scatter forward and negative values scatter backward." />
    <input name="sheen" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Sheen" uifolder="Sheen" uiadvanced="true"
           doc="The weight of a sheen layer that can be used to approximate microfibers or fabrics such as velvet and satin." />
    <input name="sheen_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Sheen Color" uifolder="Sheen" uiadvanced="true"
           doc="The color of the sheen layer." />
    <input name="sheen_roughness" type="float" value="0.3" uimin="0.0" uimax="1.0" uiname="Sheen Roughness" uifolder="Sheen" uiadvanced="true"
           doc="The roughness of the sheen layer." />
    <input name="coat" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Coat" uifolder="Coat"
           doc="The weight of a reflective clear-coat layer on top of the material. Use for materials such as car paint or an oily layer." />
    <input name="coat_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Coat Color" uifolder="Coat"
           doc="The color of the clear-coat layer's transparency." />
    <input name="coat_roughness" type="float" value="0.1" uimin="0.0" uimax="1.0" uiname="Coat Roughness" uifolder="Coat"
           doc="The roughness of the clear-coat reflections. The lower the value, the sharper the reflection." />
    <input name="coat_anisotropy" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Coat Anisotropy" uifolder="Coat" uiadvanced="true"
           doc="The amount of directional bias, or anisotropy, of the clear-coat layer." />
    <input name="coat_rotation" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Coat Rotation" uifolder="Coat" uiadvanced="true"
           doc="The rotation of the anisotropic effect of the clear-coat layer." />
    <input name="coat_IOR" type="float" value="1.5" uimin="0.0" uisoftmin="1.0" uisoftmax="3.0" uiname="Coat Index of Refraction" uifolder="Coat"
           doc="The index of refraction of the clear-coat layer." />
    <input name="coat_normal" type="vector3" defaultgeomprop="Nworld" uiname="Coat normal" uifolder="Coat"
           doc="Input normal for clear-coat layer" />
    <input name="coat_affect_color" type="float" value="0" uimin="0" uimax="1" uiname="Coat Affect Color" uifolder="Coat" uiadvanced="true"
           doc="Controls the saturation of diffuse reflection and subsurface scattering below the clear-coat." />
    <input name="coat_affect_roughness" type="float" value="0" uimin="0" uimax="1" uiname="Coat Affect Roughness" uifolder="Coat" uiadvanced="true"
           doc="Controls the roughness of the specular reflection in the layers below the clear-coat." />
    <input name="thin_film_thickness" type="float" value="0" uimin="0.0" uisoftmax="2000.0" uiname="Thin Film Thickness" uifolder="Thin Film" uiadvanced="true"
           doc="The thickness of the thin film layer on a surface. Use for materials such as multitone car paint or soap bubbles (in nanometers)." />
    <input name="thin_film_IOR" type="float" value="1.5" uimin="0.0" uisoftmin="1.0" uisoftmax="3.0" uiname="Thin Film Index of Refraction" uifolder="Thin Film" uiadvanced="true"
           doc="The index of refraction of the medium surrounding the material." />
    <input name="emission" type="float" value="0" uimin="0.0" uisoftmax="1.0" uiname="Emission" uifolder="Emission"
           doc="The amount of emitted incandescent light." />
    <input name="emission_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Emission Color" uifolder="Emission"
           doc="The color of the emitted light." />
    <input name="opacity" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Opacity" uifolder="Geometry"
           doc="The opacity of the entire material." />
    <input name="thin_walled" type="boolean" value="false" uiname="Thin Walled" uifolder="Geometry" uiadvanced="true"
           doc="If true the surface is double-sided and represents an infinitely thin shell. Suitable for thin objects such as tree leaves or paper." />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Geometry"
           doc="Input geometric normal" />
    <input name="tangent" type="vector3" defaultgeomprop="Tworld" uiname="Tangent Input" uifolder="Geometry"
           doc="Input geometric tangent" />
    <output name="out" type="surfaceshader" />
  </nodedef>

  <!--
    Association between implementation and definition.
    Note that version 1.0.1 only changes default values and thus reuses the same 1.0.0 nodegraph implementation.
  -->
  <implementation name="IMPL_standard_surface_surfaceshader_101" nodedef="ND_standard_surface_surfaceshader" nodegraph="NG_standard_surface_surfaceshader_100" />
  <implementation name="IMPL_standard_surface_surfaceshader_100" nodedef="ND_standard_surface_surfaceshader_100" nodegraph="NG_standard_surface_surfaceshader_100" />

  <!--
    Autodesk Standard Surface nodegraph implementation.
  -->
  <nodegraph name="NG_standard_surface_surfaceshader_100">

    <!-- Roughness influence by coat-->
    <!-- Calculate main specular roughness -->
    <multiply name="coat_affect_roughness_multiply1" type="float">
      <input name="in1" type="float" interfacename="coat_affect_roughness" />
      <input name="in2" type="float" interfacename="coat" />
    </multiply>
    <multiply name="coat_affect_roughness_multiply2" type="float">
      <input name="in1" type="float" nodename="coat_affect_roughness_multiply1" />
      <input name="in2" type="float" interfacename="coat_roughness" />
    </multiply>
    <mix name="coat_affected_roughness" type="float">
      <input name="fg" type="float" value="1.0" />
      <input name="bg" type="float" interfacename="specular_roughness" />
      <input name="mix" type="float" nodename="coat_affect_roughness_multiply2" />
    </mix>
    <roughness_anisotropy name="main_roughness" type="vector2">
      <input name="roughness" type="float" nodename="coat_affected_roughness" />
      <input name="anisotropy" type="float" interfacename="specular_anisotropy" />
    </roughness_anisotropy>
    <!-- Calculate transmission roughness -->
    <add name="transmission_roughness_add" type="float">
      <input name="in1" type="float" interfacename="specular_roughness" />
      <input name="in2" type="float" interfacename="transmission_extra_roughness" />
    </add>
    <clamp name="transmission_roughness_clamped" type="float">
      <input name="in" type="float" nodename="transmission_roughness_add" />
    </clamp>
    <mix name="coat_affected_transmission_roughness" type="float">
      <input name="fg" type="float" value="1.0" />
      <input name="bg" type="float" nodename="transmission_roughness_clamped" />
      <input name="mix" type="float" nodename="coat_affect_roughness_multiply2" />
    </mix>
    <roughness_anisotropy name="transmission_roughness" type="vector2">
      <input name="roughness" type="float" nodename="coat_affected_transmission_roughness" />
      <input name="anisotropy" type="float" interfacename="specular_anisotropy" />
    </roughness_anisotropy>

    <!-- Tangent rotation -->
    <multiply name="tangent_rotate_degree" type="float">
      <input name="in1" type="float" interfacename="specular_rotation" />
      <input name="in2" type="float" value="360" />
    </multiply>
    <rotate3d name="tangent_rotate" type="vector3">
      <input name="in" type="vector3" interfacename="tangent" />
      <input name="amount" type="float" nodename="tangent_rotate_degree" />
      <input name="axis" type="vector3" interfacename="normal" />
    </rotate3d>
    <normalize name="tangent_rotate_normalize" type="vector3">
      <input name="in" type="vector3" nodename="tangent_rotate" />
    </normalize>
    <ifgreater name="main_tangent" type="vector3">
      <input name="value1" type="float" interfacename="specular_anisotropy" />
      <input name="value2" type="float" value="0.0" />
      <input name="in1" type="vector3" nodename="tangent_rotate_normalize" />
      <input name="in2" type="vector3" interfacename="tangent" />
    </ifgreater>

    <!-- Coat tangent rotation -->
    <multiply name="coat_tangent_rotate_degree" type="float">
      <input name="in1" type="float" interfacename="coat_rotation" />
      <input name="in2" type="float" value="360" />
    </multiply>
    <rotate3d name="coat_tangent_rotate" type="vector3">
      <input name="in" type="vector3" interfacename="tangent" />
      <input name="amount" type="float" nodename="coat_tangent_rotate_degree" />
      <input name="axis" type="vector3" interfacename="coat_normal" />
    </rotate3d>
    <normalize name="coat_tangent_rotate_normalize" type="vector3">
      <input name="in" type="vector3" nodename="coat_tangent_rotate" />
    </normalize>
    <ifgreater name="coat_tangent" type="vector3">
      <input name="value1" type="float" interfacename="coat_anisotropy" />
      <input name="value2" type="float" value="0.0" />
      <input name="in1" type="vector3" nodename="coat_tangent_rotate_normalize" />
      <input name="in2" type="vector3" interfacename="tangent" />
    </ifgreater>

    <!-- Colors influenced by coat ("coat gamma") -->
    <clamp name="coat_clamped" type="float">
      <input name="in" type="float" interfacename="coat" />
    </clamp>
    <multiply name="coat_gamma_multiply" type="float">
      <input name="in1" type="float" nodename="coat_clamped" />
      <input name="in2" type="float" interfacename="coat_affect_color" />
    </multiply>
    <add name="coat_gamma" type="float">
      <input name="in1" type="float" nodename="coat_gamma_multiply" />
      <input name="in2" type="float" value="1.0" />
    </add>
    <max name="base_color_nonnegative" type="color3">
      <input name="in1" type="color3" interfacename="base_color" />
      <input name="in2" type="float" value="0.0" />
    </max>
    <power name="coat_affected_diffuse_color" type="color3">
      <input name="in1" type="color3" nodename="base_color_nonnegative" />
      <input name="in2" type="float" nodename="coat_gamma" />
    </power>
    <max name="subsurface_color_nonnegative" type="color3">
      <input name="in1" type="color3" interfacename="subsurface_color" />
      <input name="in2" type="float" value="0.0" />
    </max>
    <power name="coat_affected_subsurface_color" type="color3">
      <input name="in1" type="color3" nodename="subsurface_color_nonnegative" />
      <input name="in2" type="float" nodename="coat_gamma" />
    </power>

    <!-- Diffuse/Subsurface Layer -->
    <oren_nayar_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
      <input name="weight" type="float" interfacename="base" />
      <input name="color" type="color3" nodename="coat_affected_diffuse_color" />
      <input name="roughness" type="float" interfacename="diffuse_roughness" />
      <input name="normal" type="vector3" interfacename="normal" />
    </oren_nayar_diffuse_bsdf>
    <translucent_bsdf name="translucent_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="color" type="color3" nodename="coat_affected_subsurface_color" />
      <input name="normal" type="vector3" interfacename="normal" />
    </translucent_bsdf>
    <multiply name="subsurface_radius_scaled" type="color3">
      <input name="in1" type="color3" interfacename="subsurface_radius" />
      <input name="in2" type="float" interfacename="subsurface_scale" />
    </multiply>
    <subsurface_bsdf name="subsurface_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="color" type="color3" nodename="coat_affected_subsurface_color" />
      <input name="radius" type="color3" nodename="subsurface_radius_scaled" />
      <input name="anisotropy" type="float" interfacename="subsurface_anisotropy" />
      <input name="normal" type="vector3" interfacename="normal" />
    </subsurface_bsdf>
    <convert name="subsurface_selector" type="float">
      <input name="in" type="boolean" interfacename="thin_walled" />
    </convert>
    <mix name="selected_subsurface_bsdf" type="BSDF">
      <input name="fg" type="BSDF" nodename="translucent_bsdf" />
      <input name="bg" type="BSDF" nodename="subsurface_bsdf" />
      <input name="mix" type="float" nodename="subsurface_selector" />
    </mix>
    <mix name="subsurface_mix" type="BSDF">
      <input name="fg" type="BSDF" nodename="selected_subsurface_bsdf" />
      <input name="bg" type="BSDF" nodename="diffuse_bsdf" />
      <input name="mix" type="float" interfacename="subsurface" />
    </mix>

    <!-- Sheen Layer -->
    <sheen_bsdf name="sheen_bsdf" type="BSDF">
      <input name="weight" type="float" interfacename="sheen" />
      <input name="color" type="color3" interfacename="sheen_color" />
      <input name="roughness" type="float" interfacename="sheen_roughness" />
      <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="subsurface_mix" />
    </layer>

    <!-- Transmission Layer -->
    <dielectric_bsdf name="transmission_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="tint" type="color3" interfacename="transmission_color" />
      <input name="ior" type="float" interfacename="specular_IOR" />
      <input name="roughness" type="vector2" nodename="transmission_roughness" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="tangent" type="vector3" nodename="main_tangent" />
      <input name="distribution" type="string" value="ggx" />
      <input name="scatter_mode" type="string" value="T" />
    </dielectric_bsdf>
    <mix name="transmission_mix" type="BSDF">
      <input name="fg" type="BSDF" nodename="transmission_bsdf" />
      <input name="bg" type="BSDF" nodename="sheen_layer" />
      <input name="mix" type="float" interfacename="transmission" />
    </mix>

    <!-- Specular Layer -->
    <dielectric_bsdf name="specular_bsdf" type="BSDF">
      <input name="weight" type="float" interfacename="specular" />
      <input name="tint" type="color3" interfacename="specular_color" />
      <input name="ior" type="float" interfacename="specular_IOR" />
      <input name="roughness" type="vector2" nodename="main_roughness" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="tangent" type="vector3" nodename="main_tangent" />
      <input name="distribution" type="string" value="ggx" />
      <input name="scatter_mode" type="string" value="R" />
      <input name="thinfilm_thickness" type="float" interfacename="thin_film_thickness" />
      <input name="thinfilm_ior" type="float" interfacename="thin_film_IOR" />
    </dielectric_bsdf>
    <layer name="specular_layer" type="BSDF">
      <input name="top" type="BSDF" nodename="specular_bsdf" />
      <input name="base" type="BSDF" nodename="transmission_mix" />
    </layer>

    <!-- Metal Layer -->
    <multiply name="metal_reflectivity" type="color3">
      <input name="in1" type="color3" interfacename="base_color" />
      <input name="in2" type="float" interfacename="base" />
    </multiply>
    <multiply name="metal_edgecolor" type="color3">
      <input name="in1" type="color3" interfacename="specular_color" />
      <input name="in2" type="float" interfacename="specular" />
    </multiply>
    <artistic_ior name="artistic_ior" type="multioutput">
      <input name="reflectivity" type="color3" nodename="metal_reflectivity" />
      <input name="edge_color" type="color3" nodename="metal_edgecolor" />
    </artistic_ior>
    <conductor_bsdf name="metal_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="ior" type="color3" nodename="artistic_ior" output="ior" />
      <input name="extinction" type="color3" nodename="artistic_ior" output="extinction" />
      <input name="roughness" type="vector2" nodename="main_roughness" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="tangent" type="vector3" nodename="main_tangent" />
      <input name="distribution" type="string" value="ggx" />
      <input name="thinfilm_thickness" type="float" interfacename="thin_film_thickness" />
      <input name="thinfilm_ior" type="float" interfacename="thin_film_IOR" />
    </conductor_bsdf>
    <mix name="metalness_mix" type="BSDF">
      <input name="fg" type="BSDF" nodename="metal_bsdf" />
      <input name="bg" type="BSDF" nodename="specular_layer" />
      <input name="mix" type="float" interfacename="metalness" />
    </mix>

    <!-- Coat Layer -->
    <mix name="coat_attenuation" type="color3">
      <input name="fg" type="color3" interfacename="coat_color" />
      <input name="bg" type="color3" value="1.0, 1.0, 1.0" />
      <input name="mix" type="float" interfacename="coat" />
    </mix>
    <multiply name="thin_film_layer_attenuated" type="BSDF">
      <input name="in1" type="BSDF" nodename="metalness_mix" />
      <input name="in2" type="color3" nodename="coat_attenuation" />
    </multiply>
    <roughness_anisotropy name="coat_roughness_vector" type="vector2">
      <input name="roughness" type="float" interfacename="coat_roughness" />
      <input name="anisotropy" type="float" interfacename="coat_anisotropy" />
    </roughness_anisotropy>
    <dielectric_bsdf name="coat_bsdf" type="BSDF">
      <input name="weight" type="float" interfacename="coat" />
      <input name="tint" type="color3" value="1.0, 1.0, 1.0" />
      <input name="ior" type="float" interfacename="coat_IOR" />
      <input name="roughness" type="vector2" nodename="coat_roughness_vector" />
      <input name="normal" type="vector3" interfacename="coat_normal" />
      <input name="tangent" type="vector3" nodename="coat_tangent" />
      <input name="distribution" type="string" value="ggx" />
      <input name="scatter_mode" type="string" value="R" />
    </dielectric_bsdf>
    <layer name="coat_layer" type="BSDF">
      <input name="top" type="BSDF" nodename="coat_bsdf" />
      <input name="base" type="BSDF" nodename="thin_film_layer_attenuated" />
    </layer>

    <!-- Emission Layer -->
    <subtract name="one_minus_coat_ior" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="coat_IOR" />
    </subtract>
    <add name="one_plus_coat_ior" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="coat_IOR" />
    </add>
    <divide name="coat_ior_to_F0_sqrt" type="float">
      <input name="in1" type="float" nodename="one_minus_coat_ior" />
      <input name="in2" type="float" nodename="one_plus_coat_ior" />
    </divide>
    <multiply name="coat_ior_to_F0" type="float">
      <input name="in1" type="float" nodename="coat_ior_to_F0_sqrt" />
      <input name="in2" type="float" nodename="coat_ior_to_F0_sqrt" />
    </multiply>
    <subtract name="one_minus_coat_ior_to_F0" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="coat_ior_to_F0" />
    </subtract>
    <multiply name="emission_weight" type="color3">
      <input name="in1" type="color3" interfacename="emission_color" />
      <input name="in2" type="float" interfacename="emission" />
    </multiply>
    <uniform_edf name="emission_edf" type="EDF">
      <input name="color" type="color3" nodename="emission_weight" />
    </uniform_edf>
    <multiply name="coat_tinted_emission_edf" type="EDF">
      <input name="in1" type="EDF" nodename="emission_edf" />
      <input name="in2" type="color3" interfacename="coat_color" />
    </multiply>
    <convert name="emission_color0" type="color3">
      <input name="in" type="float" nodename="one_minus_coat_ior_to_F0" />
    </convert>
    <generalized_schlick_edf name="coat_emission_edf" type="EDF">
      <input name="color0" type="color3" nodename="emission_color0" />
      <input name="color90" type="color3" value="0.0, 0.0, 0.0" />
      <input name="exponent" type="float" value="5.0" />
      <input name="base" type="EDF" nodename="coat_tinted_emission_edf" />
    </generalized_schlick_edf>
    <mix name="blended_coat_emission_edf" type="EDF">
      <input name="fg" type="EDF" nodename="coat_emission_edf" />
      <input name="bg" type="EDF" nodename="emission_edf" />
      <input name="mix" type="float" interfacename="coat" />
    </mix>

    <!-- Surface construction with opacity -->
    <!-- Node <surface> only supports monochromatic opacity so use the luminance of input opacity color -->
    <luminance name="opacity_luminance" type="color3">
      <input name="in" type="color3" interfacename="opacity" />
    </luminance>
    <extract name="opacity_luminance_float" type="float">
      <input name="in" type="color3" nodename="opacity_luminance" />
      <input name="index" type="integer" value="0" />
    </extract>
    <surface name="shader_constructor" type="surfaceshader">
      <input name="bsdf" type="BSDF" nodename="coat_layer" />
      <input name="edf" type="EDF" nodename="blended_coat_emission_edf" />
      <input name="opacity" type="float" nodename="opacity_luminance_float" />
    </surface>

    <!-- Output -->
    <output name="out" type="surfaceshader" nodename="shader_constructor" />

  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    OpenPBR Surface node definition
  -->
  <nodedef name="ND_open_pbr_surface_surfaceshader" node="open_pbr_surface" nodegroup="pbr" version="1.1" isdefaultversion="true"
           doc="OpenPBR Surface Shading Model" uiname="OpenPBR Surface">
    <input name="base_weight" type="float" value="1.0" uimin="0.0" uimax="1.0" uiname="Base Weight" uifolder="Base"
           doc="Multiplier on the intensity of the reflection from the diffuse and metallic base." />
    <input name="base_color" type="color3" value="0.8, 0.8, 0.8" uimin="0,0,0" uimax="1,1,1" uiname="Base Color" uifolder="Base"
           doc="Color of the reflection from the diffuse and metallic base." />
    <input name="base_diffuse_roughness" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Base Diffuse Roughness" uifolder="Base" uiadvanced="true"
           doc="Roughness of the diffuse reflection. Higher values cause the surface to appear flatter." />
    <input name="base_metalness" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Base Metalness" uifolder="Base"
           doc="Specifies how metallic the base material appears (dials the base from pure dielectric to pure metal)." />
    <input name="specular_weight" type="float" value="1.0" uimin="0.0" uisoftmax="1.0" uiname="Specular Weight" uifolder="Specular"
           doc="Multiplies the specular reflectivity." />
    <input name="specular_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Specular Color" uifolder="Specular"
           doc="Color of the specular reflection (controls the physical edge-tint for metals, and a non-physical overall tint for dielectrics)." />
    <input name="specular_roughness" type="float" value="0.3" uimin="0.0" uimax="1.0" uiname="Specular Roughness" uifolder="Specular"
           doc="The roughness of the specular reflection. Lower numbers produce sharper reflections, higher numbers produce blurrier reflections." />
    <input name="specular_ior" type="float" value="1.5" uimin="0.0" uisoftmin="1.0" uisoftmax="3.0" uiname="Specular Index of Refraction" uifolder="Specular"
           doc="Index of refraction of the dielectric base." />
    <input name="specular_roughness_anisotropy" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Specular Anisotropy" uifolder="Specular" uiadvanced="true"
           doc="The directional bias of the roughness of the metal/dielectric base, resulting in increasingly stretched highlights along the tangent direction." />
    <input name="transmission_weight" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Transmission Weight" uifolder="Transmission" uiadvanced="true" hint="transparency"
           doc="Mixture weight between the transparent and opaque dielectric base. The greater the value the more transparent the material." />
    <input name="transmission_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Transmission Color" uifolder="Transmission" uiadvanced="true"
           doc="Controls color of the transparent base due to Beer's law volumetric absorption under the surface (reverts to a non-physical tint when transmission_depth is zero)." />
    <input name="transmission_depth" type="float" value="0.0" uimin="0.0" uisoftmax="1.0" uiname="Transmission Depth" uifolder="Transmission" uiadvanced="true"
           doc="Specifies the distance light travels inside the transparent base before it becomes exactly the transmission_color according to Beer's law." />
    <input name="transmission_scatter" type="color3" value="0, 0, 0" uimin="0,0,0" uimax="1,1,1" uiname="Transmission Scatter" uifolder="Transmission" uiadvanced="true"
           doc="Controls the color of light volumetrically scattered inside the transparent base. Suitable for materials with visually significant scattering such as honey, fruit juice, murky water, opalescent glass, or milky glass." />
    <input name="transmission_scatter_anisotropy" type="float" value="0.0" uimin="-1.0" uimax="1.0" uiname="Transmission Anisotropy" uifolder="Transmission" uiadvanced="true"
           doc="The amount of directional bias, or anisotropy, of the volumetric scattering in the transparent base." />
    <input name="transmission_dispersion_scale" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Transmission Dispersion Scale" uifolder="Transmission" uiadvanced="true"
           doc="Linearly scales the amount of dispersion." />
    <input name="transmission_dispersion_abbe_number" type="float" value="20.0" uimin="0.0" uisoftmin="9.0" uisoftmax="91.0" uiname="Transmission Dispersion Abbe Number" uifolder="Transmission" uiadvanced="true"
           doc="Physical Abbe number of the dielectric medium, describing how much the dielectric index of refraction varies across wavelengths." />
    <input name="subsurface_weight" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Subsurface Weight" uifolder="Subsurface" uiadvanced="true"
           doc="Mixture weight which dials the opaque dielectric base between diffuse reflection and subsurface scattering. A value of 1.0 indicates full subsurface scattering and a value 0 for diffuse reflection only." />
    <input name="subsurface_color" type="color3" value="0.8, 0.8, 0.8" uimin="0,0,0" uimax="1,1,1" uiname="Subsurface Color" uifolder="Subsurface" uiadvanced="true"
           doc="The observed reflection color of the subsurface scattering medium." />
    <input name="subsurface_radius" type="float" value="1.0" uimin="0.0" uisoftmax="1.0" uiname="Subsurface Radius" uifolder="Subsurface" uiadvanced="true"
           doc="Length scale of the subsurface scattering mean free path." />
    <input name="subsurface_radius_scale" type="color3" value="1.0, 0.5, 0.25" uimin="0,0,0" uimax="1,1,1" uiname="Subsurface Radius Scale" uifolder="Subsurface" uiadvanced="true"
           doc="RGB multiplier to subsurface_radius, giving the per-channel scattering mean-free-paths." />
    <input name="subsurface_scatter_anisotropy" type="float" value="0.0" uimin="-1.0" uimax="1.0" uiname="Subsurface Anisotropy" uifolder="Subsurface" uiadvanced="true"
           doc="Controls the phase-function of subsurface scattering, where zero scatters light evenly, positive values scatter forwards, and negative values scatter backwards." />
    <input name="fuzz_weight" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Fuzz Weight" uifolder="Fuzz" uiadvanced="true"
           doc="The presence weight of a fuzz layer that can be used to approximate microfibers, for fabrics such as velvet and satin as well as dust grains." />
    <input name="fuzz_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Fuzz Color" uifolder="Fuzz" uiadvanced="true"
           doc="The color of the fuzz layer." />
    <input name="fuzz_roughness" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Fuzz Roughness" uifolder="Fuzz" uiadvanced="true"
           doc="The roughness of the fuzz layer." />
    <input name="coat_weight" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Coat Weight" uifolder="Coat"
           doc="The presence weight of a reflective clear-coat layer on top of the material. Use for materials such as car paint or an oily layer." />
    <input name="coat_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Coat Color" uifolder="Coat"
           doc="The color of the clear-coat layer's transparency, due to absorption in the coat." />
    <input name="coat_roughness" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Coat Roughness" uifolder="Coat"
           doc="The roughness of the clear-coat reflections. The lower the value, the sharper the reflection." />
    <input name="coat_roughness_anisotropy" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Coat Anisotropy" uifolder="Coat" uiadvanced="true"
           doc="The directional bias of the roughness of the clear-coat layer, resulting in increasingly stretched highlights along the coat tangent direction." />
    <input name="coat_ior" type="float" value="1.6" uimin="0.0" uisoftmin="1.0" uisoftmax="3.0" uiname="Coat Index of Refraction" uifolder="Coat"
           doc="The index of refraction of the clear-coat layer." />
    <input name="coat_darkening" type="float" value="1.0" uimin="0.0" uimax="1.0" uiname="Coat Darkening" uifolder="Coat"
           doc="Modulates the physical coat darkening effect." />
    <input name="thin_film_weight" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Thin Film Weight" uifolder="Thin Film" uiadvanced="true"
           doc="Coverage weight of the thin-film. Use for materials such as multi-tone car paint or soap bubbles." />
    <input name="thin_film_thickness" type="float" value="0.5" uimin="0.0" uisoftmax="1.0" uiname="Thin Film Thickness" uifolder="Thin Film" uiadvanced="true"
           doc="The thickness of the thin-film layer on the base (in micrometers)." />
    <input name="thin_film_ior" type="float" value="1.4" uimin="0.0" uisoftmin="1.0" uisoftmax="3.0" uiname="Thin Film Index of Refraction" uifolder="Thin Film" uiadvanced="true"
           doc="The index of refraction of the thin-film." />
    <input name="emission_luminance" type="float" value="0.0" uimin="0.0" uisoftmax="1000.0" uiname="Emission Luminance" uifolder="Emission"
           doc="The amount of emitted light, as a luminance in nits." />
    <input name="emission_color" type="color3" value="1, 1, 1" uimin="0,0,0" uimax="1,1,1" uiname="Emission Color" uifolder="Emission"
           doc="The color of the emitted light." />
    <input name="geometry_opacity" type="float" value="1" uimin="0" uimax="1" uiname="Opacity" uifolder="Geometry" hint="opacity"
           doc="The opacity of the entire material." />
    <input name="geometry_thin_walled" type="boolean" value="false" uiname="Thin Walled" uifolder="Geometry" uiadvanced="true"
           doc="If true the surface is double-sided and represents an infinitesimally thin shell. Suitable for extremely geometrically thin objects such as leaves or paper." />
    <input name="geometry_normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Geometry"
           doc="Input geometric normal" />
    <input name="geometry_coat_normal" type="vector3" defaultgeomprop="Nworld" uiname="Coat Normal" uifolder="Geometry"
           doc="Input normal for coat layer" />
    <input name="geometry_tangent" type="vector3" defaultgeomprop="Tworld" uiname="Tangent" uifolder="Geometry"
           doc="Input geometric tangent" />
    <input name="geometry_coat_tangent" type="vector3" defaultgeomprop="Tworld" uiname="Coat Tangent" uifolder="Geometry"
           doc="Input geometric tangent for coat layer" />
    <output name="out" type="surfaceshader" />
  </nodedef>

  <!--
    OpenPBR Surface graph definition
  -->
  <nodegraph name="NG_open_pbr_surface_surfaceshader" nodedef="ND_open_pbr_surface_surfaceshader">

    <!-- 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 diffuse reflection coefficient" of coat  -->
    <subtract name="one_minus_coat_F0" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="coat_ior_to_F0" />
    </subtract>
    <multiply name="coat_ior_sqr" type="float">
      <input name="in1" type="float" interfacename="coat_ior" />
      <input name="in2" type="float" interfacename="coat_ior" />
    </multiply>
    <divide name="one_minus_coat_F0_over_eta2" type="float">
      <input name="in1" type="float" nodename="one_minus_coat_F0" />
      <input name="in2" type="float" nodename="coat_ior_sqr" />
    </divide>
    <subtract name="Kcoat" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="one_minus_coat_F0_over_eta2" />
    </subtract>
    <!-- approximate base metal albedo estimate, Emetal  -->
    <multiply name="Emetal" type="color3">
      <input name="in1" type="color3" interfacename="base_color" />
      <input name="in2" type="float" interfacename="specular_weight" />
    </multiply>
    <!-- approximate base dielectric albedo estimate, Edielectric  -->
    <mix name="Edielectric" type="color3">
      <input name="fg" type="color3" interfacename="subsurface_color" />
      <input name="bg" type="color3" interfacename="base_color" />
      <input name="mix" type="float" interfacename="subsurface_weight" />
    </mix>
    <!-- thus calculate overall base albedo estimate approximation, Ebase  -->
    <mix name="Ebase" type="color3">
      <input name="fg" type="color3" nodename="Emetal" />
      <input name="bg" type="color3" nodename="Edielectric" />
      <input name="mix" type="float" interfacename="base_metalness" />
    </mix>
    <!-- final base darkening factor due to coat:  base_darkening = (1 - Kcoat) / (1 - Ebase*Kcoat)  -->
    <multiply name="Ebase_Kcoat" type="color3">
      <input name="in1" type="color3" nodename="Ebase" />
      <input name="in2" type="float" nodename="Kcoat" />
    </multiply>
    <subtract name="one_minus_Kcoat" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="Kcoat" />
    </subtract>
    <subtract name="one_minus_Ebase_Kcoat" type="color3">
      <input name="in1" type="color3" value="1.0, 1.0, 1.0" />
      <input name="in2" type="color3" nodename="Ebase_Kcoat" />
    </subtract>
    <convert name="one_minus_Kcoat_color" type="color3">
      <input name="in" type="float" nodename="one_minus_Kcoat" />
    </convert>
    <divide name="base_darkening" type="color3">
      <input name="in1" type="color3" nodename="one_minus_Kcoat_color" />
      <input name="in2" type="color3" nodename="one_minus_Ebase_Kcoat" />
    </divide>
    <multiply name="coat_weight_times_coat_darkening" type="float">
      <input name="in1" type="float" interfacename="coat_weight" />
      <input name="in2" type="float" interfacename="coat_darkening" />
    </multiply>
    <mix name="modulated_base_darkening" type="color3">
      <input name="fg" type="color3" nodename="base_darkening" />
      <input name="bg" type="color3" value="1.0, 1.0, 1.0" />
      <input name="mix" type="float" nodename="coat_weight_times_coat_darkening" />
    </mix>
    <multiply name="darkened_base_substrate" type="BSDF">
      <input name="in1" type="BSDF" nodename="base_substrate" />
      <input name="in2" type="color3" nodename="modulated_base_darkening" />
    </multiply>

    <!-- Coat Layer -->
    <mix name="coat_attenuation" type="color3">
      <input name="fg" type="color3" interfacename="coat_color" />
      <input name="bg" type="color3" value="1.0, 1.0, 1.0" />
      <input name="mix" type="float" interfacename="coat_weight" />
    </mix>
    <multiply name="coat_substrate_attenuated" type="BSDF">
      <input name="in1" type="BSDF" nodename="darkened_base_substrate" />
      <input name="in2" type="color3" nodename="coat_attenuation" />
    </multiply>

    <open_pbr_anisotropy name="coat_roughness_vector" type="vector2">
      <input name="roughness" type="float" interfacename="coat_roughness" />
      <input name="anisotropy" type="float" interfacename="coat_roughness_anisotropy" />
    </open_pbr_anisotropy>
    <dielectric_bsdf name="coat_bsdf" type="BSDF">
      <input name="weight" type="float" interfacename="coat_weight" />
      <input name="ior" type="float" interfacename="coat_ior" />
      <input name="roughness" type="vector2" nodename="coat_roughness_vector" />
      <input name="normal" type="vector3" interfacename="geometry_coat_normal" />
      <input name="tangent" type="vector3" interfacename="geometry_coat_tangent" />
      <input name="scatter_mode" type="string" value="R" />
    </dielectric_bsdf>
    <layer name="coat_layer" type="BSDF">
      <input name="top" type="BSDF" nodename="coat_bsdf" />
      <input name="base" type="BSDF" nodename="coat_substrate_attenuated" />
    </layer>

    <!-- Fuzz Layer -->
    <sheen_bsdf name="fuzz_bsdf" type="BSDF">
      <input name="weight" type="float" interfacename="fuzz_weight" />
      <input name="color" type="color3" interfacename="fuzz_color" />
      <input name="roughness" type="float" interfacename="fuzz_roughness" />
      <input name="normal" type="vector3" interfacename="geometry_normal" />
      <input name="mode" type="string" value="zeltner" />
    </sheen_bsdf>
    <layer name="fuzz_layer" type="BSDF">
      <input name="top" type="BSDF" nodename="fuzz_bsdf" />
      <input name="base" type="BSDF" nodename="coat_layer" />
    </layer>

    <!-- Emission Layer -->
    <subtract name="coat_ior_minus_one" type="float">
      <input name="in1" type="float" interfacename="coat_ior" />
      <input name="in2" type="float" value="1.0" />
    </subtract>
    <add name="coat_ior_plus_one" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="coat_ior" />
    </add>
    <divide name="coat_ior_to_F0_sqrt" type="float">
      <input name="in1" type="float" nodename="coat_ior_minus_one" />
      <input name="in2" type="float" nodename="coat_ior_plus_one" />
    </divide>
    <multiply name="coat_ior_to_F0" type="float">
      <input name="in1" type="float" nodename="coat_ior_to_F0_sqrt" />
      <input name="in2" type="float" nodename="coat_ior_to_F0_sqrt" />
    </multiply>
    <multiply name="emission_weight" type="color3">
      <input name="in1" type="color3" interfacename="emission_color" />
      <input name="in2" type="float" interfacename="emission_luminance" />
    </multiply>
    <uniform_edf name="uncoated_emission_edf" type="EDF">
      <input name="color" type="color3" nodename="emission_weight" />
    </uniform_edf>
    <multiply name="coat_tinted_emission_edf" type="EDF">
      <input name="in1" type="EDF" nodename="uncoated_emission_edf" />
      <input name="in2" type="color3" interfacename="coat_color" />
    </multiply>
    <convert name="one_minus_coat_F0_color" type="color3">
      <input name="in" type="float" nodename="one_minus_coat_F0" />
    </convert>
    <generalized_schlick_edf name="coated_emission_edf" type="EDF">
      <input name="color0" type="color3" nodename="one_minus_coat_F0_color" />
      <input name="color90" type="color3" value="0.0, 0.0, 0.0" />
      <input name="exponent" type="float" value="5.0" />
      <input name="base" type="EDF" nodename="coat_tinted_emission_edf" />
    </generalized_schlick_edf>
    <mix name="emission_edf" type="EDF">
      <input name="fg" type="EDF" nodename="coated_emission_edf" />
      <input name="bg" type="EDF" nodename="uncoated_emission_edf" />
      <input name="mix" type="float" interfacename="coat_weight" />
    </mix>

    <!-- Surface Construction -->
    <surface name="shader_constructor" type="surfaceshader">
      <input name="bsdf" type="BSDF" nodename="fuzz_layer" />
      <input name="edf" type="EDF" nodename="emission_edf" />
      <input name="opacity" type="float" interfacename="geometry_opacity" />
    </surface>

    <!-- Output -->
    <output name="out" type="surfaceshader" nodename="shader_constructor" />

  </nodegraph>

  <!--
    OpenPBR Anisotropy node definition
  -->
  <nodedef name="ND_open_pbr_anisotropy" node="open_pbr_anisotropy" nodegroup="pbr"
           doc="Computes anisotropic surface roughness as defined in the OpenPBR specification.">
    <input name="roughness" type="float" value="0.0" />
    <input name="anisotropy" type="float" value="0.0" />
    <output name="out" type="vector2" />
  </nodedef>

  <!--
    OpenPBR Anisotropy graph definition
  -->
  <nodegraph name="NG_open_pbr_anisotropy" nodedef="ND_open_pbr_anisotropy">
    <invert name="aniso_invert" type="float">
      <input name="in" type="float" interfacename="anisotropy" />
    </invert>
    <multiply name="aniso_invert_sq" type="float">
      <input name="in1" type="float" nodename="aniso_invert" />
      <input name="in2" type="float" nodename="aniso_invert" />
    </multiply>
    <add name="denom" type="float">
      <input name="in1" type="float" nodename="aniso_invert_sq" />
      <input name="in2" type="float" value="1.0" />
    </add>
    <divide name="fraction" type="float">
      <input name="in1" type="float" value="2.0" />
      <input name="in2" type="float" nodename="denom" />
    </divide>
    <sqrt name="sqrt" type="float">
      <input name="in" type="float" nodename="fraction" />
    </sqrt>
    <multiply name="rough_sq" type="float">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" interfacename="roughness" />
    </multiply>
    <multiply name="alpha_x" type="float">
      <input name="in1" type="float" nodename="rough_sq" />
      <input name="in2" type="float" nodename="sqrt" />
    </multiply>
    <multiply name="alpha_y" type="float">
      <input name="in1" type="float" nodename="aniso_invert" />
      <input name="in2" type="float" nodename="alpha_x" />
    </multiply>
    <combine2 name="result" type="vector2">
      <input name="in1" type="float" nodename="alpha_x" />
      <input name="in2" type="float" nodename="alpha_y" />
    </combine2>
    <output name="out" type="vector2" nodename="result" />
  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_dielectric" node="LamaDielectric" nodegroup="pbr" doc="Lama dielectric" version="1.0" isdefaultversion="true">
    <input name="reflectionTint" type="color3" value="1.0, 1.0, 1.0" uiname="Reflection Tint" uifolder="Main"
           doc="Color multiplier for external reflection. It should be used with parsimony, as a non-white value breaks physicality." />
    <input name="transmissionTint" type="color3" value="1.0, 1.0, 1.0" uiname="Transmission Tint" uifolder="Main"
           doc="Color multiplier for rays going inside the medium (covers external transmission and internal reflection). It should be used with parcimony, as a non-white value breaks physicality. The preferred way to define the color of a dielectric is through the Interior attributes right below." />
    <input name="fresnelMode" type="integer" uniform="true" enum="Artistic,Scientific" enumvalues="0,1" value="0" uiname="Fresnel Mode" uifolder="Main"
           doc="Switches the Fresnel parameterization between Artistic and Scientific mode. The Artistic mode offers a scalar value defining the reflectivity in the normal direction. The Scientific mode proposes an index of refraction. Both parameterizations can achieve identical results, as one can be mapped to the other." />
    <input name="IOR" type="float" value="1.5" uimin="1.0" uimax="3.0" uiname="IOR" uifolder="Main"
           doc="Index of refraction (often denoted by eta), defining the amount reflected by the surface in the normal direction, and how the rays are bent by refraction." />
    <input name="reflectivity" type="float" value="0.04" uimin="0.0" uimax="1.0" uisoftmin="0.0" uisoftmax="0.25" uiname="Reflectivity" uifolder="Main"
           doc="Amount reflected by the surface in the normal direction. Also affects how the rays are bent by refraction." />
    <input name="roughness" type="float" value="0.1" uimin="0.0" uimax="1.0" uiname="Roughness" uifolder="Main"
           doc="Micro-facet distribution roughness." />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Main"
           doc="Shading normal, typically defined by bump or normal mapping. Defaults to the smooth surface normal if not set." />
    <input name="anisotropy" type="float" value="0.0" uimin="-1.0" uimax="1.0" uiname="Anisotropy" uifolder="Anisotropy"
           doc="Defines the amount of anisotropy, changing the co-tangent axis roughness from the original value to 1 (or to 0 with a negative value)." />
    <input name="direction" type="vector3" defaultgeomprop="Tworld" uiname="Direction" uifolder="Anisotropy"
           doc="Overrides the surface tangent as the anisotropy direction." />
    <input name="rotation" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" uiname="Rotation" uifolder="Anisotropy"
           doc="Rotates the anisotropy direction (possibly overridden by the previous attribute) around the normal, from 0 to 360 degrees." />
    <input name="absorptionColor" type="color3" value="1.0, 1.0, 1.0" uiname="Absorption Color" uifolder="Interior"
           doc="Interior volume absorption color. It is defined as the negative logarithm of the extinction coefficient, with values between 0 and 1, such that the object itself and its shadows are tinted proportionnally. If set to 1, there is no absorption, and if set to 0, the object will be completely opaque. Note that for single scattering to kick in, the value must be inferior to 1. This value will also act as coating color, when this node is used as the top material in a layer node." />
    <input name="absorptionRadius" type="float" value="1.0" uimin="0.0" uiname="Absorption Radius" uifolder="Interior"
           doc="Distance, in world space units, at which the Absorption Color is assumed to be reached. Can be used to control the rate of absorption." />
    <input name="scatterColor" type="color3" value="0.0, 0.0, 0.0" uiname="Scatter Color" uifolder="Interior"
           doc="Color (aka scattering albedo) of the medium, defines what proportion of the light hitting volumetric particles is scattered around by the phase function (as opposed to just absorbed), for each color channel. Only takes effect if the corresponding channel has a non-null density, in other words if the Absorption Color value for that channel is inferior to 1." />
    <input name="scatterAnisotropy" type="float" value="0.0" uimin="-1.0" uimax="1.0" uiname="Scatter Anisotropy" uifolder="Interior"
           doc="Anisotropy of the medium's phase function, ranging from full backward scattering at -1 to forward scattering at 1. Only takes effect if the Scatter Color is non-null." />
    <output name="out" type="BSDF" />
  </nodedef>

  <nodegraph name="IMPL_lama_dielectric" nodedef="ND_lama_dielectric">

    <!-- IOR -->
    <convert name="reflectivity_color" type="color3">
      <input name="in" type="float" interfacename="reflectivity" uivisible="false" />
    </convert>
    <artistic_ior name="artistic_ior" type="multioutput">
      <input name="reflectivity" type="color3" nodename="reflectivity_color" />
      <input name="edge_color" type="color3" value="0.0, 0.0, 0.0" />
    </artistic_ior>
    <extract name="ior_float" type="float">
      <input name="in" type="color3" nodename="artistic_ior" output="ior" />
      <input name="index" type="integer" value="0" />
    </extract>
    <switch name="fresnel_mode_switch" type="float">
      <input name="in1" type="float" nodename="ior_float" />
      <input name="in2" type="float" interfacename="IOR" />
      <input name="which" type="integer" interfacename="fresnelMode" />
    </switch>

    <!-- Roughness -->
    <subtract name="roughness_inverse" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="roughness" />
    </subtract>
    <ifgreatereq name="delta" type="float">
      <input name="in1" type="float" nodename="roughness_inverse" />
      <input name="in2" type="float" interfacename="roughness" />
      <input name="value1" type="float" interfacename="anisotropy" />
      <input name="value2" type="float" value="0" />
    </ifgreatereq>
    <multiply name="roughness_additional" type="float">
      <input name="in1" type="float" interfacename="anisotropy" />
      <input name="in2" type="float" nodename="delta" />
    </multiply>
    <add name="roughness_bitangent" type="float">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" nodename="roughness_additional" />
    </add>
    <clamp name="roughness_bitangent_clamped" type="float">
      <input name="in" type="float" nodename="roughness_bitangent" />
    </clamp>
    <combine2 name="roughness_linear" type="vector2">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" nodename="roughness_bitangent_clamped" />
    </combine2>
    <power name="roughness_anisotropic_squared" type="vector2">
      <input name="in1" type="vector2" nodename="roughness_linear" />
      <input name="in2" type="float" value="2" />
    </power>
    <max name="roughness_anisotropic_squared_clamped" type="vector2">
      <input name="in1" type="vector2" nodename="roughness_anisotropic_squared" />
      <input name="in2" type="float" value="0.000001" />
    </max>

    <!-- Tangent -->
    <multiply name="tangent_rotate_degree" type="float">
      <input name="in1" type="float" interfacename="rotation" />
      <input name="in2" type="float" value="-360" />
    </multiply>
    <subtract name="tangent_rotate_degree_offset" type="float">
      <input name="in1" type="float" nodename="tangent_rotate_degree" />
      <input name="in2" type="float" value="0" />
    </subtract>
    <rotate3d name="tangent_rotate" type="vector3">
      <input name="in" type="vector3" interfacename="direction" />
      <input name="amount" type="float" nodename="tangent_rotate_degree_offset" />
      <input name="axis" type="vector3" interfacename="normal" />
    </rotate3d>
    <normalize name="tangent_rotate_normalize" type="vector3">
      <input name="in" type="vector3" nodename="tangent_rotate" />
    </normalize>

    <!-- Interior -->
    <divide name="absorption" type="color3">
      <input name="in1" type="color3" interfacename="absorptionColor" />
      <input name="in2" type="float" interfacename="absorptionRadius" />
    </divide>
    <convert name="absorption_vector" type="vector3">
      <input name="in" type="color3" nodename="absorption" />
    </convert>
    <convert name="scatter_vector" type="vector3">
      <input name="in" type="color3" interfacename="scatterColor" />
    </convert>
    <anisotropic_vdf name="interior_vdf" type="VDF">
      <input name="absorption" type="vector3" nodename="absorption_vector" />
      <input name="scattering" type="vector3" nodename="scatter_vector" />
      <input name="anisotropy" type="float" interfacename="scatterAnisotropy" />
    </anisotropic_vdf>

    <!-- BTDF -->
    <dielectric_bsdf name="transmission_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="tint" type="color3" interfacename="transmissionTint" />
      <input name="ior" type="float" nodename="fresnel_mode_switch" />
      <input name="roughness" type="vector2" nodename="roughness_anisotropic_squared_clamped" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="tangent" type="vector3" nodename="tangent_rotate_normalize" />
      <input name="distribution" type="string" value="ggx" />
      <input name="scatter_mode" type="string" value="T" />
    </dielectric_bsdf>
    <layer name="transmission_layer" type="BSDF">
      <input name="top" type="BSDF" nodename="transmission_bsdf" />
      <input name="base" type="VDF" nodename="interior_vdf" />
    </layer>

    <!-- BRDF -->
    <dielectric_bsdf name="reflection_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="tint" type="color3" interfacename="reflectionTint" />
      <input name="ior" type="float" nodename="fresnel_mode_switch" />
      <input name="roughness" type="vector2" nodename="roughness_anisotropic_squared_clamped" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="tangent" type="vector3" nodename="tangent_rotate_normalize" />
      <input name="distribution" type="string" value="ggx" />
      <input name="scatter_mode" type="string" value="R" />
    </dielectric_bsdf>

    <!-- BSDF -->
    <layer name="dielectric_bsdf" type="BSDF">
      <input name="top" type="BSDF" nodename="reflection_bsdf" />
      <input name="base" type="BSDF" nodename="transmission_layer" />
    </layer>

    <!-- Output -->
    <output name="out" type="BSDF" nodename="dielectric_bsdf" />

  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_diffuse" node="LamaDiffuse" nodegroup="pbr" version="1.0" isdefaultversion="true">
    <input name="color" uiname="Color" type="color3" value="0.18, 0.18, 0.18"
           doc="Diffuse color (aka albedo), defining what ratio of light is reflected for each color channel." />
    <input name="roughness" uiname="Roughness" type="float" uimin="0.0" uimax="1.0" value="0.0"
           doc="Micro-facet distribution (Oren-Nayar) roughness." />
    <input name="normal" uiname="Normal" type="vector3" defaultgeomprop="Nworld"
           doc="Shading normal, typically defined by bump or normal mapping. Defaults to the smooth surface normal if not set." />
    <input name="energyCompensation" uiname="Energy Compensation" uifolder="Advanced" type="float" uniform="true" uimin="0.0" uimax="1.0" value="1.0"
           doc="Indicates how much energy should be added to compensate for the loss inherent to the Oren-Nayar model, ranging from no compensation at all, to the expected energy from multiple scattering between the micro-facets. This prevents overly dark results when roughness is high." />
    <output name="out" type="BSDF" />
  </nodedef>

  <nodegraph name="NG_lama_diffuse" nodedef="ND_lama_diffuse">
    <multiply name="roughness_squared" type="float">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" interfacename="roughness" />
    </multiply>
    <multiply name="half_roughness_squared" type="float">
      <input name="in1" type="float" nodename="roughness_squared" />
      <input name="in2" type="float" value="0.5" />
    </multiply>
    <oren_nayar_diffuse_bsdf name="oren_nayar_uncompensated" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="color" type="color3" interfacename="color" />
      <input name="roughness" type="float" nodename="half_roughness_squared" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="energy_compensation" type="boolean" value="false" />
    </oren_nayar_diffuse_bsdf>
    <oren_nayar_diffuse_bsdf name="oren_nayar_compensated" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="color" type="color3" interfacename="color" />
      <input name="roughness" type="float" nodename="half_roughness_squared" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="energy_compensation" type="boolean" value="true" />
    </oren_nayar_diffuse_bsdf>
    <mix name="oren_nayar" type="BSDF">
      <input name="fg" type="BSDF" nodename="oren_nayar_compensated" />
      <input name="bg" type="BSDF" nodename="oren_nayar_uncompensated" />
      <input name="mix" type="float" interfacename="energyCompensation" />
    </mix>
    <output name="out" type="BSDF" nodename="oren_nayar" />
  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_conductor" node="LamaConductor" nodegroup="pbr" doc="Lama conductor" version="1.0" isdefaultversion="true">
    <input name="tint" type="color3" value="1, 1, 1" uiname="Tint" uifolder="Main"
           doc="Overall color multiplier. It should be used with parsimony, as a non-white value breaks physicality. The preferred way to define the color of a conductor is through the Fresnel attributes right below." />
    <input name="fresnelMode" type="integer" uniform="true" enum="Artistic,Scientific" enumvalues="0,1" value="0" uiname="Fresnel Mode" uifolder="Main"
           doc="Switches the Fresnel between Artistic and Scientific parameters. The Artistic mode offers reflectivity in the normal direction and reflectivity90 at the grazing angle. The Scientific mode provides an index of refraction for each rgb component. Note that IOR is only used to calculate the reflectivity value used by the Schlick approximation. When reflectivity90 is 1, then both modes achieve identical results, as one can be mapped to the other." />
    <input name="IOR" type="vector3" value="0.180000007153,0.419999986887,1.37000000477" uiname="IOR" uifolder="Main"
           doc="Index of refraction (often denoted by eta), defining the color reflected by the surface in the normal direction." />
    <input name="extinction" type="vector3" value="3.42000007629,2.34999990463,1.76999998093" uiname="Extinction" uifolder="Main"
           doc="Extinction coefficient (often denoted by kappa), influencing how the reflected color curve evolves between its value in the normal direction (or 0 degree), and 1 when reaching 90 degrees. A null value does not deviate the curve at all." />
    <input name="reflectivity" type="color3" value="0.9450, 0.7772, 0.3737" uiname="Reflectivity" uifolder="Main"
           doc="Color reflected by the surface in the normal direction." />
    <input name="edgeColor" type="color3" value="0.7137, 0.7373, 0.4550" uiname="Edge Color" uifolder="Main"
           doc="Indicates how the reflected color curve evolves between its value in the normal direction (or 0 degree), and 1 when reaching 90 degrees. Note that this color is unlikely to be reached, and just bends the curve towards it when reaching grazing angles. A null value does not deviate the curve at all." />
    <input name="roughness" type="float" value="0.1" uimin="0.0" uimax="1.0" uiname="Roughness" uifolder="Main"
           doc="Micro-facet distribution roughness." />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Main"
           doc="Shading normal, typically defined by bump or normal mapping. Defaults to the smooth surface normal if not set." />
    <input name="anisotropy" type="float" value="0.0" uimin="-1.0" uimax="1.0" uiname="Anisotropy" uifolder="Anisotropy"
           doc="Defines the amount of anisotropy, changing the co-tangent axis roughness from the original value to 1 (or to 0 with a negative value)." />
    <input name="anisotropyDirection" type="vector3" defaultgeomprop="Tworld" uiname="Direction" uifolder="Anisotropy"
           doc="Overrides the surface tangent as the anisotropy direction." />
    <input name="anisotropyRotation" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0"  uiname="Rotation" uifolder="Anisotropy"
           doc="Rotates the anisotropy direction (possibly overridden by the previous attribute) around the normal, from 0 to 360 degrees." />
    <output name="out" type="BSDF" />
  </nodedef>

  <nodegraph name="IMPL_lama_conductor" nodedef="ND_lama_conductor">

    <!-- IOR -->
    <artistic_ior name="artistic_ior" type="multioutput">
      <input name="reflectivity" type="color3" interfacename="reflectivity" />
      <input name="edge_color" type="color3" interfacename="edgeColor" />
    </artistic_ior>
    <convert name="convert_ior" type="color3">
      <input name="in" type="vector3" interfacename="IOR" />
    </convert>
    <convert name="convert_extinction" type="color3">
      <input name="in" type="vector3" interfacename="extinction" />
    </convert>
    <switch name="eta_switch" type="color3">
      <input name="in1" type="color3" nodename="artistic_ior" output="ior" />
      <input name="in2" type="color3" nodename="convert_ior" />
      <input name="which" type="integer" interfacename="fresnelMode" />
    </switch>
    <switch name="kappa_switch" type="color3">
      <input name="in1" type="color3" nodename="artistic_ior" output="extinction" />
      <input name="in2" type="color3" nodename="convert_extinction" />
      <input name="which" type="integer" interfacename="fresnelMode" />
    </switch>

    <!-- Roughness -->
    <subtract name="roughness_inverse" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="roughness" />
    </subtract>
    <ifgreatereq name="delta" type="float">
      <input name="in1" type="float" nodename="roughness_inverse" />
      <input name="in2" type="float" interfacename="roughness" />
      <input name="value1" type="float" interfacename="anisotropy" />
      <input name="value2" type="float" value="0" />
    </ifgreatereq>
    <multiply name="roughness_additional" type="float">
      <input name="in1" type="float" interfacename="anisotropy" />
      <input name="in2" type="float" nodename="delta" />
    </multiply>
    <add name="roughness_bitangent" type="float">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" nodename="roughness_additional" />
    </add>
    <clamp name="roughness_bitangent_clamped" type="float">
      <input name="in" type="float" nodename="roughness_bitangent" />
    </clamp>
    <combine2 name="roughness_linear" type="vector2">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" nodename="roughness_bitangent_clamped" />
    </combine2>
    <power name="roughness_anisotropic_squared" type="vector2">
      <input name="in1" type="vector2" nodename="roughness_linear" />
      <input name="in2" type="float" value="2" />
    </power>
    <max name="roughness_anisotropic_squared_clamped" type="vector2">
      <input name="in1" type="vector2" nodename="roughness_anisotropic_squared" />
      <input name="in2" type="float" value="0.000001" />
    </max>

    <!-- Tangent -->
    <multiply name="tangent_rotate_degree" type="float">
      <input name="in1" type="float" interfacename="anisotropyRotation" />
      <input name="in2" type="float" value="-360" />
    </multiply>
    <rotate3d name="tangent_rotate" type="vector3">
      <input name="in" type="vector3" interfacename="anisotropyDirection" />
      <input name="amount" type="float" nodename="tangent_rotate_degree" />
      <input name="axis" type="vector3" interfacename="normal" />
    </rotate3d>
    <normalize name="tangent_rotate_normalize" type="vector3">
      <input name="in" type="vector3" nodename="tangent_rotate" />
    </normalize>

    <!-- BRDF -->
    <conductor_bsdf name="conductor_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="ior" type="color3" nodename="eta_switch" />
      <input name="extinction" type="color3" nodename="kappa_switch" />
      <input name="roughness" type="vector2" nodename="roughness_anisotropic_squared_clamped" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="tangent" type="vector3" nodename="tangent_rotate_normalize" />
      <input name="distribution" type="string" value="ggx" />
    </conductor_bsdf>

    <!-- Tinted BRDF -->
    <multiply name="tinted_bsdf" type="BSDF">
      <input name="in1" type="BSDF" nodename="conductor_bsdf" />
      <input name="in2" type="color3" interfacename="tint" />
    </multiply>

    <!-- Output -->
    <output name="out" type="BSDF" nodename="tinted_bsdf" />

  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_iridescence" node="LamaIridescence" nodegroup="pbr" doc="Lama iridescence" version="1.0" isdefaultversion="true">
    <input name="roughness" type="float" value="0.01" uimin="0.0" uimax="1.0" uiname="Roughness" uifolder="Main"
           doc="Micro-facet distribution roughness." />
    <input name="anisotropy" type="float" value="0.0" uimin="-1.0" uimax="1.0" uiname="Anisotropy" uifolder="Anisotropy"
           doc="Defines the amount of anisotropy, changing the co-tangent axis roughness from the original value to 1 (or to 0 with a negative value)." />
    <input name="anisotropyDirection" type="vector3" defaultgeomprop="Tworld" uiname="Direction" uifolder="Anisotropy"
               doc="Overrides the surface tangent as the anisotropy direction." />
    <input name="anisotropyRotation" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" uiname="Rotation" uifolder="Anisotropy"
           doc="Rotates the anisotropy direction (possibly overridden by the previous attribute) around the normal, from 0 to 360 degrees." />
    <input name="relativeFilmThickness" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Relative Thickness" uifolder="Main"
           doc="Relative thin film thickness in the range from 0 to 1 will be scaled to the minimum and maximum thickness, respectively." />
    <input name="minFilmThickness" type="float" value="400.0" uimin="0.0" uisoftmin="0.0" uisoftmax="1000.0" uiname="Min. Thickness" uifolder="Main"
           doc="Minimum thin film thickness in nanometers, driving the iridescent effect." />
    <input name="maxFilmThickness" type="float" value="800.0" uimin="0.0" uisoftmin="0.0" uisoftmax="1000.0" uiname="Max. Thickness" uifolder="Main"
           doc="Maximum thin film thickness in nanometers, driving the iridescent effect." />
    <input name="filmIOR" type="float" value="1.3" uimin="0.0" uisoftmin="1.0" uisoftmax="3.0" uiname="IOR" uifolder="Main"
           doc="Thin film index of refraction, driving the iridescent effect." />
    <output name="out" type="BSDF" />
  </nodedef>

  <nodegraph name="IMPL_lama_iridescence" nodedef="ND_lama_iridescence">

    <!-- Roughness -->
    <subtract name="roughness_inverse" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="roughness" />
    </subtract>
    <ifgreatereq name="delta" type="float">
      <input name="in1" type="float" nodename="roughness_inverse" />
      <input name="in2" type="float" interfacename="roughness" />
      <input name="value1" type="float" interfacename="anisotropy" />
      <input name="value2" type="float" value="0" />
    </ifgreatereq>
    <multiply name="roughness_additional" type="float">
      <input name="in1" type="float" interfacename="anisotropy" />
      <input name="in2" type="float" nodename="delta" />
    </multiply>
    <add name="roughness_bitangent" type="float">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" nodename="roughness_additional" />
    </add>
    <clamp name="roughness_bitangent_clamped" type="float">
      <input name="in" type="float" nodename="roughness_bitangent" />
    </clamp>
    <combine2 name="roughness_linear" type="vector2">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" nodename="roughness_bitangent_clamped" />
    </combine2>
    <power name="roughness_anisotropic_squared" type="vector2">
      <input name="in1" type="vector2" nodename="roughness_linear" />
      <input name="in2" type="float" value="2" />
    </power>
    <max name="roughness_anisotropic_squared_clamped" type="vector2">
      <input name="in1" type="vector2" nodename="roughness_anisotropic_squared" />
      <input name="in2" type="float" value="0.000001" />
    </max>

    <!-- Tangent -->
    <normal name="tangent_normal" type="vector3">
      <input name="space" type="string" value="world" />
    </normal>
    <multiply name="tangent_rotate_degree" type="float">
      <input name="in1" type="float" interfacename="anisotropyRotation" />
      <input name="in2" type="float" value="-360" />
    </multiply>
    <subtract name="tangent_rotate_degree_offset" type="float">
      <input name="in1" type="float" nodename="tangent_rotate_degree" />
      <input name="in2" type="float" value="0" />
    </subtract>
    <rotate3d name="tangent_rotate" type="vector3">
      <input name="in" type="vector3" interfacename="anisotropyDirection" />
      <input name="amount" type="float" nodename="tangent_rotate_degree_offset" />
      <input name="axis" type="vector3" nodename="tangent_normal" /> />
    </rotate3d>
    <normalize name="tangent_rotate_normalize" type="vector3">
      <input name="in" type="vector3" nodename="tangent_rotate" />
    </normalize>

    <!-- Thinfilm Thickness -->
    <mix name="thinfilm_thickness" type="float">
      <input name="fg" type="float" interfacename="maxFilmThickness" />
      <input name="bg" type="float" interfacename="minFilmThickness" />
      <input name="mix" type="float" interfacename="relativeFilmThickness" />
    </mix>

    <!-- BSDF -->
    <dielectric_bsdf name="iridescence_bsdf" type="BSDF">
      <input name="roughness" type="vector2" nodename="roughness_anisotropic_squared_clamped" />
      <input name="ior" type="float" value="1.0" />
      <input name="thinfilm_thickness" type="float" nodename="thinfilm_thickness" />
      <input name="thinfilm_ior" type="float" interfacename="filmIOR" />
      <input name="tangent" type="vector3" nodename="tangent_rotate_normalize" />
      <input name="distribution" type="string" value="ggx" />
      <input name="scatter_mode" type="string" value="RT" />
    </dielectric_bsdf>

    <!-- Output -->
    <output name="out" type="BSDF" nodename="iridescence_bsdf" />

  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_translucent" node="LamaTranslucent" nodegroup="pbr" version="1.0" isdefaultversion="true">
    <input name="color" uiname="Color" type="color3" value="0.18, 0.18, 0.18"
           doc="Translucent color (aka albedo), defining what ratio of light is transmitted for each color channel." />
    <input name="roughness" uiname="Roughness" type="float" uimin="0.0" uimax="1.0" value="0.0"
           doc="Micro-facet distribution (Oren-Nayar) roughness." />
    <input name="normal" uiname="Normal" type="vector3" defaultgeomprop="Nworld"
           doc="Shading normal, typically defined by bump or normal mapping. Defaults to the smooth surface normal if not set." />
    <input name="energyCompensation" uiname="Energy Compensation" uifolder="Advanced" type="float" uniform="true" uimin="0.0" uimax="1.0" value="1.0"
           doc="Indicates how much energy should be added to compensate for the loss inherent to the Oren-Nayar model, ranging from no compensation at all, to the expected energy from multiple scattering between the micro-facets. This prevents overly dark results when roughness is high." />
    <output name="out" type="BSDF" />
  </nodedef>

  <nodegraph name="NG_lama_translucent" nodedef="ND_lama_translucent">
    <translucent_bsdf name="translucent_bsdf1" type="BSDF">
      <input name="color" type="color3" interfacename="color" />
      <input name="normal" type="vector3" interfacename="normal" />
    </translucent_bsdf>
    <output name="out" type="BSDF" nodename="translucent_bsdf1" />
  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_sss" node="LamaSSS" nodegroup="pbr" doc="Lama SSS" version="1.0" isdefaultversion="true">
    <input name="color" type="color3" value="0.18, 0.18, 0.18" uiname="Color" uifolder="Main"
           doc="Diffuse color (aka albedo), defining what ratio of light is reflected -- or transmitted -- for each color channel." />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Main"
           doc="Shading normal, typically defined by bump or normal mapping. Defaults to the smooth surface normal if not set." />
    <input name="sssRadius" type="color3" value="0.0, 0.0, 0.0" uiname="Radius" uifolder="SSS"
           doc="Diffuse Mean Free Path, expressed for each color channel in mm. Indicates on average how much the light travels under the surface before being scattered. The higher the value, the softer the result will be. If zero (black), which is the default value, the computation simplifies to a Lambertian reflection lobe with no subsurface scattering." />
    <input name="sssScale" type="float" value="1.0" uimin="0.0" uiname="Scale" uifolder="SSS"
           doc="Multiplies the radius, to adjust its scale to the scene at hand. If zero, the computation simplifies to a Lambertian reflection lobe with no subsurface scattering." />
    <input name="sssMode" type="integer" uniform="true" enum="Path-traced Davis,Path-traced exponential,Diffusion Burley,Diffusion Burley (mean free path)" enumvalues="0,1,2,3" value="0" uiname="Mode" uifolder="Main"
           doc="Selects what method should be used to compute sub-surface scattering. The first two options are path-traced variants, with different attenuation strategies applied to the path. The second two are traditional diffusion models. The first Diffusion Burley expects a diffuse mean free path in mm (the average length of a path measured from its entry and exit points after subsurface scattering interactions). The second Diffusion Burley uses mean free path in mm (the average distance that a photon travels in a subsurface volume, which is 1/sigma_t, where sigma_t is the extinction coefficient)." />
    <input name="sssIOR" type="float" value="1.0" uimin="1.0" uisoftmin="1.0" uisoftmax="2.0"  uiname="IOR" uifolder="SSS"
           doc="Index of refraction use to trigger cases of total internal reflections, when the paths are reaching the surface after having travelled under it. Can be used to avoid excessive glow in highly curved regions (corners, creases, ...)." />
    <input name="sssAnisotropy" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Anisotropy" uifolder="SSS"
           doc="Higher values makes light scatter predominantly forward under the surface, making the object look less diffuse and more transparent." />
    <input name="sssBleed" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Bleed" uifolder="SSS"
           doc="Controls the depth of light bleed in the subsurface medium. Has the effect of increasing the distance light travels in the medium while preserving fine detail, compared to increasing the Mean Free Path." />
    <input name="sssFollowTopology" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Follow Topology" uifolder="SSS"
           doc="Controls how strongly normals are considered in the subsurface computation. For path-traced sss (sssMode 0 and 1), the followTopology parameter reduces sss paths being blocked by backsides behind a surface, but also reduces sss from one side to another in convex regions such as ridges and ears. For diffusion sss (sssMode 2 and 3), the followTopology parameter reduces sss from one side to another in concave regions such as crevasses and wrinkles." />
    <input name="sssSubset" type="string" uniform="true" value="" uiname="Subset" uifolder="SSS"
           doc="Specifies trace subset for inclusion/exclusion when struck by a ray indirectly." />
    <input name="sssContinuationRays" type="integer" value="0" uiname="Continuation Rays" uifolder="SSS"
           doc="When enabled, ignores internal geometry and jumps to the last surface." />
    <input name="sssUnitLength" type="float" value="0.00328" uiname="Unit Length" uifolder="SSS"
           doc="This is the multiplier that converts between millimeters and scene units. Both mean free path and diffuse mean free path are specified in millimeters and this parameter is used for the unit conversion. The default value of 0.00328 converts millimeters to feet. For centimeter scene units, this would be 0.1, for meters it would be 0.001 etc." />
    <input name="mode" type="integer" uniform="true" enum="Reflection,Transmission,Reflection(with direct illumination)" enumvalues="0,1,2" value="0" uiname="Mode" uifolder="Advanced"
           doc="If the subsurface is enabled, Reflection: should be used when both the camera and the light are outside of the object. Reflection(with direct illumination): should be used when both the camera and the light are outside of the object. This mode also computes the direct illumination at the sss ray exit point. Transmission: should be used when the light is inside the object while the camera is outside. " />
    <input name="albedoInversionMethod" type="integer" enum="Pixar,Chiang" enumvalues="0,1" value="0" uiname="Albedo Inversion Method" uifolder="Advanced"
           doc="Decides which albedo inversion methods is used. Pixar: Does the Pixar Path Traced SSS default albedo inversion. Chiang: Does Chiang's albedo inversion (with no dmfp remapping). The look is closer to Arnold Standard Surface randomwalk." />
    <output name="out" type="BSDF" />
  </nodedef>

  <nodegraph name="IMPL_lama_sss" nodedef="ND_lama_sss">

    <!-- DMFP -->
    <multiply name="subsurface_radius_scaled" type="color3">
      <input name="in1" type="color3" interfacename="sssRadius" />
      <input name="in2" type="float" interfacename="sssScale" />
    </multiply>
    <multiply name="subsurface_multiply_unitlength" type="color3">
      <input name="in1" type="color3" nodename="subsurface_radius_scaled" />
      <input name="in2" type="float" interfacename="sssUnitLength" />
    </multiply>

    <!-- BRDF -->
    <subsurface_bsdf name="subsurface_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="color" type="color3" interfacename="color" />
      <input name="radius" type="color3" nodename="subsurface_multiply_unitlength" />
      <input name="anisotropy" type="float" interfacename="sssAnisotropy" />
      <input name="normal" type="vector3" interfacename="normal" />
    </subsurface_bsdf>

    <!-- Output -->
    <output name="out" type="BSDF" nodename="subsurface_bsdf" />

  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_surface" node="LamaSurface" nodegroup="pbr" version="1.0" isdefaultversion="true">
    <input name="materialFront" uiname="Material Front" type="BSDF" 
           doc="Material used on the front side (as defined by the geometric normal)." />
    <input name="materialBack" uiname="Material Back" type="BSDF" 
           doc="Material used on the back side (as defined by the geometric normal)." />
    <input name="presence" type="float" value="1.0"
           doc="Connect a mask here to apply a cutout pattern to your object. This is useful for cutouts like creating leaves and other thin, complex shapes. It can also be used as opacity for gray values for semi-opaque results when seen directly by the camera." />
    <output name="out" type="material" />
  </nodedef>

  <nodegraph name="NG_lama_surface" nodedef="ND_lama_surface">
    <surface name="front" type="surfaceshader">
      <input name="bsdf" type="BSDF" interfacename="materialFront" />
      <input name="opacity" type="float" interfacename="presence" />
    </surface>
    <surface name="back" type="surfaceshader">
      <input name="bsdf" type="BSDF" interfacename="materialBack" />
      <input name="opacity" type="float" interfacename="presence" />
    </surface>
    <surfacematerial name="surface_material" type="material">
      <input name="surfaceshader" type="surfaceshader" nodename="front" />
      <input name="backsurfaceshader" type="surfaceshader" nodename="back" />
    </surfacematerial>
    <output name="out" type="material" nodename="surface_material" />
  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_sheen" node="LamaSheen" nodegroup="pbr" doc="Lama sheen" version="1.0" isdefaultversion="true">
    <input name="color" type="color3" value="1, 1, 1" uiname="Color" uifolder="Main"
           doc="Amount of sheen to add, per channel. When this node is used as top material in a stack, the more sheen is added, the less energy will be transmitted to the base material." />
    <input name="roughness" type="float" value="0.1" uimin="0.0" uimax="1.0" uiname="Roughness" uifolder="Main"
           doc="Roughness of the sheen effect. Very rough sheen can be used to create a rough diffuse look (when combined with a diffuse node by a layer or mix)." />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Main"
           doc="Shading normal, typically defined by bump or normal mapping. Defaults to the smooth surface normal if not set." />
    <output name="out" type="BSDF" />
  </nodedef>

  <nodegraph name="IMPL_lama_sheen" nodedef="ND_lama_sheen">

    <!-- Roughness -->
    <multiply name="roughness_compressed" type="float">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" value="0.9" />
    </multiply>
    <add name="roughness_remapped" type="float">
      <input name="in1" type="float" nodename="roughness_compressed" />
      <input name="in2" type="float" value="0.1" />
    </add>
    <power name="roughness_squared" type="float">
      <input name="in1" type="float" nodename="roughness_remapped" />
      <input name="in2" type="float" value="2" />
    </power>

    <!-- BRDF -->
    <sheen_bsdf name="sheen_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="color" type="color3" interfacename="color" />
      <input name="roughness" type="float" nodename="roughness_squared" />
      <input name="normal" type="vector3" interfacename="normal" />
    </sheen_bsdf>

    <!-- Output -->
    <output name="out" type="BSDF" nodename="sheen_bsdf" />

  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">

  <!-- LamaAdd for BSDFs -->
  <nodedef name="ND_lama_add_bsdf" node="LamaAdd" nodegroup="pbr" version="1.0" isdefaultversion="true">
    <input name="material1" uiname="Material 1" type="BSDF" doc="First material to add." />
    <input name="material2" uiname="Material 2" type="BSDF" doc="Second material to add." />
    <input name="weight1" uiname="Weight 1" type="float" uimin="0.0" uimax="1.0" value="1.0" doc="Weight of the first material." />
    <input name="weight2" uiname="Weight 2" type="float" uimin="0.0" uimax="1.0" value="0.0" doc="Weight of the second material." />
    <output name="out" type="BSDF" />
  </nodedef>
  <nodegraph name="NG_lama_add_bsdf" nodedef="ND_lama_add_bsdf">
    <multiply name="mul1" type="BSDF">
      <input name="in1" type="BSDF" interfacename="material1" />
      <input name="in2" type="float" interfacename="weight1" />
    </multiply>
    <multiply name="mul2" type="BSDF">
      <input name="in1" type="BSDF" interfacename="material2" />
      <input name="in2" type="float" interfacename="weight2" />
    </multiply>
    <add name="add1" type="BSDF">
      <input name="in1" type="BSDF" nodename="mul1" />
      <input name="in2" type="BSDF" nodename="mul2" />
    </add>
    <output name="out" type="BSDF" nodename="add1" />
  </nodegraph>

  <!-- LamaAdd for EDFs -->
  <nodedef name="ND_lama_add_edf" node="LamaAdd" nodegroup="pbr" version="1.0" isdefaultversion="true">
    <input name="material1" uiname="Material 1" type="EDF" doc="First material to add." />
    <input name="material2" uiname="Material 2" type="EDF" doc="Second material to add." />
    <input name="weight1" uiname="Weight 1" type="float" uimin="0.0" uimax="1.0" value="1.0" doc="Weight of the first material." />
    <input name="weight2" uiname="Weight 2" type="float" uimin="0.0" uimax="1.0" value="0.0" doc="Weight of the second material." />
    <output name="out" type="EDF" />
  </nodedef>
  <nodegraph name="NG_lama_add_edf" nodedef="ND_lama_add_edf">
    <multiply name="mul1" type="EDF">
      <input name="in1" type="EDF" interfacename="material1" />
      <input name="in2" type="float" interfacename="weight1" />
    </multiply>
    <multiply name="mul2" type="EDF">
      <input name="in1" type="EDF" interfacename="material2" />
      <input name="in2" type="float" interfacename="weight2" />
    </multiply>
    <add name="add1" type="EDF">
      <input name="in1" type="EDF" nodename="mul1" />
      <input name="in2" type="EDF" nodename="mul2" />
    </add>
    <output name="out" type="EDF" nodename="add1" />
  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <!-- LamaLayer for BSDFs -->
  <nodedef name="ND_lama_layer_bsdf" node="LamaLayer" nodegroup="pbr" version="1.0" isdefaultversion="true">
    <input name="materialTop" uiname="Material Top" type="BSDF"
           doc="Material used for the top slab. If not set, the base material will be used by itself." />
    <input name="materialBase" uiname="Material Base" type="BSDF"
           doc="Base material, right under the top one." />
    <input name="topMix" uiname="Top Mix" type="float" uimin="0.0" uimax="1.0" value="1.0"
           doc="Defines how visible the top material is." />
    <!-- NOTE: The topThickness feature isn't supported by the MaterialX definitions of the nodes right now. -->
    <input name="topThickness" uiname="Top Thickness" type="float" uimin="0.0" value="0.0"
           doc="Thickness of the top slab. It is only relevant for interior effects associated with the top material, such as absorption. If the top material is itself a layer node, this value is passed on to its base component. And if the top material is a mix or add, this value is passed on to both child materials." />
    <output name="out" type="BSDF" />
  </nodedef>
  <nodegraph name="NG_lama_layer_bsdf" nodedef="ND_lama_layer_bsdf">
    <multiply name="mul" type="BSDF">
      <input name="in1" type="BSDF" interfacename="materialTop" />
      <input name="in2" type="float" interfacename="topMix" />
    </multiply>
    <layer name="layer" type="BSDF">
      <input name="top" type="BSDF" nodename="mul" />
      <input name="base" type="BSDF" interfacename="materialBase" />
    </layer>
    <output name="out" type="BSDF" nodename="layer" />
  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_generalized_schlick" node="LamaGeneralizedSchlick" nodegroup="pbr" doc="Lama generalized schlick" version="1.0" isdefaultversion="true">
    <input name="reflectionTint" type="color3" value="1.0, 1.0, 1.0" uiname="Reflection Tint" uifolder="Main"
           doc="Color multiplier for external reflection. It should be used with parsimony, as a non-white value breaks physicality." />
    <input name="transmissionTint" type="color3" value="1.0, 1.0, 1.0" uiname="Transmission Tint" uifolder="Main"
           doc="Color multiplier for rays going inside the medium (covers external transmission and internal reflection). It should be used sparingly, as a non-white value breaks physicality. The preferred way to define the color of a dielectric is through the Interior attributes right below." />
    <input name="fresnelMode" type="integer" uniform="true" enum="Artistic,Scientific" enumvalues="0,1" value="0" uiname="Fresnel Mode" uifolder="Main"
           doc="Switches the Fresnel between Artistic and Scientific parameters. The Artistic mode offers reflectivity in the normal direction and reflectivity90 at the grazing angle. The Scientific mode provides an index of refraction for each rgb component. Note that IOR is only used to calculate the reflectivity value used by the Schlick approximation. When reflectivity90 is 1, then both modes achieve identical results, as one can be mapped to the other." />
    <input name="IOR" type="vector3" value="1.5,1.5,1.5" uiname="IOR" uifolder="Main"
           doc="Index of refraction (often denoted by eta), defining the amount reflected by the surface in the normal direction, and how the rays are bent by refraction. A separate value can be specified for each color channel, if desired." />
    <input name="reflectivity" type="color3" value="0.04, 0.04, 0.04" uiname="Reflectivity" uifolder="Main"
           doc="Color reflected by the surface in the normal direction." />
    <input name="reflectivity90" type="color3" value="1.0, 1.0, 1.0" uiname="Reflectivity 90" uifolder="Main"
           doc="Color reflected by the surface at the grazing angle. Should be kept at 1,1,1 for most materials." />
    <input name="reflectivityProfile" type="float" value="0.2" uimin="0.0" uimax="1.0" uiname="ReflectivityProfile" uifolder="Main"
           doc="The inverse of the exponent to use for Schlick." />
    <input name="roughness" type="float" value="0.1" uimin="0.0" uimax="1.0" uiname="Roughness" uifolder="Main"
           doc="Micro-facet distribution roughness." />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" uiname="Normal" uifolder="Main"
           doc="Shading normal, typically defined by bump or normal mapping. Defaults to the smooth surface normal if not set." />
    <input name="anisotropy" type="float" value="-1.0" uimin="-1.0" uimax="1.0" uiname="Anisotropy" uifolder="Anisotropy"
           doc="Defines the roughness in the co-tangent direction, giving anisotropic reflection if the value differs from the roughness parameter value. A negative value (the default) means use the original roughness value, i.e. no anisotropy. " />
    <input name="anisotropyDirection" type="vector3" defaultgeomprop="Tworld" uiname="Direction" uifolder="Anisotropy"
           doc="Overrides the surface tangent as the anisotropy direction." />
    <input name="anisotropyRotation" type="float" value="0.0" uisoftmin="0.0" uisoftmax="1.0" uiname="Rotation" uifolder="Anisotropy"
           doc="Rotates the anisotropy direction (possibly overridden by the previous attribute) around the normal, from 0 to 360 degrees." />
    <input name="absorptionColor" type="color3" value="1.0, 1.0, 1.0" uiname="Absorption Color" uifolder="Interior"
           doc="Interior volume absorption color. It is defined as the negative logarithm of the extinction coefficient, with values between 0 and 1, such that the object itself and its shadows are tinted proportionally. If set to 1, there is no absorption, and if set to 0, the object will be completely opaque. Note that for single scattering to kick in, the value must be inferior to 1. This value will also act as coating color, when this node is used as top layer in a stack." />
    <input name="absorptionRadius" type="float" value="1.0" uimin="0.0" uiname="Absorption Radius" uifolder="Interior"
           doc="Distance, in world space units, at which the Absorption Color is assumed to be reached. Can be used to control the rate of absorption." />
    <input name="scatterColor" type="color3" value="0.0, 0.0, 0.0" uiname="Scatter Color" uifolder="Interior"
           doc="Color (aka scattering albedo) of the medium, defines what proportion of the light hitting volumetric particles is scattered around by the phase function (as opposed to just absorbed), for each color channel. Only takes effect if the corresponding channel has a non-null density, in other words if the Absorption Color value for that channel is inferior to 1." />
    <input name="scatterAnisotropy" type="float" value="0.0" uimin="-1.0" uimax="1.0" uiname="Scatter Anisotropy" uifolder="Interior"
           doc="Anisotropy of the medium's phase function, ranging from full backward scattering at -1 to forward scattering at 1. Only takes effect if the Scatter Color is non-null." />
    <output name="out" type="BSDF" />
  </nodedef>

  <nodegraph name="IMPL_lama_generalized_schlick" nodedef="ND_lama_generalized_schlick">

    <!-- Color0 and Color90 -->
    <convert name="convert_ior" type="color3">
      <input name="in" type="vector3" interfacename="IOR" />
    </convert>
    <add name="ior_plus_one" type="color3">
      <input name="in1" type="color3" nodename="convert_ior" />
      <input name="in2" type="float" value="1" />
    </add>
    <subtract name="ior_sub_one" type="color3">
      <input name="in1" type="color3" nodename="convert_ior" />
      <input name="in2" type="float" value="1" />
    </subtract>
    <divide name="ior_divide" type="color3">
      <input name="in1" type="color3" nodename="ior_sub_one" />
      <input name="in2" type="color3" nodename="ior_plus_one" />
    </divide>
    <multiply name="ior_multiply" type="color3">
      <input name="in1" type="color3" nodename="ior_divide" />
      <input name="in2" type="color3" nodename="ior_divide" />
    </multiply>
    <switch name="fresnel_mode_switch" type="color3">
      <input name="in1" type="color3" interfacename="reflectivity" />
      <input name="in2" type="color3" nodename="ior_multiply" />
      <input name="which" type="integer" interfacename="fresnelMode" />
    </switch>

    <!-- Exponent -->
    <divide name="exponent" type="float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" interfacename="reflectivityProfile" />
    </divide>

    <!-- Roughness -->
    <ifgreater name="anisotropy_switch" type="float">
      <input name="value1" type="float" interfacename="anisotropy" />
      <input name="value2" type="float" value="0.0" />
      <input name="in1" type="float" interfacename="anisotropy" />
      <input name="in2" type="float" interfacename="roughness" />
    </ifgreater>
    <combine2 name="roughness_linear" type="vector2">
      <input name="in1" type="float" interfacename="roughness" />
      <input name="in2" type="float" nodename="anisotropy_switch" />
    </combine2>
    <power name="roughness_anisotropic_squared" type="vector2">
      <input name="in1" type="vector2" nodename="roughness_linear" />
      <input name="in2" type="float" value="2" />
    </power>
    <max name="roughness_anisotropic_squared_clamped" type="vector2">
      <input name="in1" type="vector2" nodename="roughness_anisotropic_squared" />
      <input name="in2" type="float" value="0.000001" />
    </max>

    <!-- Tangent -->
    <multiply name="tangent_rotate_degree" type="float">
      <input name="in1" type="float" interfacename="anisotropyRotation" />
      <input name="in2" type="float" value="-360" />
    </multiply>
    <rotate3d name="tangent_rotate" type="vector3">
      <input name="in" type="vector3" interfacename="anisotropyDirection" />
      <input name="amount" type="float" nodename="tangent_rotate_degree" />
      <input name="axis" type="vector3" interfacename="normal" />
    </rotate3d>
    <normalize name="tangent_rotate_normalize" type="vector3">
      <input name="in" type="vector3" nodename="tangent_rotate" />
    </normalize>

    <!-- Interior -->
    <divide name="absorption" type="color3">
      <input name="in1" type="color3" interfacename="absorptionColor" />
      <input name="in2" type="float" interfacename="absorptionRadius" />
    </divide>
    <convert name="absorption_vector" type="vector3">
      <input name="in" type="color3" nodename="absorption" />
    </convert>
    <convert name="scatter_vector" type="vector3">
      <input name="in" type="color3" interfacename="scatterColor" />
    </convert>
    <anisotropic_vdf name="interior_vdf" type="VDF">
      <input name="absorption" type="vector3" nodename="absorption_vector" />
      <input name="scattering" type="vector3" nodename="scatter_vector" />
      <input name="anisotropy" type="float" interfacename="scatterAnisotropy" />
    </anisotropic_vdf>

    <!-- Transmission -->
    <generalized_schlick_bsdf name="transmission_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="color0" type="color3" nodename="fresnel_mode_switch" />
      <input name="color90" type="color3" interfacename="reflectivity90" />
      <input name="exponent" type="float" nodename="exponent" />
      <input name="roughness" type="vector2" nodename="roughness_anisotropic_squared_clamped" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="tangent" type="vector3" nodename="tangent_rotate_normalize" />
      <input name="distribution" type="string" value="ggx" />
      <input name="scatter_mode" type="string" value="T" />
    </generalized_schlick_bsdf>
    <layer name="transmission_interior" type="BSDF">
      <input name="top" type="BSDF" nodename="transmission_bsdf" />
      <input name="base" type="VDF" nodename="interior_vdf" />
    </layer>
    <multiply name="transmission_layer" type="BSDF">
      <input name="in1" type="BSDF" nodename="transmission_interior" />
      <input name="in2" type="color3" interfacename="transmissionTint" />
    </multiply>

    <!-- Reflection -->
    <generalized_schlick_bsdf name="reflection_generalized_schlick_bsdf" type="BSDF">
      <input name="weight" type="float" value="1.0" />
      <input name="color0" type="color3" nodename="fresnel_mode_switch" />
      <input name="color90" type="color3" interfacename="reflectivity90" />
      <input name="exponent" type="float" nodename="exponent" />
      <input name="roughness" type="vector2" nodename="roughness_anisotropic_squared_clamped" />
      <input name="normal" type="vector3" interfacename="normal" />
      <input name="tangent" type="vector3" nodename="tangent_rotate_normalize" />
      <input name="distribution" type="string" value="ggx" />
      <input name="scatter_mode" type="string" value="R" />
    </generalized_schlick_bsdf>
    <multiply name="reflection_layer" type="BSDF">
      <input name="in1" type="BSDF" nodename="reflection_generalized_schlick_bsdf" />
      <input name="in2" type="color3" interfacename="reflectionTint" />
    </multiply>

    <!-- BSDF -->
    <layer name="generalized_schlick_bsdf" type="BSDF">
      <input name="top" type="BSDF" nodename="reflection_layer" />
      <input name="base" type="BSDF" nodename="transmission_layer" />
    </layer>

    <!-- Output -->
    <output name="out" type="BSDF" nodename="generalized_schlick_bsdf" />

  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">
  <nodedef name="ND_lama_emission" node="LamaEmission" nodegroup="pbr" doc="Lama emission" version="1.0" isdefaultversion="true">
    <input name="color" type="color3" value="0.0, 0.0, 0.0" uiname="Color" uifolder="Main"
           doc="Color being uniformly emitted in all directions above the surface." />
    <output name="out" type="EDF" />
  </nodedef>

  <nodegraph name="IMPL_lama_emission" nodedef="ND_lama_emission">

    <!-- EDF -->
    <uniform_edf name="emission" type="EDF">
      <input name="color" type="color3" interfacename="color" />
    </uniform_edf>

    <!-- Output -->
    <output name="out" type="EDF" nodename="emission" />

  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39" colorspace="acescg">

  <!-- LamaMix for BSDFs -->
  <nodedef name="ND_lama_mix_bsdf" node="LamaMix" nodegroup="pbr" version="1.0" isdefaultversion="true">
    <input name="material1" uiname="Material 1" type="BSDF"
           doc="First material to mix." />
    <input name="material2" uiname="Material 2" type="BSDF"
           doc="Second material to mix." />
    <input name="mix" type="float" uimin="0.0" uimax="1.0" value="0.0"
           doc="Defines the balance between the two materials, ranging from 0 (Material 1 only) to 1 (Material 2 only). Can also be seen as a Material 2 over Material 1 mask." />
    <output name="out" type="BSDF" />
  </nodedef>
  <nodegraph name="NG_lama_mix_bsdf" nodedef="ND_lama_mix_bsdf">
    <mix name="mix" type="BSDF">
      <input name="fg" type="BSDF" interfacename="material2" />
      <input name="bg" type="BSDF" interfacename="material1" />
      <input name="mix" type="float" interfacename="mix" />
    </mix>
    <output name="out" type="BSDF" nodename="mix" />
  </nodegraph>

  <!-- LamaMix for EDFs -->
  <nodedef name="ND_lama_mix_edf" node="LamaMix" nodegroup="pbr" version="1.0" isdefaultversion="true">
    <input name="material1" uiname="Material 1" type="EDF"
           doc="First material to mix." />
    <input name="material2" uiname="Material 2" type="EDF"
           doc="Second material to mix." />
    <input name="mix" type="float" uimin="0.0" uimax="1.0" value="0.0"
           doc="Defines the balance between the two materials, ranging from 0 (Material 1 only) to 1 (Material 2 only). Can also be seen as a Material 2 over Material 1 mask." />
    <output name="out" type="EDF" />
  </nodedef>
  <nodegraph name="NG_lama_mix_edf" nodedef="ND_lama_mix_edf">
    <mix name="mix" type="EDF">
      <input name="fg" type="EDF" interfacename="material2" />
      <input name="bg" type="EDF" interfacename="material1" />
      <input name="mix" type="float" interfacename="mix" />
    </mix>
    <output name="out" type="EDF" nodename="mix" />
  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <nodedef name="ND_standard_surface_to_UsdPreviewSurface" node="standard_surface_to_UsdPreviewSurface" nodegroup="translation">
    <input name="metalness" type="float" value="0" />
    <input name="base" type="float" value="1" />
    <input name="base_color" type="color3" value="0.8, 0.8, 0.8" />
    <input name="specular" type="float" value="1" />
    <input name="specular_color" type="color3" value="1, 1, 1" />
    <input name="specular_IOR" type="float" value="1.5" />
    <input name="specular_roughness" type="float" value="0.2" />
    <input name="coat" type="float" value="0" />
    <input name="coat_color" type="color3" value="1, 1, 1" />
    <input name="coat_roughness" type="float" value="0.1" />
    <input name="subsurface" type="float" value="0" />
    <input name="subsurface_color" type="color3" value="1, 1, 1" />
    <input name="emission" type="float" value="0" />
    <input name="emission_color" type="color3" value="1, 1, 1" />
    <input name="opacity" type="color3" value="1, 1, 1" />
    <input name="normal" type="vector3" value="0.5, 0.5, 1.0" />

    <output name="diffuseColor_out" type="color3" />
    <output name="emissiveColor_out" type="color3" />
    <output name="metallic_out" type="float" />
    <output name="roughness_out" type="float" />
    <output name="clearcoat_out" type="float" />
    <output name="clearcoatRoughness_out" type="float" />
    <output name="opacity_out" type="float" />
    <output name="ior_out" type="float" />
    <output name="normal_out" type="vector3" />
  </nodedef>

  <nodegraph name="NG_standard_surface_to_UsdPreviewSurface" nodedef="ND_standard_surface_to_UsdPreviewSurface">

    <!-- Constants -->
    <divide name="constantOneThird" type="float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" value="3" />
    </divide>
    <convert name="constantOneThirdVector" type="vector3">
      <input name="in" type="float" nodename="constantOneThird" />
    </convert>

    <!-- Diffuse/Specular -->
    <dot name="metallic" type="float">
      <input name="in" type="float" interfacename="metalness" />
    </dot>
    <multiply name="scaledBaseColor" type="color3">
      <input name="in1" type="color3" interfacename="base_color" />
      <input name="in2" type="float" interfacename="base" />
    </multiply>
    <mix name="baseSubsurfaceColor" type="color3">
      <input name="fg" type="color3" interfacename="subsurface_color" />
      <input name="bg" type="color3" nodename="scaledBaseColor" />
      <input name="mix" type="float" interfacename="subsurface" />
    </mix>
    <mix name="coatAttenuation" type="color3">
      <input name="fg" type="color3" interfacename="coat_color" />
      <input name="bg" type="color3" value="1.0, 1.0, 1.0" />
      <input name="mix" type="float" interfacename="coat" />
    </mix>
    <multiply name="diffuseColor" type="color3">
      <input name="in1" type="color3" nodename="baseSubsurfaceColor" />
      <input name="in2" type="color3" nodename="coatAttenuation" />
    </multiply>
    <dot name="roughness" type="float">
      <input name="in" type="float" interfacename="specular_roughness" />
    </dot>
    <dot name="ior" type="float">
      <input name="in" type="float" interfacename="specular_IOR" />
    </dot>

    <!-- Clearcoat -->
    <multiply name="scaledCoatColor" type="color3">
      <input name="in1" type="color3" interfacename="coat_color" />
      <input name="in2" type="float" interfacename="coat" />
    </multiply>
    <convert name="coatColorVector" type="vector3">
      <input name="in" type="color3" nodename="scaledCoatColor" />
    </convert>
    <dotproduct name="clearcoat" type="float">
      <input name="in1" type="vector3" nodename="coatColorVector" />
      <input name="in2" type="vector3" nodename="constantOneThirdVector" />
    </dotproduct>
    <dot name="clearcoatRoughness" type="float">
      <input name="in" type="float" interfacename="coat_roughness" />
    </dot>

    <!-- Emissive -->
    <multiply name="scaledEmissionColor" type="color3">
      <input name="in1" type="color3" interfacename="emission_color" />
      <input name="in2" type="float" interfacename="emission" />
    </multiply>
    <multiply name="emissiveColor" type="color3">
      <input name="in1" type="color3" nodename="scaledEmissionColor" />
      <input name="in2" type="color3" nodename="coatAttenuation" />
    </multiply>

    <!-- Opacity -->
    <convert name="opacityVector" type="vector3">
      <input name="in" type="color3" interfacename="opacity" />
    </convert>
    <dotproduct name="opacity" type="float">
      <input name="in1" type="vector3" nodename="opacityVector" />
      <input name="in2" type="vector3" nodename="constantOneThirdVector" />
    </dotproduct>

    <!-- Normal Map -->
    <subtract name="biasNormal" type="vector3">
      <input name="in1" type="vector3" interfacename="normal" />
      <input name="in2" type="float" value="0.5" />
    </subtract>
    <multiply name="normal" type="vector3">
      <input name="in1" type="vector3" nodename="biasNormal" />
      <input name="in2" type="float" value="2" />
    </multiply>

    <output name="diffuseColor_out" type="color3" nodename="diffuseColor" />
    <output name="emissiveColor_out" type="color3" nodename="emissiveColor" />
    <output name="metallic_out" type="float" nodename="metallic" />
    <output name="roughness_out" type="float" nodename="roughness" />
    <output name="clearcoat_out" type="float" nodename="clearcoat" />
    <output name="clearcoatRoughness_out" type="float" nodename="clearcoatRoughness" />
    <output name="opacity_out" type="float" nodename="opacity" />
    <output name="ior_out" type="float" nodename="ior" />
    <output name="normal_out" type="vector3" nodename="normal" />
  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <nodedef name="ND_standard_surface_to_gltf_pbr" node="standard_surface_to_gltf_pbr" nodegroup="translation">
    <input name="base" type="float" value="1" />
    <input name="base_color" type="color3" value="0.8, 0.8, 0.8" />
    <input name="metalness" type="float" value="0" />
    <input name="specular_roughness" type="float" value="0.2" />
    <input name="transmission" type="float" value="0" />
    <input name="transmission_color" type="color3" value="1, 1, 1" />
    <input name="transmission_depth" type="float" value="0" />
    <input name="sheen" type="float" value="0" />
    <input name="sheen_color" type="color3" value="1, 1, 1" />
    <input name="sheen_roughness" type="float" value="0.3" />
    <input name="coat" type="float" value="0" />
    <input name="coat_color" type="color3" value="0, 0, 0" />
    <input name="coat_roughness" type="float" value="0.1" />
    <input name="emission" type="float" value="0" />
    <input name="emission_color" type="color3" value="1, 1, 1" />

    <output name="base_color_out" type="color3" />
    <output name="metallic_out" type="float" />
    <output name="roughness_out" type="float" />
    <output name="transmission_out" type="float" />
    <output name="thickness_out" type="float" />
    <output name="attenuation_color_out" type="color3" />
    <output name="sheen_color_out" type="color3" />
    <output name="sheen_roughness_out" type="float" />
    <output name="clearcoat_out" type="float" />
    <output name="clearcoat_roughness_out" type="float" />
    <output name="emissive_out" type="color3" />
  </nodedef>

  <nodegraph name="NG_standard_surface_to_gltf_pbr" nodedef="ND_standard_surface_to_gltf_pbr">

    <!-- Constants -->
    <divide name="constantOneThird" type="float">
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" value="3" />
    </divide>
    <convert name="constantOneThirdVector" type="vector3">
      <input name="in" type="float" nodename="constantOneThird" />
    </convert>

    <!-- Coat attenuation -->
    <convert name="coatColorVector" type="vector3">
      <input name="in" type="color3" interfacename="coat_color" />
    </convert>
    <dotproduct name="hasCoatColor" type="float">
      <input name="in1" type="vector3" nodename="coatColorVector" />
      <input name="in2" type="vector3" value="1, 1, 1" />
    </dotproduct>
    <multiply name="scaledBaseColor" type="color3">
      <input name="in1" type="color3" interfacename="base_color" />
      <input name="in2" type="float" interfacename="base" />
    </multiply>
    <mix name="coatAttenuation" type="color3">
      <input name="fg" type="color3" interfacename="coat_color" />
      <input name="bg" type="color3" value="1, 1, 1" />
      <input name="mix" type="float" interfacename="coat" />
    </mix>
    <multiply name="mixedBaseColor" type="color3">
      <input name="in1" type="color3" nodename="scaledBaseColor" />
      <input name="in2" type="color3" nodename="coatAttenuation" />
    </multiply>
    <multiply name="coatColorScaled" type="color3">
      <input name="in1" type="color3" interfacename="coat_color" />
      <input name="in2" type="float" interfacename="coat" />
    </multiply>
    <convert name="coatColorScaledVector" type="vector3">
      <input name="in" type="color3" nodename="coatColorScaled" />
    </convert>
    <dotproduct name="weightedCoat" type="float">
      <input name="in1" type="vector3" nodename="coatColorScaledVector" />
      <input name="in2" type="vector3" nodename="constantOneThirdVector" />
    </dotproduct>

    <!-- Metallic roughness -->
    <ifequal name="baseColor" type="color3">
      <input name="value1" type="float" nodename="hasCoatColor" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="color3" nodename="scaledBaseColor" />
      <input name="in2" type="color3" nodename="mixedBaseColor" />
    </ifequal>
    <ifgreater name="transmissionBaseColor" type="color3">
      <input name="value1" type="float" interfacename="transmission_depth" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="color3" value="1, 1, 1" />
      <input name="in2" type="color3" interfacename="transmission_color" />
    </ifgreater>
    <ifgreater name="base_color" type="color3">
      <input name="value1" type="float" interfacename="transmission" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="color3" nodename="transmissionBaseColor" />
      <input name="in2" type="color3" nodename="baseColor" />
    </ifgreater>
    <dot name="metallic" type="float">
      <input name="in" type="float" interfacename="metalness" />
    </dot>
    <dot name="roughness" type="float">
      <input name="in" type="float" interfacename="specular_roughness" />
    </dot>

    <!-- Transmission -->
    <dot name="transmission" type="float">
      <input name="in" type="float" interfacename="transmission" />
    </dot>
    <dot name="thickness" type="float">
      <input name="in" type="float" interfacename="transmission_depth" />
    </dot>
    <ifgreater name="transmissionAttenuationColor" type="color3">
      <input name="value1" type="float" interfacename="transmission_depth" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="color3" interfacename="transmission_color" />
      <input name="in2" type="color3" value="1, 1, 1" />
    </ifgreater>
    <ifgreater name="attenuation_color" type="color3">
      <input name="value1" type="float" interfacename="transmission" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="color3" nodename="transmissionAttenuationColor" />
      <input name="in2" type="color3" value="1, 1, 1" />
    </ifgreater>

    <!-- Sheen -->
    <multiply name="sheen_color" type="color3">
      <input name="in1" type="color3" interfacename="sheen_color" />
      <input name="in2" type="float" interfacename="sheen" />
    </multiply>
    <ifgreater name="sheen_roughness" type="float">
      <input name="value1" type="float" interfacename="sheen" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="float" interfacename="sheen_roughness" />
      <input name="in2" type="float" value="0" />
    </ifgreater>

    <!-- Clearcoat -->
    <ifequal name="clearcoat" type="float">
      <input name="value1" type="float" nodename="hasCoatColor" />
      <input name="value2" type="float" value="0" />
      <input name="in1" type="float" interfacename="coat" />
      <input name="in2" type="float" nodename="weightedCoat" />
    </ifequal>
    <dot name="clearcoat_roughness" type="float">
      <input name="in" type="float" interfacename="coat_roughness" />
    </dot>

    <!-- Emission -->
    <multiply name="emissive" type="color3">
      <input name="in1" type="color3" interfacename="emission_color" />
      <input name="in2" type="float" interfacename="emission" />
    </multiply>

    <output name="base_color_out" type="color3" nodename="base_color" />
    <output name="metallic_out" type="float" nodename="metallic" />
    <output name="roughness_out" type="float" nodename="roughness" />
    <output name="transmission_out" type="float" nodename="transmission" />
    <output name="thickness_out" type="float" nodename="thickness" />
    <output name="attenuation_color_out" type="color3" nodename="attenuation_color" />
    <output name="sheen_color_out" type="color3" nodename="sheen_color" />
    <output name="sheen_roughness_out" type="float" nodename="sheen_roughness" />
    <output name="clearcoat_out" type="float" nodename="clearcoat" />
    <output name="clearcoat_roughness_out" type="float" nodename="clearcoat_roughness" />
    <output name="emissive_out" type="color3" nodename="emissive" />

  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <nodedef name="ND_standard_surface_to_open_pbr_surface" node="standard_surface_to_open_pbr_surface" nodegroup="translation">
    <input name="base" type="float" value="0.8" />
    <input name="base_color" type="color3" value="1.0, 1.0, 1.0" />
    <input name="diffuse_roughness" type="float" value="0" />
    <input name="metalness" type="float" value="0" />

    <input name="specular" type="float" value="1" />
    <input name="specular_color" type="color3" value="1, 1, 1" />
    <input name="specular_roughness" type="float" value="0.2" />
    <input name="specular_IOR" type="float" value="1.5" />
    <input name="specular_anisotropy" type="float" value="0" />

    <input name="transmission" type="float" value="0" />
    <input name="transmission_color" type="color3" value="1, 1, 1"/>
    <input name="transmission_depth" type="float" value="0" />
    <input name="transmission_scatter" type="color3" value="0, 0, 0" />
    <input name="transmission_scatter_anisotropy" type="float" value="0" />
    <input name="transmission_dispersion" type="float" value="0" />
    
    <input name="subsurface" type="float" value="0" uimin="0.0" />
    <input name="subsurface_color" type="color3" value="1, 1, 1" />
    <input name="subsurface_radius" type="color3" value="1, 1, 1" />
    <input name="subsurface_scale" type="float" value="1" />
    <input name="subsurface_anisotropy" type="float" value="0" />

    <input name="sheen" type="float" value="0" uimin="0.0" />
    <input name="sheen_color" type="color3" value="1, 1, 1" />
    <input name="sheen_roughness" type="float" value="0.3" />

    <input name="coat" type="float" value="0" />
    <input name="coat_color" type="color3" value="1, 1, 1" />
    <input name="coat_roughness" type="float" value="0.1" />
    <input name="coat_anisotropy" type="float" value="0.0" />
    <input name="coat_IOR" type="float" value="1.5" />
    <input name="coat_affect_roughness" type="float" value="0" />
    
    <input name="thin_film_thickness" type="float" value="0" />
    <input name="thin_film_IOR" type="float" value="1.5" />

    <input name="emission" type="float" value="0" />
    <input name="emission_color" type="color3" value="1, 1, 1" />

    <input name="opacity" type="color3" value="1, 1, 1" />
    <input name="thin_walled" type="boolean" value="false" />

    <!--Outputs-->
    <output name="base_weight_out" type="float" />
    <output name="base_color_out" type="color3" />
    <output name="base_diffuse_roughness_out" type="float" />
    <output name="base_metalness_out" type="float" />

    <output name="specular_weight_out" type="float" />
    <output name="specular_color_out" type="color3" />
    <output name="specular_roughness_out" type="float" />
    <output name="specular_ior_out" type="float" />
    <output name="specular_roughness_anisotropy_out" type="float" />

    <output name="transmission_weight_out" type="float" />
    <output name="transmission_color_out" type="color3" />
    <output name="transmission_depth_out" type="float" />
    <output name="transmission_scatter_out" type="color3" />
    <output name="transmission_scatter_anisotropy_out" type="float" />
    <output name="transmission_dispersion_scale_out" type="float" />
    
    <output name="subsurface_weight_out" type="float" />
    <output name="subsurface_color_out" type="color3" />
    <output name="subsurface_radius_out" type="float" />
    <output name="subsurface_radius_scale_out" type="color3" />
    <output name="subsurface_scatter_anisotropy_out" type="float" />

    <output name="fuzz_weight_out" type="float" />
    <output name="fuzz_color_out" type="color3" />
    <output name="fuzz_roughness_out" type="float" />

    <output name="coat_weight_out" type="float" />
    <output name="coat_color_out" type="color3" />
    <output name="coat_roughness_out" type="float" />
    <output name="coat_roughness_anisotropy_out" type="float" />
    <output name="coat_ior_out" type="float" />
    <output name="coat_darkening_out" type="float" />

    <output name="thin_film_weight_out" type="float" />
    <output name="thin_film_thickness_out" type="float" />
    <output name="thin_film_ior_out" type="float" />

    <output name="emission_luminance_out" type="float" />
    <output name="emission_color_out" type="color3" />

    <output name="geometry_opacity_out" type="float" />
    <output name="geometry_thin_walled_out" type="boolean" />
  </nodedef>

  <nodegraph name="NG_standard_surface_to_open_pbr_surface" nodedef="ND_standard_surface_to_open_pbr_surface">

    <!--Base-->
    <dot name="baseWeight" type="float">
      <input name="in" type="float" interfacename="base" />
    </dot>
    <mix name="coatAttenuation" type="color3">
      <input name="fg" type="color3" interfacename="coat_color" />
      <input name="bg" type="color3" value="1.0, 1.0, 1.0" />
      <input name="mix" type="float" interfacename="coat" />
    </mix>
    <multiply name="baseColor" type="color3">
      <input name="in1" type="color3" interfacename="base_color" />
      <input name="in2" type="color3" nodename="coatAttenuation" />
    </multiply>
    <dot name="baseDiffuseRoughness" type="float">
      <input name="in" type="float" interfacename="diffuse_roughness" />
    </dot>
    <dot name="baseMetalness" type="float">
      <input name="in" type="float" interfacename="metalness" />
    </dot>

    <!--Specular-->
    <!--In OpenPBR Surface, specular_weight controls the strength of the metallic layer, while it Standard Surface it has no effect on the metallic layer.-->
    <ifgreater name="specWeight" type="float">
      <input name="value1" type="float" interfacename="metalness" />
      <input name="value2" type="float" value="0.0" />
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="specular" />
    </ifgreater>
    <convert name="specVector" type="vector3">
      <input name="in" type="color3" interfacename="specular_color" />
    </convert>
    <dotproduct name="dotProd" type="float">
      <input name="in1" type="vector3" nodename="specVector" />
      <input name="in2" type="vector3" value="1.0, 1.0, 1.0" />
    </dotproduct>
    <!--Intentionally ignoring the original specular_color input for metals, since the translation between these concepts will take more thought.-->
    <ifequal name="specColor" type="color3">
      <input name="value1" type="float" value="0.0"  />
      <input name="value2" type="float" nodename="dotProd" />
      <input name="in1" type="color3" value="1.0, 1.0, 1.0" />
      <input name="in2" type="color3" interfacename="specular_color" />
    </ifequal>
    <dot name="specRoughness" type="float">
      <input name="in" type="float" interfacename="specular_roughness" />
    </dot>
    <dot name="specIOR" type="float">
      <input name="in" type="float" interfacename="specular_IOR" />
    </dot>
    <dot name="specRoughnessAnisotropy" type="float">
      <input name="in" type="float" interfacename="specular_anisotropy" />
    </dot>

    <!--Transmission-->
    <dot name="transmissionWeight" type="float">
      <input name="in" type="float" interfacename="transmission" />
    </dot>
    <dot name="transmissionColor" type="color3">
      <input name="in" type="color3" interfacename="transmission_color" />
    </dot>
    <dot name="transmissionDepth" type="float">
      <input name="in" type="float" interfacename="transmission_depth" />
    </dot>
    <dot name="transmissionScatter" type="color3">
      <input name="in" type="color3" interfacename="transmission_scatter" />
    </dot>
    <dot name="transmissionScatterAnisotropy" type="float">
      <input name="in" type="float" interfacename="transmission_scatter_anisotropy" />
    </dot>
    <dot name="transmissionDispersion" type="float">
      <input name="in" type="float" interfacename="transmission_dispersion" />
    </dot>

    <!--Subsurface-->
    <dot name="subsurfaceWeight" type="float">
      <input name="in" type="float" interfacename="subsurface" />
    </dot>
    <dot name="subsurfaceColor" type="color3">
      <input name="in" type="color3" interfacename="subsurface_color" />
    </dot>
    <dot name="subsurfaceRadius" type="float">
      <input name="in" type="float" interfacename="subsurface_scale" />
    </dot>
    <dot name="subsurfaceRadiusScale" type="color3">
      <input name="in" type="color3" interfacename="subsurface_radius" />
    </dot>
    <dot name="subsurfaceAnisotropy" type="float">
      <input name="in" type="float" interfacename="subsurface_anisotropy" />
    </dot>

    <!--Fuzz-->
    <dot name="fuzzWeight" type="float">
      <input name="in" type="float" interfacename="sheen" />
    </dot>
    <dot name="fuzzColor" type="color3">
      <input name="in" type="color3" interfacename="sheen_color" />
    </dot>
    <!--Fuzz roughness translation is approximated by eye, and could potentially be improved with an analytic or ML-based solution.-->
    <power name="fuzzRoughness" type="float">
      <input name="in1" type="float" interfacename="sheen_roughness" />
      <input name="in2" type="float" value="0.4" />
    </power>

    <!--Coat-->
    <!--Standard Surface takes the approach of tinting the surface underneath by the color of this clearcoat, and that technique is how artists often create colored metals in Standard Surface. If this approach was taken, then coat_weight is set to 0 so that the color is not added redundantly.-->
    <multiply name="coatMetallic" type="float">
      <input name="in1" type="float" interfacename="coat" />
      <input name="in2" type="float" interfacename="metalness" />
    </multiply>
    <ifgreater name="coatWeight" type="float">
      <input name="value1" type="float" nodename="coatMetallic" />
      <input name="value2" type="float" value="0.0" />
      <input name="in1" type="float" value="0.0" />
      <input name="in2" type="float" interfacename="coat" />
    </ifgreater>
    <dot name="coatColor" type="color3">
      <input name="in" type="color3" interfacename="coat_color" />
    </dot>
    <dot name="coatRoughness" type="float">
      <input name="in" type="float" interfacename="coat_roughness" />
    </dot>
    <dot name="coatAnisotropy" type="float">
      <input name="in" type="float" interfacename="coat_anisotropy" />
    </dot>
    <dot name="coatIOR" type="float">
      <input name="in" type="float" interfacename="coat_IOR" />
    </dot>
    <dot name="coatDarkening" type="float">
      <input name="in" type="float" interfacename="coat_affect_roughness" />
    </dot>

    <!--ThinFilm-->
    <multiply name="thinFilmThicknessConversion" type="float">
      <input name="in1" type="float" interfacename="thin_film_thickness" />
      <input name="in2" type="float" value="0.001" />
    </multiply>
    <ifgreater name="thinFilmWeight" type="float">
      <input name="value1" type="float" nodename="thinFilmThicknessConversion" />
      <input name="value2" type="float" value="0.0" />
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" value="0.0" />
    </ifgreater>
    <dot name="thinFilmThickness" type="float">
      <input name="in" type="float" nodename="thinFilmThicknessConversion" />
    </dot>
    <dot name="thinFilmIOR" type="float">
      <input name="in" type="float" interfacename="thin_film_IOR" />
    </dot>

    <!--Emission-->
    <dot name="emissionLuminance" type="float">
      <input name="in" type="float" interfacename="emission" />
    </dot>
    <dot name="emissionColor" type="color3">
      <input name="in" type="color3" interfacename="emission_color" />
    </dot>

    <!--Geometry-->
    <extract name="geometryOpacity" type="float">
      <input name="in" type="color3" interfacename="opacity" />
      <input name="index" type="integer" value="0" />
    </extract>
    <dot name="geometryThinWalled" type="boolean">
      <input name="in" type="boolean" interfacename="thin_walled" />
    </dot>

    <!--Outputs-->
    <output name="base_weight_out" type="float" nodename="baseWeight" />
    <output name="base_color_out" type="color3" nodename="baseColor" />
    <output name="base_diffuse_roughness_out" type="float" nodename="baseDiffuseRoughness" />
    <output name="base_metalness_out" type="float" nodename="baseMetalness" />

    <output name="specular_weight_out" type="float" nodename="specWeight" />
    <output name="specular_color_out" type="color3" nodename="specColor" />
    <output name="specular_roughness_out" type="float" nodename="specRoughness" />
    <output name="specular_ior_out" type="float" nodename="specIOR" />
    <output name="specular_roughness_anisotropy_out" type="float" nodename="specRoughnessAnisotropy" />
    
    <output name="transmission_weight_out" type="float" nodename="transmissionWeight" />
    <output name="transmission_color_out" type="color3" nodename="transmissionColor" />
    <output name="transmission_depth_out" type="float" nodename="transmissionDepth" />
    <output name="transmission_scatter_out" type="color3" nodename="transmissionScatter" />
    <output name="transmission_scatter_anisotropy_out" type="float" nodename="transmissionScatterAnisotropy" />
    <output name="transmission_dispersion_scale_out" type="float" nodename="transmissionDispersion" />

    <output name="subsurface_weight_out" type="float" nodename="subsurfaceWeight" />
    <output name="subsurface_color_out" type="color3" nodename="subsurfaceColor" />
    <output name="subsurface_radius_out" type="float" nodename="subsurfaceRadius" />
    <output name="subsurface_radius_scale_out" type="color3" nodename="subsurfaceRadiusScale" />
    <output name="subsurface_scatter_anisotropy_out" type="float" nodename="subsurfaceAnisotropy" />

    <output name="fuzz_weight_out" type="float" nodename="fuzzWeight" />
    <output name="fuzz_color_out" type="color3" nodename="fuzzColor" />
    <output name="fuzz_roughness_out" type="float" nodename="fuzzRoughness" />

    <output name="coat_weight_out" type="float" nodename="coatWeight" />
    <output name="coat_color_out" type="color3" nodename="coatColor" />
    <output name="coat_roughness_out" type="float" nodename="coatRoughness" />
    <output name="coat_roughness_anisotropy_out" type="float" nodename="coatAnisotropy" />
    <output name="coat_ior_out" type="float" nodename="coatIOR" />
    <output name="coat_darkening_out" type="float" nodename="coatDarkening" />

    <output name="thin_film_weight_out" type="float" nodename="thinFilmWeight" />
    <output name="thin_film_thickness_out" type="float" nodename="thinFilmThickness" />
    <output name="thin_film_ior_out" type="float" nodename="thinFilmIOR" />

    <output name="emission_luminance_out" type="float" nodename="emissionLuminance" />
    <output name="emission_color_out" type="color3" nodename="emissionColor" />

    <output name="geometry_opacity_out" type="float" nodename="geometryOpacity" />
    <output name="geometry_thin_walled_out" type="boolean" nodename="geometryThinWalled" />
  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39">

  <nodedef name="ND_open_pbr_surface_to_standard_surface" node="open_pbr_surface_to_standard_surface" nodegroup="translation">
    <input name="base_weight" type="float" value="1.0" />
    <input name="base_color" type="color3" value="0.8, 0.8, 0.8" />
    <input name="base_diffuse_roughness" type="float" value="0.0" />
    <input name="base_metalness" type="float" value="0.0" />

    <input name="specular_weight" type="float" value="1.0" />
    <input name="specular_color" type="color3" value="1, 1, 1" />
    <input name="specular_roughness" type="float" value="0.3" />
    <input name="specular_ior" type="float" value="1.5" />
    <input name="specular_roughness_anisotropy" type="float" value="0.0" />

    <input name="transmission_weight" type="float" value="0.0" />
    <input name="transmission_color" type="color3" value="1, 1, 1" />
    <input name="transmission_depth" type="float" value="0.0" />
    <input name="transmission_scatter" type="color3" value="0, 0, 0" />
    <input name="transmission_scatter_anisotropy" type="float" value="0.0" />
    <input name="transmission_dispersion_scale" type="float" value="0.0" />

    <input name="subsurface_weight" type="float" value="0" />
    <input name="subsurface_color" type="color3" value="0.8, 0.8, 0.8" />
    <input name="subsurface_radius" type="float" value="1.0" />
    <input name="subsurface_radius_scale" type="color3" value="1.0, 0.5, 0.25" />
    <input name="subsurface_scatter_anisotropy" type="float" value="0.0" />

    <input name="fuzz_weight" type="float" value="0.0" />
    <input name="fuzz_color" type="color3" value="1, 1, 1" />
    <input name="fuzz_roughness" type="float" value="0.5" />

    <input name="coat_weight" type="float" value="0.0" />
    <input name="coat_color" type="color3" value="1, 1, 1" />
    <input name="coat_roughness" type="float" value="0.0" />
    <input name="coat_roughness_anisotropy" type="float" value="0.0" />
    <input name="coat_ior" type="float" value="1.6" />
    <input name="coat_darkening" type="float" value="1.0" />

    <input name="thin_film_weight" type="float" value="0" />
    <input name="thin_film_thickness" type="float" value="0.5" />
    <input name="thin_film_ior" type="float" value="1.4" />

    <input name="emission_luminance" type="float" value="0.0" />
    <input name="emission_color" type="color3" value="1, 1, 1" />

    <input name="geometry_opacity" type="float" value="1" />
    <input name="geometry_thin_walled" type="boolean" value="false" />

    <!--Outputs-->
    <output name="base_out" type="float" />
    <output name="base_color_out" type="color3" />
    <output name="diffuse_roughness_out" type="float" />
    <output name="metalness_out" type="float" />

    <output name="specular_out" type="float"/>
    <output name="specular_color_out" type="color3" />
    <output name="specular_roughness_out" type="float" />
    <output name="specular_IOR_out" type="float" />
    <output name="specular_anisotropy_out" type="float" />

    <output name="transmission_out" type="float" />
    <output name="transmission_color_out" type="color3" />
    <output name="transmission_depth_out" type="float" />
    <output name="transmission_scatter_out" type="color3" />
    <output name="transmission_scatter_anisotropy_out" type="float" />
    <output name="transmission_dispersion_out" type="float" />

    <output name="subsurface_out" type="float" />
    <output name="subsurface_color_out" type="color3" />
    <output name="subsurface_radius_out" type="color3" />
    <output name="subsurface_scale_out" type="float" />
    <output name="subsurface_anisotropy_out" type="float" />

    <output name="sheen_out" type="float" />
    <output name="sheen_color_out" type="color3" />
    <output name="sheen_roughness_out" type="float" />

    <output name="coat_out" type="float" />
    <output name="coat_color_out" type="color3" />
    <output name="coat_roughness_out" type="float" />
    <output name="coat_anisotropy_out" type="float" />
    <output name="coat_IOR_out" type="float" />
    <output name="coat_affect_roughness_out" type="float" />

    <output name="thin_film_thickness_out" type="float" />
    <output name="thin_film_IOR_out" type="float" />

    <output name="emission_out" type="float" />
    <output name="emission_color_out" type="color3" />

    <output name="opacity_out" type="color3" />
    <output name="thin_walled_out" type="boolean" />
  </nodedef>

  <nodegraph name="NG_open_pbr_surface_to_standard_surface" nodedef="ND_open_pbr_surface_to_standard_surface">

    <!-- Coat Darkening -->
    <subtract name="coat_ior_minus_one" type="float">
      <input name="in1" type="float" interfacename="coat_ior" />
      <input name="in2" type="float" value="1.0" />
    </subtract>
    <add name="coat_ior_plus_one" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" interfacename="coat_ior" />
    </add>
    <divide name="coat_ior_to_F0_sqrt" type="float">
      <input name="in1" type="float" nodename="coat_ior_minus_one" />
      <input name="in2" type="float" nodename="coat_ior_plus_one" />
    </divide>
    <multiply name="coat_ior_to_F0" type="float">
      <input name="in1" type="float" nodename="coat_ior_to_F0_sqrt" />
      <input name="in2" type="float" nodename="coat_ior_to_F0_sqrt" />
    </multiply>
    <!-- approximate Kcoat, "internal diffuse reflection coefficient" of coat  -->
    <subtract name="one_minus_coat_F0" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="coat_ior_to_F0" />
    </subtract>
    <multiply name="coat_ior_sqr" type="float">
      <input name="in1" type="float" interfacename="coat_ior" />
      <input name="in2" type="float" interfacename="coat_ior" />
    </multiply>
    <divide name="one_minus_coat_F0_over_eta2" type="float">
      <input name="in1" type="float" nodename="one_minus_coat_F0" />
      <input name="in2" type="float" nodename="coat_ior_sqr" />
    </divide>
    <subtract name="Kcoat" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="one_minus_coat_F0_over_eta2" />
    </subtract>
    <!-- approximate base metal albedo estimate, Emetal  -->
    <multiply name="Emetal" type="color3">
      <input name="in1" type="color3" interfacename="base_color" />
      <input name="in2" type="float" interfacename="specular_weight" />
    </multiply>
    <!-- approximate base dielectric albedo estimate, Edielectric  -->
    <mix name="Edielectric" type="color3">
      <input name="fg" type="color3" interfacename="subsurface_color" />
      <input name="bg" type="color3" interfacename="base_color" />
      <input name="mix" type="float" interfacename="subsurface_weight" />
    </mix>
    <!-- thus calculate overall base albedo estimate approximation, Ebase  -->
    <mix name="Ebase" type="color3">
      <input name="fg" type="color3" nodename="Emetal" />
      <input name="bg" type="color3" nodename="Edielectric" />
      <input name="mix" type="float" interfacename="base_metalness" />
    </mix>
    <!-- final base darkening factor due to coat:  base_darkening = (1 - Kcoat) / (1 - Ebase*Kcoat)  -->
    <multiply name="Ebase_Kcoat" type="color3">
      <input name="in1" type="color3" nodename="Ebase" />
      <input name="in2" type="float" nodename="Kcoat" />
    </multiply>
    <subtract name="one_minus_Kcoat" type="float">
      <input name="in1" type="float" value="1.0" />
      <input name="in2" type="float" nodename="Kcoat" />
    </subtract>
    <subtract name="one_minus_Ebase_Kcoat" type="color3">
      <input name="in1" type="color3" value="1.0, 1.0, 1.0" />
      <input name="in2" type="color3" nodename="Ebase_Kcoat" />
    </subtract>
    <convert name="one_minus_Kcoat_color" type="color3">
      <input name="in" type="float" nodename="one_minus_Kcoat" />
    </convert>
    <divide name="base_darkening" type="color3">
      <input name="in1" type="color3" nodename="one_minus_Kcoat_color" />
      <input name="in2" type="color3" nodename="one_minus_Ebase_Kcoat" />
    </divide>
    <multiply name="coat_weight_times_coat_darkening" type="float">
      <input name="in1" type="float" interfacename="coat_weight" />
      <input name="in2" type="float" interfacename="coat_darkening" />
    </multiply>
    <mix name="modulated_base_darkening" type="color3">
      <input name="fg" type="color3" nodename="base_darkening" />
      <input name="bg" type="color3" value="1.0, 1.0, 1.0" />
      <input name="mix" type="float" nodename="coat_weight_times_coat_darkening" />
    </mix>

    <!--Base-->
    <dot name="base" type="float">
      <input name="in" type="float" interfacename="base_weight" />
    </dot>
    <dot name="diffuseRoughness" type="float">
      <input name="in" type="float" interfacename="base_diffuse_roughness" />
    </dot>
    <dot name="metalness" type="float">
      <input name="in" type="float" interfacename="base_metalness" />
    </dot>
    <multiply name="baseColor" type="color3">
      <input name="in1" type="color3" interfacename="base_color" />
      <input name="in2" type="color3" nodename="modulated_base_darkening" />
    </multiply>

    <!--Specular-->
    <dot name="spec" type="float">
      <input name="in" type="float" interfacename="specular_weight" />
    </dot>
    <dot name="specColor" type="color3">
      <input name="in" type="color3" interfacename="specular_color" />
    </dot>
    <!--Allows override of specular_roughness by coat_roughness for materials with coat, but not for simpler materials that don't leverage coat at all.-->
    <mix name="specRoughness" type="float">
      <input name="fg" type="float" interfacename="coat_roughness" />
      <input name="bg" type="float" interfacename="specular_roughness" />
      <input name="mix" type="float" interfacename="coat_weight" />
    </mix>
    <dot name="specIOR" type="float">
      <input name="in" type="float" interfacename="specular_ior" />
    </dot>
    <!--The logic for anisotropic specular is noticeably different between Standard Surface and OpenPBR, so the translation between these concepts will take more thought.-->
    <dot name="specAnisotropy" type="float">
      <input name="in" type="float" interfacename="specular_roughness_anisotropy" />
    </dot>

    <!--Transmission-->
    <dot name="transmission" type="float">
      <input name="in" type="float" interfacename="transmission_weight" />
    </dot>
    <dot name="transmissionColor" type="color3">
      <input name="in" type="color3" interfacename="transmission_color" />
    </dot>
    <dot name="transmissionDepth" type="float">
      <input name="in" type="float" interfacename="transmission_depth" />
    </dot>
    <dot name="transmissionScatter" type="color3">
      <input name="in" type="color3" interfacename="transmission_scatter" />
    </dot>
    <dot name="transmissionScatterAnisotropy" type="float">
      <input name="in" type="float" interfacename="transmission_scatter_anisotropy" />
    </dot>
    <dot name="transmissionDispersion" type="float">
      <input name="in" type="float" interfacename="transmission_dispersion_scale" />
    </dot>

    <!--Subsurface-->
    <dot name="subsurface" type="float">
      <input name="in" type="float" interfacename="subsurface_weight" />
    </dot>
    <multiply name="subsurfaceColor" type="color3">
      <input name="in1" type="color3" interfacename="subsurface_color" />
      <input name="in2" type="color3" nodename="modulated_base_darkening" />
    </multiply>
    <dot name="subsurfaceScale" type="float">
      <input name="in" type="float" interfacename="subsurface_radius" />
    </dot>
    <dot name="subsurfaceRadius" type="color3">
      <input name="in" type="color3" interfacename="subsurface_radius_scale" />
    </dot>
    <dot name="subsurfaceAnisotropy" type="float">
      <input name="in" type="float" interfacename="subsurface_scatter_anisotropy" />
    </dot>

    <!--Sheen-->
    <dot name="sheen" type="float">
      <input name="in" type="float" interfacename="fuzz_weight" />
    </dot>
    <dot name="sheenColor" type="color3">
      <input name="in" type="color3" interfacename="fuzz_color" />
    </dot>
    <!--Sheen roughness translation is approximated by eye, and could potentially be improved with an analytic or ML-based solution.-->
    <power name="sheenRoughness" type="float">
      <input name="in1" type="float" interfacename="fuzz_roughness" />
      <input name="in2" type="float" value="2.5" />
    </power>

    <!--Coat-->
    <dot name="coat" type="float">
      <input name="in" type="float" interfacename="coat_weight" />
    </dot>
    <dot name="coatColor" type="color3">
      <input name="in" type="color3" interfacename="coat_color" />
    </dot>
    <dot name="coatRoughness" type="float">
      <input name="in" type="float" interfacename="coat_roughness" />
    </dot>
    <dot name="coatAnisotropy" type="float">
      <input name="in" type="float" interfacename="coat_roughness_anisotropy" />
    </dot>
    <dot name="coatIOR" type="float">
      <input name="in" type="float" interfacename="coat_ior" />
    </dot>
    <constant name="coatAffectRoughness" type="float">
      <input name="value" type="float" value="1.0" />
    </constant>

    <!--ThinFilm-->
    <multiply name="thinFilmThicknessConversion" type="float">
      <input name="in1" type="float" interfacename="thin_film_thickness" />
      <input name="in2" type="float" value="1000" />
    </multiply>
    <ifgreater name="thinFilmThickness" type="float">
      <input name="value1" type="float" interfacename="thin_film_weight" />
      <input name="value2" type="float" value="0.0" />
      <input name="in1" type="float" nodename="thinFilmThicknessConversion" />
      <input name="in2" type="float" value="0.0" />
    </ifgreater>
    <dot name="thinFilmIOR" type="float">
      <input name="in" type="float" interfacename="thin_film_ior" />
    </dot>

    <!--Emission-->
    <dot name="emission" type="float">
      <input name="in" type="float" interfacename="emission_luminance" />
    </dot>
    <dot name="emissionColor" type="color3">
      <input name="in" type="color3" interfacename="emission_color" />
    </dot>

    <!--Geometry-->
    <convert name="geometryOpacity" type="color3">
      <input name="in" type="float" interfacename="geometry_opacity" />
    </convert>
    <dot name="geometryThinWalled" type="boolean">
      <input name="in" type="boolean" interfacename="geometry_thin_walled" />
    </dot>

    <!--Outputs-->
    <output name="base_out" type="float" nodename="base" />
    <output name="base_color_out" type="color3" nodename="baseColor" />
    <output name="diffuse_roughness_out" type="float" nodename="diffuseRoughness" />
    <output name="metalness_out" type="float" nodename="metalness" />

    <output name="specular_out" type="float" nodename="spec" />
    <output name="specular_color_out" type="color3" nodename="specColor" />
    <output name="specular_roughness_out" type="float" nodename="specRoughness" />
    <output name="specular_IOR_out" type="float" nodename="specIOR" />
    <output name="specular_anisotropy_out" type="float" nodename="specAnisotropy" />

    <output name="transmission_out" type="float" nodename="transmission" />
    <output name="transmission_color_out" type="color3" nodename="transmissionColor" />
    <output name="transmission_depth_out" type="float" nodename="transmissionDepth" />
    <output name="transmission_scatter_out" type="color3" nodename="transmissionScatter" />
    <output name="transmission_scatter_anisotropy_out" type="float" nodename="transmissionScatterAnisotropy" />
    <output name="transmission_dispersion_out" type="float" nodename="transmissionDispersion" />

    <output name="subsurface_out" type="float" nodename="subsurface" />
    <output name="subsurface_color_out" type="color3" nodename="subsurfaceColor" />
    <output name="subsurface_radius_out" type="color3" nodename="subsurfaceRadius" />
    <output name="subsurface_scale_out" type="float" nodename="subsurfaceScale" />
    <output name="subsurface_anisotropy_out" type="float" nodename="subsurfaceAnisotropy" />

    <output name="sheen_out" type="float" nodename="sheen" />
    <output name="sheen_color_out" type="color3" nodename="sheenColor" />
    <output name="sheen_roughness_out" type="float" nodename="sheenRoughness" />

    <output name="coat_out" type="float" nodename="coat" />
    <output name="coat_color_out" type="color3" nodename="coatColor" />
    <output name="coat_roughness_out" type="float" nodename="coatRoughness" />
    <output name="coat_anisotropy_out" type="float" nodename="coatAnisotropy" />
    <output name="coat_IOR_out" type="float" nodename="coatIOR" />
    <output name="coat_affect_roughness_out" type="float" nodename="coatAffectRoughness" />

    <output name="thin_film_thickness_out" type="float" nodename="thinFilmThickness" />
    <output name="thin_film_IOR_out" type="float" nodename="thinFilmIOR" />

    <output name="emission_out" type="float" nodename="emission" />
    <output name="emission_color_out" type="color3" nodename="emissionColor" />

    <output name="opacity_out" type="color3" nodename="geometryOpacity" />
    <output name="thin_walled_out" type="boolean" nodename="geometryThinWalled" />
  </nodegraph>
</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations of the default color transforms in MaterialX.
  -->

  <nodedef name="ND_g18_rec709_to_lin_rec709_color3" node="g18_rec709_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_g18_rec709_to_lin_rec709_color4" node="g18_rec709_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_g22_rec709_to_lin_rec709_color3" node="g22_rec709_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_g22_rec709_to_lin_rec709_color4" node="g22_rec709_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_rec709_display_to_lin_rec709_color3" node="rec709_display_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_rec709_display_to_lin_rec709_color4" node="rec709_display_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_acescg_to_lin_rec709_color3" node="acescg_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_acescg_to_lin_rec709_color4" node="acescg_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_g22_ap1_to_lin_rec709_color3" node="g22_ap1_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_g22_ap1_to_lin_rec709_color4" node="g22_ap1_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_srgb_texture_to_lin_rec709_color3" node="srgb_texture_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_srgb_texture_to_lin_rec709_color4" node="srgb_texture_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_lin_adobergb_to_lin_rec709_color3" node="lin_adobergb_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_lin_adobergb_to_lin_rec709_color4" node="lin_adobergb_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_adobergb_to_lin_rec709_color3" node="adobergb_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_adobergb_to_lin_rec709_color4" node="adobergb_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_srgb_displayp3_to_lin_rec709_color3" node="srgb_displayp3_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_srgb_displayp3_to_lin_rec709_color4" node="srgb_displayp3_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

  <nodedef name="ND_lin_displayp3_to_lin_rec709_color3" node="lin_displayp3_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color3" value="0.0, 0.0, 0.0" />
    <output name="out" type="color3" />
  </nodedef>

  <nodedef name="ND_lin_displayp3_to_lin_rec709_color4" node="lin_displayp3_to_lin_rec709" nodegroup="colortransform">
    <input name="in" type="color4" value="0.0, 0.0, 0.0, 1.0" />
    <output name="out" type="color4" />
  </nodedef>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Nodegraph implementations for the default color transforms in MaterialX.
  -->

  <nodegraph name="NG_g18_rec709_to_lin_rec709_color3" nodedef="ND_g18_rec709_to_lin_rec709_color3">
    <max name="max" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="float" value="0" />
    </max>
    <power name="gamma" type="color3">
      <input name="in1" type="color3" nodename="max" />
      <input name="in2" type="float" value="1.8" />
    </power>
    <output name="out" type="color3" nodename="gamma" />
  </nodegraph>

  <nodegraph name="NG_g18_rec709_to_lin_rec709_color4" nodedef="ND_g18_rec709_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <g18_rec709_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </g18_rec709_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_g22_rec709_to_lin_rec709_color3" nodedef="ND_g22_rec709_to_lin_rec709_color3">
    <max name="max" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="float" value="0" />
    </max>
    <power name="gamma" type="color3">
      <input name="in1" type="color3" nodename="max" />
      <input name="in2" type="float" value="2.2" />
    </power>
    <output name="out" type="color3" nodename="gamma" />
  </nodegraph>

  <nodegraph name="NG_g22_rec709_to_lin_rec709_color4" nodedef="ND_g22_rec709_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <g22_rec709_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </g22_rec709_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_rec709_display_to_lin_rec709_color3" nodedef="ND_rec709_display_to_lin_rec709_color3">
    <max name="max" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="float" value="0" />
    </max>
    <power name="gamma" type="color3">
      <input name="in1" type="color3" nodename="max" />
      <input name="in2" type="float" value="2.4" />
    </power>
    <output name="out" type="color3" nodename="gamma" />
  </nodegraph>

  <nodegraph name="NG_rec709_display_to_lin_rec709_color4" nodedef="ND_rec709_display_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <rec709_display_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </rec709_display_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_acescg_to_lin_rec709_color3" nodedef="ND_acescg_to_lin_rec709_color3">
    <constant name="mat" type="matrix33">
      <input name="value" type="matrix33" value="1.705050992658, -0.130256417507, -0.024003356805, -0.621792120657,  1.140804736575, -0.128968976065, -0.083258872001, -0.010548319068, 1.15297233287" />
    </constant>
    <convert name="asVec" type="vector3">
      <input name="in" type="color3" interfacename="in" />
    </convert>
    <transformmatrix name="transform" type="vector3">
      <input name="in" type="vector3" nodename="asVec" />
      <input name="mat" type="matrix33" nodename="mat" />
    </transformmatrix>
    <convert name="asColor" type="color3">
      <input name="in" type="vector3" nodename="transform" />
    </convert>
    <output name="out" type="color3" nodename="asColor" />
  </nodegraph>

  <nodegraph name="NG_acescg_to_lin_rec709_color4" nodedef="ND_acescg_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <acescg_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </acescg_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_g22_ap1_to_lin_rec709_color3" nodedef="ND_g22_ap1_to_lin_rec709_color3">
    <max name="max" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="float" value="0" />
    </max>
    <power name="gamma" type="color3">
      <input name="in1" type="color3" nodename="max" />
      <input name="in2" type="float" value="2.2" />
    </power>
    <acescg_to_lin_rec709 name="rec709" type="color3">
      <input name="in" type="color3" nodename="gamma" />
    </acescg_to_lin_rec709>
    <output name="out" type="color3" nodename="rec709" />
  </nodegraph>

  <nodegraph name="NG_g22_ap1_to_lin_rec709_color4" nodedef="ND_g22_ap1_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <g22_ap1_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </g22_ap1_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_srgb_texture_to_lin_rec709_color3" nodedef="ND_srgb_texture_to_lin_rec709_color3">
    <constant name="threshold" type="float">
      <input name="value" type="float" value="0.04045" />
    </constant>
    <separate3 name="colorSeparate" type="multioutput">
      <input name="in" type="color3" interfacename="in" />
    </separate3>
    <ifgreater name="isAboveR" type="float">
      <input name="value1" type="float" nodename="colorSeparate" output="outr" />
      <input name="value2" type="float" nodename="threshold" />
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" value="0" />
    </ifgreater>
    <ifgreater name="isAboveG" type="float">
      <input name="value1" type="float" nodename="colorSeparate" output="outg" />
      <input name="value2" type="float" nodename="threshold" />
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" value="0" />
    </ifgreater>
    <ifgreater name="isAboveB" type="float">
      <input name="value1" type="float" nodename="colorSeparate" output="outb" />
      <input name="value2" type="float" nodename="threshold" />
      <input name="in1" type="float" value="1" />
      <input name="in2" type="float" value="0" />
    </ifgreater>
    <combine3 name="isAbove" type="color3">
      <input name="in1" type="float" nodename="isAboveR" />
      <input name="in2" type="float" nodename="isAboveG" />
      <input name="in3" type="float" nodename="isAboveB" />
    </combine3>
    <divide name="linSeg" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="float" value="12.92" />
    </divide>
    <add name="bias" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="float" value="0.055" />
    </add>
    <max name="max" type="color3">
      <input name="in1" type="color3" nodename="bias" />
      <input name="in2" type="float" value="0" />
    </max>
    <divide name="scale" type="color3">
      <input name="in1" type="color3" nodename="max" />
      <input name="in2" type="float" value="1.055" />
    </divide>
    <power name="powSeg" type="color3">
      <input name="in1" type="color3" nodename="scale" />
      <input name="in2" type="float" value="2.4" />
    </power>
    <mix name="mix" type="color3">
      <input name="bg" type="color3" nodename="linSeg" />
      <input name="fg" type="color3" nodename="powSeg" />
      <input name="mix" type="color3" nodename="isAbove" />
    </mix>
    <output name="out" type="color3" nodename="mix" />
  </nodegraph>

  <nodegraph name="NG_srgb_texture_to_lin_rec709_color4" nodedef="ND_srgb_texture_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <srgb_texture_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </srgb_texture_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_lin_adobergb_to_lin_rec709_color3" nodedef="ND_lin_adobergb_to_lin_rec709_color3">
    <constant name="mat" type="matrix33">
      <input name="value" type="matrix33" value="1.39835574e+00, -2.50233861e-16,  2.77555756e-17, -3.98355744e-01,  1.00000000e+00, -4.29289893e-02, 0.00000000e+00,  0.00000000e+00,  1.04292899e+00" />
    </constant>
    <convert name="asVec" type="vector3">
      <input name="in" type="color3" interfacename="in" />
    </convert>
    <transformmatrix name="transform" type="vector3">
      <input name="in" type="vector3" nodename="asVec" />
      <input name="mat" type="matrix33" nodename="mat" />
    </transformmatrix>
    <convert name="asColor" type="color3">
      <input name="in" type="vector3" nodename="transform" />
    </convert>
    <output name="out" type="color3" nodename="asColor" />
  </nodegraph>

  <nodegraph name="NG_lin_adobergb_to_lin_rec709_color4" nodedef="ND_lin_adobergb_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <lin_adobergb_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </lin_adobergb_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_adobergb_to_lin_rec709_color3" nodedef="ND_adobergb_to_lin_rec709_color3">
    <divide name="constant" type="float">
      <input name="in1" type="float" value="563.0" />
      <input name="in2" type="float" value="256.0" />
    </divide>
    <max name="max" type="color3">
      <input name="in1" type="color3" interfacename="in" />
      <input name="in2" type="float" value="0" />
    </max>
    <power name="gamma" type="color3">
      <input name="in1" type="color3" nodename="max" />
      <input name="in2" type="float" nodename="constant" />
    </power>
    <lin_adobergb_to_lin_rec709 name="rec709" type="color3">
      <input name="in" type="color3" nodename="gamma" />
    </lin_adobergb_to_lin_rec709>
    <output name="out" type="color3" nodename="rec709" />
  </nodegraph>

  <nodegraph name="NG_adobergb_to_lin_rec709_color4" nodedef="ND_adobergb_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <adobergb_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </adobergb_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_srgb_displayp3_to_lin_rec709_color3" nodedef="ND_srgb_displayp3_to_lin_rec709_color3">
    <constant name="mat" type="matrix33">
      <input name="value" type="matrix33"
             value="1.22493029, -0.04205868, -0.01964128, -0.22492968, 1.04205894, -0.07864794, 0.00000006,-0.00000001, 1.09828925"/>
    </constant>
    <!--  Use srgb_texture_to_lin_rec709 to convert from sRGB to Lin before passing to the mat conversion -->
    <srgb_texture_to_lin_rec709 name="srgb_transform" type="color3">
      <input name="in" type="color3" interfacename="in" />
    </srgb_texture_to_lin_rec709>
    <convert name="asVec" type="vector3">
      <input name="in" type="color3" nodename="srgb_transform" />
    </convert>
    <transformmatrix name="transform" type="vector3">
      <input name="in" type="vector3" nodename="asVec" />
      <input name="mat" type="matrix33" nodename="mat" />
    </transformmatrix>
    <convert name="asColor" type="color3">
      <input name="in" type="vector3" nodename="transform" />
    </convert>
    <output name="out" type="color3" nodename="asColor" />
  </nodegraph>

  <nodegraph name="NG_srgb_displayp3_to_lin_rec709_color4" nodedef="ND_srgb_displayp3_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <srgb_displayp3_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </srgb_displayp3_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

  <nodegraph name="NG_lin_displayp3_to_lin_rec709_color3" nodedef="ND_lin_displayp3_to_lin_rec709_color3">
    <constant name="mat" type="matrix33">
      <input name="value" type="matrix33"
             value="1.22493029, -0.04205868, -0.01964128, -0.22492968, 1.04205894, -0.07864794, 0.00000006,-0.00000001, 1.09828925"/>
    </constant>
    <convert name="asVec" type="vector3">
      <input name="in" type="color3" interfacename="in" />
    </convert>
    <transformmatrix name="transform" type="vector3">
      <input name="in" type="vector3" nodename="asVec" />
      <input name="mat" type="matrix33" nodename="mat" />
    </transformmatrix>
    <convert name="asColor" type="color3">
      <input name="in" type="vector3" nodename="transform" />
    </convert>
    <output name="out" type="color3" nodename="asColor" />
  </nodegraph>

  <nodegraph name="NG_lin_displayp3_to_lin_rec709_color4" nodedef="ND_lin_displayp3_to_lin_rec709_color4">
    <convert name="asColor3" type="color3">
      <input name="in" type="color4" interfacename="in" />
    </convert>
    <lin_displayp3_to_lin_rec709 name="transform" type="color3">
      <input name="in" type="color3" nodename="asColor3" />
    </lin_displayp3_to_lin_rec709>
    <extract name="alpha" type="float">
      <input name="in" type="color4" interfacename="in" />
      <input name="index" type="integer" value="3" />
    </extract>
    <combine2 name="asColor4" type="color4">
      <input name="in1" type="color3" nodename="transform" />
      <input name="in2" type="float" nodename="alpha" />
    </combine2>
    <output name="out" type="color4" nodename="asColor4" />
  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Graph definitions of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- View-dependent nodes                                                     -->
  <!-- ======================================================================== -->

  <!--
    Node: <facingratio>
  -->
  <nodegraph name="NG_facingratio_float" nodedef="ND_facingratio_float">
    <dotproduct name="N_dotproduct" type="float">
      <input name="in1" type="vector3" interfacename="viewdirection" />
      <input name="in2" type="vector3" interfacename="normal" />
    </dotproduct>
    <multiply name="N_scale" type="float">
      <input name="in1" type="float" nodename="N_dotproduct" />
      <input name="in2" type="float" value="-1" />
    </multiply>
    <absval name="N_absval" type="float">
      <input name="in" type="float" nodename="N_dotproduct" />
    </absval>
    <ifequal name="N_facing" type="float">
      <input name="value1" type="boolean" interfacename="faceforward" />
      <input name="value2" type="boolean" value="true" />
      <input name="in1" type="float" nodename="N_absval" />
      <input name="in2" type="float" nodename="N_scale" />
    </ifequal>
    <invert name="N_invert" type="float">
      <input name="in" type="float" nodename="N_facing" />
    </invert>
    <ifequal name="N_result" type="float">
      <input name="value1" type="boolean" interfacename="invert" />
      <input name="value2" type="boolean" value="true" />
      <input name="in1" type="float" nodename="N_invert" />
      <input name="in2" type="float" nodename="N_facing" />
    </ifequal>
    <output name="out" type="float" nodename="N_result" />
  </nodegraph>

  <!--
    Node: <gooch_shade>
  -->
  <nodegraph name="NG_gooch_shade" type="color3" nodedef="ND_gooch_shade">
    <normal name="normal" type="vector3">
      <input name="space" type="string" value="world" />
    </normal>
    <viewdirection name="viewdir" type="vector3">
      <input name="space" type="string" value="world" />
    </viewdirection>
    <normalize name="unit_normal" type="vector3">
      <input name="in" type="vector3" nodename="normal" />
    </normalize>
    <normalize name="unit_viewdir" type="vector3">
      <input name="in" type="vector3" nodename="viewdir" />
    </normalize>
    <normalize name="unit_lightdir" type="vector3">
      <input name="in" type="vector3" interfacename="light_direction" />
    </normalize>
    <dotproduct name="NdotL" type="float">
      <input name="in1" type="vector3" nodename="unit_normal" />
      <input name="in2" type="vector3" nodename="unit_lightdir" />
    </dotproduct>
    <add name="one_plus_NdotL" type="float">
      <input name="in2" type="float" nodename="NdotL" />
      <input name="in1" type="float" value="1" />
    </add>
    <divide name="cool_intensity" type="float">
      <input name="in1" type="float" nodename="one_plus_NdotL" />
      <input name="in2" type="float" value="2" />
    </divide>
    <mix name="diffuse" type="color3">
      <input name="bg" type="color3" interfacename="warm_color" />
      <input name="fg" type="color3" interfacename="cool_color" />
      <input name="mix" type="float" nodename="cool_intensity" />
    </mix>
    <reflect name="view_reflect" type="vector3">
      <input name="in" type="vector3" nodename="unit_viewdir" />
      <input name="normal" type="vector3" nodename="unit_normal" />
    </reflect>
    <multiply name="invert_lightdir" type="vector3">
      <input name="in1" type="vector3" nodename="unit_lightdir" />
      <input name="in2" type="float" value="-1" />
    </multiply>
    <dotproduct name="VdotR" type="float">
      <input name="in1" type="vector3" nodename="invert_lightdir" />
      <input name="in2" type="vector3" nodename="view_reflect" />
    </dotproduct>
    <max name="VdotR_nonnegative" type="float">
      <input name="in1" type="float" nodename="VdotR" />
      <input name="in2" type="float" value="0" />
    </max>
    <power name="specular_highlight" type="float">
      <input name="in1" type="float" nodename="VdotR_nonnegative" />
      <input name="in2" type="float" interfacename="shininess" />
    </power>
    <multiply name="specular" type="float">
      <input name="in1" type="float" nodename="specular_highlight" />
      <input name="in2" type="float" interfacename="specular_intensity" />
    </multiply>
    <add name="final_color" type="color3">
      <input name="in1" type="color3" nodename="diffuse" />
      <input name="in2" type="float" nodename="specular" />
    </add>
    <output name="out" type="color3" nodename="final_color" />
  </nodegraph>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations of standard data types and nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- View-dependent properties                                                -->
  <!-- ======================================================================== -->

  <geompropdef name="Vworld" type="vector3" geomprop="viewdirection" space="world" />

  <!-- ======================================================================== -->
  <!-- View-dependent nodes                                                     -->
  <!-- ======================================================================== -->

  <!--
    Node: <viewdirection>
    The current scene view direction, as defined by the shading environment.
  -->
  <nodedef name="ND_viewdirection_vector3" node="viewdirection" nodegroup="npr">
    <input name="space" type="string" value="world" enum="model,object,world" uniform="true" />
    <output name="out" type="vector3" default="0.0, 0.0, 1.0" />
  </nodedef>

  <!--
    Node: <facingratio>
    Return the geometric facing ratio, computed as the dot product between the
    view direction and geometric normal.
  -->
  <nodedef name="ND_facingratio_float" node="facingratio" nodegroup="npr">
    <input name="viewdirection" type="vector3" defaultgeomprop="Vworld" />
    <input name="normal" type="vector3" defaultgeomprop="Nworld" />
    <input name="faceforward" type="boolean" value="true" />
    <input name="invert" type="boolean" value="false" />
    <output name="out" type="float" default="0.0" />
  </nodedef>

  <!--
    Node: <gooch_shade>
    Compute Gooch Shading.
  -->
  <nodedef name="ND_gooch_shade" node="gooch_shade" nodegroup="npr" doc="Compute Gooch shading">
    <input name="warm_color" type="color3" value="0.8, 0.8, 0.7" uiname="Warm Color" doc="Warm color" />
    <input name="cool_color" type="color3" value="0.3, 0.3, 0.8" uiname="Cool Color" doc="Cool color" />
    <input name="specular_intensity" type="float" value="1" uimin="0" uimax="1" uiname="Specular Intensity" doc="Specular Intensity" />
    <input name="shininess" type="float" value="64" uimin="1" uisoftmax="256" uiname="Shininess" doc="Specular Power" />
    <input name="light_direction" type="vector3" value="1, -0.5, -0.5" uimin="-1, -1, -1" uimax="1, 1, 1" uiname="Light Direction" doc="Light vector in world space" />
    <output name="out" type="color3" />
  </nodedef>

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations for MSL implementations of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- View-dependent nodes                                                     -->
  <!-- ======================================================================== -->

  <!-- <viewdirection> -->
  <implementation name="IM_viewdirection_vector3_genmsl" nodedef="ND_viewdirection_vector3" target="genmsl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations for GLSL implementations of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- View-dependent nodes                                                     -->
  <!-- ======================================================================== -->

  <!-- <viewdirection> -->
  <implementation name="IM_viewdirection_vector3_genglsl" nodedef="ND_viewdirection_vector3" target="genglsl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations for OSL implementations of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- View-dependent nodes                                                     -->
  <!-- ======================================================================== -->

  <!-- <viewdirection> -->
  <implementation name="IM_viewdirection_vector3_genosl" nodedef="ND_viewdirection_vector3" sourcecode="transform({{space}}, I)" target="genosl" />

</materialx>
<?xml version="1.0"?>
<materialx version="1.39">
  <!--
    Copyright Contributors to the MaterialX Project
    SPDX-License-Identifier: Apache-2.0

    Declarations for MDL implementations of standard nodes included in the MaterialX specification.
  -->

  <!-- ======================================================================== -->
  <!-- View-dependent nodes                                                     -->
  <!-- ======================================================================== -->

  <!-- <viewdirection> -->
  <implementation name="IM_viewdirection_vector3_genmdl" nodedef="ND_viewdirection_vector3" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_viewdirection_vector3(mxp_space:{{space}})" target="genmdl" />

</materialx>
