Functional Definitions Notebook¶
The following notebook demonstrates how to create functional node definitions from non-functional ones in the MaterialX standard library. This includes inline both functional nodegrapsh as well as direct implementation references.
The version of MaterialX used include the proposed changes required to support this functionality in version 1.39.5.
import MaterialX as mx
# Import lib to display markdown cells
from IPython.display import Markdown, display
def print_markdown(text):
display(Markdown(text))
print_markdown("- MaterialX version: " + mx.getVersionString())
def createTestDoc():
doc : mx.Document = mx.createDocument()
stdlib = mx.createDocument()
libFiles = mx.loadLibraries(mx.getDefaultDataLibraryFolders(), mx.getDefaultDataSearchPath(), stdlib)
defs = stdlib.getNodeDefs()
print_markdown(f"- Loaded: {len(defs)} node definitions from {len(libFiles)} library files")
return doc, stdlib
doc, stdlib = createTestDoc()
- MaterialX version: 1.39.5
- Loaded: 803 node definitions from 60 library files
The follow code is a small wrapper around the C++ NodeDef::inlineImplementation() method which basically:
- Removes any back-references to node definition (
nodedefattribute) - Create a copy of the original implementation (for the given target) parented under the existing node definition
- Returns the modified node definition
def make_functional_definition(test_name, target=''):
test_def = stdlib.getNodeDef(test_name)
if test_def:
new_def = test_def.inlineImplementation(target)
return test_def
As the branch of code used currently does not contain support for this function yet, we write a Python version here.
def make_functional_definition_impl(test_name, target='', requireExclusive=False):
"""
Add per-target implementations to a functional nodedef.
"""
test_def = stdlib.getNodeDef(test_name)
if test_def:
shared_impl = test_def.hasSharedImplementation()
if requireExclusive and shared_impl:
print(f'Node definition uses a shared implementation. Skipping: {test_name}. Target: {target}')
return None
impl = None
if shared_impl:
unmapped = stdlib.getMatchingUnmappedImplementations(test_name)
if len(unmapped) > 0:
impl = unmapped[0]
if not impl:
impl = test_def.getImplementation(target)
if impl:
new_impl = None
new_impl_name = impl.getName()
existing_child = test_def.getChild(new_impl_name)
if existing_child:
return test_def
new_impl = test_def.addChildOfCategory(impl.getCategory(), new_impl_name)
print(f'Add child implementation: {new_impl_name}. Target: {impl.getTarget()}')
if not new_impl:
print("Failed to create new functional def child:", new_impl_name)
return None
else:
# Copy over implementation content without the nodedef back-reference.
impl.removeAttribute(mx.InterfaceElement.NODE_DEF_ATTRIBUTE)
new_impl.copyContentFrom(impl)
return test_def
Examples¶
This following examples inline implementations by:
- Iterating over all target definitions in the standard library.
- Inline the implementation for each target.
The result is the accumulation of all target-specific implementations directly under the node definition.
Inline the functional nodegraph for the tiledimage definition.¶
def test_inline(test_nam, requireExclusive=False):
print_markdown(f"##### Converting node definition: `{test_name}`")
targetDefs = stdlib.getTargetDefs()
test_def = stdlib.getNodeDef(test_name)
display(Markdown('**Original definition**'))
display(Markdown("```xml\n" + mx.prettyPrint(test_def) + "\n```"))
test_def = None
for targetDef in targetDefs:
#print("> Adding target:", targetDef.getName())
test_def = make_functional_definition_impl(test_name, targetDef.getName(), requireExclusive=requireExclusive)
if test_def:
display(Markdown("**New functional node definition**"))
display(Markdown("```xml\n" + mx.prettyPrint(test_def) + "\n```"))
if test_def:
display(Markdown("##### New functional node definition:"))
display(Markdown("```xml\n" + mx.prettyPrint(test_def) + "\n```"))
test_name = "ND_tiledimage_color3"
test_def = test_inline(test_name)
Converting node definition: ND_tiledimage_color3¶
Original definition
<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">
Add child implementation: NG_tiledimage_color3. Target:
New functional node definition
<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">
<nodegraph name="NG_tiledimage_color3">
<multiply name="N_mult_color3" type="vector2">
<input name="in1" type="vector2" interfacename="texcoord">
<input name="in2" type="vector2" interfacename="uvtiling">
<subtract name="N_sub_color3" type="vector2">
<input name="in1" type="vector2" nodename="N_mult_color3">
<input name="in2" type="vector2" interfacename="uvoffset">
<divide name="N_divtilesize_color3" type="vector2">
<input name="in1" type="vector2" nodename="N_sub_color3">
<input name="in2" type="vector2" interfacename="realworldimagesize">
<multiply name="N_multtilesize_color3" type="vector2">
<input name="in1" type="vector2" nodename="N_divtilesize_color3">
<input name="in2" type="vector2" interfacename="realworldtilesize">
<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">
<output name="out" type="color3" nodename="N_img_color3">
New functional node definition:¶
<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">
<nodegraph name="NG_tiledimage_color3">
<multiply name="N_mult_color3" type="vector2">
<input name="in1" type="vector2" interfacename="texcoord">
<input name="in2" type="vector2" interfacename="uvtiling">
<subtract name="N_sub_color3" type="vector2">
<input name="in1" type="vector2" nodename="N_mult_color3">
<input name="in2" type="vector2" interfacename="uvoffset">
<divide name="N_divtilesize_color3" type="vector2">
<input name="in1" type="vector2" nodename="N_sub_color3">
<input name="in2" type="vector2" interfacename="realworldimagesize">
<multiply name="N_multtilesize_color3" type="vector2">
<input name="in1" type="vector2" nodename="N_divtilesize_color3">
<input name="in2" type="vector2" interfacename="realworldtilesize">
<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">
<output name="out" type="color3" nodename="N_img_color3">
Inline non-graph implementations for the image definition.¶
test_name = "ND_image_float"
test_def = test_inline(test_name)
Converting node definition: ND_image_float¶
Original definition
<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">
Add child implementation: IM_image_float_genglsl. Target: genglsl Add child implementation: IM_image_float_genmdl. Target: genmdl Add child implementation: IM_image_float_genmsl. Target: genmsl Add child implementation: IM_image_float_genosl. Target: genosl Add child implementation: IM_image_float_genslang. Target: genslang
New functional node definition
<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">
<implementation name="IM_image_float_genglsl" file="mx_image_float.glsl" function="mx_image_float" target="genglsl">
<input name="default" type="float" implname="default_value">
<implementation name="IM_image_float_genmdl" 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 name="IM_image_float_genmsl" file="../genglsl/mx_image_float.glsl" function="mx_image_float" target="genmsl">
<input name="default" type="float" implname="default_value">
<implementation name="IM_image_float_genosl" file="mx_image_float.osl" function="mx_image_float" target="genosl">
<input name="default" type="float" implname="default_value">
<implementation name="IM_image_float_genslang" file="../genglsl/mx_image_float.glsl" function="mx_image_float" target="genslang">
<input name="default" type="float" implname="default_value">
New functional node definition:¶
<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">
<implementation name="IM_image_float_genglsl" file="mx_image_float.glsl" function="mx_image_float" target="genglsl">
<input name="default" type="float" implname="default_value">
<implementation name="IM_image_float_genmdl" 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 name="IM_image_float_genmsl" file="../genglsl/mx_image_float.glsl" function="mx_image_float" target="genmsl">
<input name="default" type="float" implname="default_value">
<implementation name="IM_image_float_genosl" file="mx_image_float.osl" function="mx_image_float" target="genosl">
<input name="default" type="float" implname="default_value">
<implementation name="IM_image_float_genslang" file="../genglsl/mx_image_float.glsl" function="mx_image_float" target="genslang">
<input name="default" type="float" implname="default_value">
This is another example which inline the implementations for the position definition.
In this case we have a mix of source code and externally referenced implementations. The result is again a functional node definition with all implementations inlined.
test_name = "ND_position_vector3"
test_def = test_inline(test_name)
Converting node definition: ND_position_vector3¶
Original definition
<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">
Add child implementation: IM_position_vector3_genglsl. Target: genglsl Add child implementation: IM_position_vector3_genmdl. Target: genmdl Add child implementation: IM_position_vector3_genmsl. Target: genmsl Add child implementation: IM_position_vector3_genosl. Target: genosl Add child implementation: IM_position_vector3_genslang. Target: genslang
New functional node definition
<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">
<implementation name="IM_position_vector3_genglsl" target="genglsl">
<implementation name="IM_position_vector3_genmdl" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_position_vector3(mxp_space:{{space}})" target="genmdl">
<implementation name="IM_position_vector3_genmsl" target="genmsl">
<implementation name="IM_position_vector3_genosl" target="genosl" sourcecode="transform({{space}}, P)">
<implementation name="IM_position_vector3_genslang" target="genslang">
New functional node definition:¶
<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">
<implementation name="IM_position_vector3_genglsl" target="genglsl">
<implementation name="IM_position_vector3_genmdl" sourcecode="materialx::stdlib_{{MDL_VERSION_SUFFIX}}::mx_position_vector3(mxp_space:{{space}})" target="genmdl">
<implementation name="IM_position_vector3_genmsl" target="genmsl">
<implementation name="IM_position_vector3_genosl" target="genosl" sourcecode="transform({{space}}, P)">
<implementation name="IM_position_vector3_genslang" target="genslang">
Inheritance and Shared Implementations¶
Some node definitions inherit their implementations from parent definitions.
The followiing utility shows how to traverse through inheritance to find the definitions and the associated implementations.
Additionally there is a check to find out which implementations are directly references and which are indirectly referenced via
<implementation> elements.
def get_matching_definitions(def_name):
check_nodedef = stdlib.getNodeDef(def_name)
nodegraph_counts = {} # Will store {nodegraph: count}
nodegraph_nodedefs = {} # Will store {nodegraph: set(nodedefs)}
mapped_inheritance_tree_nodedefs = []
if check_nodedef:
print("-"*80)
print(f"Example hierarhy for: {check_nodedef.getName()}")
# Traverse inheritance to find all matching definitions
inheritance_tree_nodedefs = check_nodedef.getMatchingDefinitions()
print("* number of definitions in inheritance tree:", len(inheritance_tree_nodedefs))
for ndstring in inheritance_tree_nodedefs:
nd = stdlib.getNodeDef(ndstring)
if nd:
inheritance_string = nd.getInheritString()
if not inheritance_string:
inheritance_string = "<NONE>"
print(" Scan definition:", ndstring, " version:", nd.getVersionString(), " inherits from:", inheritance_string)
# See if there are any indirect mappings
for impl in stdlib.getMatchingUnmappedImplementations(ndstring):
if not impl.isA(mx.NodeGraph):
nodegraph_string = impl.getAttribute("nodegraph")
if nodegraph_string:
print("- Found intermediate mapping implementation", impl.getName(), "redirecting to nodegraph:", nodegraph_string)
else:
print("- Found intermediate mapping implementations", impl.getName())
mapped_inheritance_tree_nodedefs.append(nd)
#print(mx.prettyPrint(impl))
impl = nd.getImplementation()
if impl.isA(mx.NodeGraph):
print(" Implementation name:", impl.getName())
# Check if there is an indirect mapping to get to this nodegraph
#
if mapped_inheritance_tree_nodedefs:
for other in mapped_inheritance_tree_nodedefs:
if other.getAttribute("nodegraph") == impl.getName():
print(f" (nodegraph acessed via {other.getName()} implementation redirection !)")
else:
# >>> Code to handle regression (not required anymore after new cache change)
nodegraph_name = None
nodegraph_string = impl.getAttribute("nodegraph")
if nodegraph_string:
impl = stdlib.getNodeGraph(nodegraph_string)
nodegraph_name = nodegraph_string
if nodegraph_name:
# Count usage of each nodegraph
if nodegraph_name in nodegraph_counts:
nodegraph_counts[nodegraph_name] += 1
else:
nodegraph_counts[nodegraph_name] = 1
# Track which nodedefs use this nodegraph
if nodegraph_name not in nodegraph_nodedefs:
nodegraph_nodedefs[nodegraph_name] = set()
nodegraph_nodedefs[nodegraph_name].add(ndstring)
if impl and impl.isA(mx.NodeGraph):
print(" mapped implementation:", impl.getName())
get_matching_definitions("ND_UsdUVTexture")
get_matching_definitions("ND_standard_surface_surfaceshader")
-------------------------------------------------------------------------------- Example hierarhy for: ND_UsdUVTexture * number of definitions in inheritance tree: 2 Scan definition: ND_UsdUVTexture version: 2.2 inherits from: ND_UsdUVTexture_23 Implementation name: IMP_UsdUVTexture_22 Scan definition: ND_UsdUVTexture_23 version: 2.3 inherits from: <NONE> Implementation name: IMP_UsdUVTexture_23 -------------------------------------------------------------------------------- Example hierarhy for: ND_standard_surface_surfaceshader * number of definitions in inheritance tree: 2 Scan definition: ND_standard_surface_surfaceshader version: 1.0.1 inherits from: ND_standard_surface_surfaceshader_100 - Found intermediate mapping implementation IMPL_standard_surface_surfaceshader_101 redirecting to nodegraph: NG_standard_surface_surfaceshader_100 - Found intermediate mapping implementation IMPL_standard_surface_surfaceshader_optim redirecting to nodegraph: NG_standard_surface_surfaceshader_optim Implementation name: NG_standard_surface_surfaceshader_100 Scan definition: ND_standard_surface_surfaceshader_100 version: 1.0.0 inherits from: <NONE> - Found intermediate mapping implementation IMPL_standard_surface_surfaceshader_100 redirecting to nodegraph: NG_standard_surface_surfaceshader_100 Implementation name: NG_standard_surface_surfaceshader_100
The above scan implicitly shows that the standard_surface_surfaceshader node definition reuses an implementation NG_standard_surface_surfaceshader_100.
A more direct way to check is to scan through the "unmapped" implementations cached in a a library using the Document::getMatchingUnmappedDefinitions() method. Code to get both the direct and indirect references is shown below.
indirect_mapped_nodedefs = []
direct_mapped_nodedefs = []
for nd in stdlib.getNodeDefs():
nd_name = nd.getName()
direct_mapped_nodedefs.append(stdlib.getMatchingImplementations(nd_name))
unmapped = stdlib.getMatchingUnmappedImplementations(nd_name)
for impl in unmapped:
if not impl.isA(mx.NodeGraph):
if impl.getAttribute("nodegraph"):
indirect_mapped_nodedefs.append(impl)
print("Number of indirectly mapped nodedefs:", len(indirect_mapped_nodedefs))
for impl in indirect_mapped_nodedefs:
print(" Indirect mapping implementation:", impl.getName(), " to nodegraph:", impl.getAttribute("nodegraph"))
print("Number of directly mapped nodedefs:", len(direct_mapped_nodedefs) - len(indirect_mapped_nodedefs))
Number of indirectly mapped nodedefs: 3 Indirect mapping implementation: IMPL_standard_surface_surfaceshader_101 to nodegraph: NG_standard_surface_surfaceshader_100 Indirect mapping implementation: IMPL_standard_surface_surfaceshader_optim to nodegraph: NG_standard_surface_surfaceshader_optim Indirect mapping implementation: IMPL_standard_surface_surfaceshader_100 to nodegraph: NG_standard_surface_surfaceshader_100 Number of directly mapped nodedefs: 800
Inlining shared implementations¶
Though it is possible to inline shared implementations this results in duplication of the same implementation across multiple node definitions.
The following shows the current behaviour which is to prevent inlining if the inlining option requireExclusive is set to True.
test_name = 'ND_standard_surface_surfaceshader'
test_inline(test_name, requireExclusive=True)
Converting node definition: ND_standard_surface_surfaceshader¶
Original 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.">
Node definition uses a shared implementation. Skipping: ND_standard_surface_surfaceshader. Target: essl Node definition uses a shared implementation. Skipping: ND_standard_surface_surfaceshader. Target: genglsl Node definition uses a shared implementation. Skipping: ND_standard_surface_surfaceshader. Target: genmdl Node definition uses a shared implementation. Skipping: ND_standard_surface_surfaceshader. Target: genmsl Node definition uses a shared implementation. Skipping: ND_standard_surface_surfaceshader. Target: genosl Node definition uses a shared implementation. Skipping: ND_standard_surface_surfaceshader. Target: genoslnetwork Node definition uses a shared implementation. Skipping: ND_standard_surface_surfaceshader. Target: genslang
The following shows an alternative is to instead only inline the <implementation> reference itself, thus keeping the shared implementation intact.
Note that both a direct (nodegraph) and indirect (implemetnation) reference is inlined in this case.
test_name = 'ND_standard_surface_surfaceshader'
test_inline(test_name, requireExclusive=False)
Converting node definition: ND_standard_surface_surfaceshader¶
Original 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.">
Add child implementation: IMPL_standard_surface_surfaceshader_101. Target: Add child implementation: NG_standard_surface_surfaceshader_optim. Target: genglsl
New functional 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.">
<implementation name="IMPL_standard_surface_surfaceshader_101" nodegraph="NG_standard_surface_surfaceshader_100">
<nodegraph name="NG_standard_surface_surfaceshader_optim" target="genglsl">
<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 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">
<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">
<roughness_anisotropy name="main_roughness" type="vector2">
<input name="roughness" type="float" nodename="coat_affected_roughness">
<input name="anisotropy" type="float" interfacename="specular_anisotropy">
<add name="transmission_roughness_add" type="float">
<input name="in1" type="float" interfacename="specular_roughness">
<input name="in2" type="float" interfacename="transmission_extra_roughness">
<clamp name="transmission_roughness_clamped" type="float">
<input name="in" type="float" nodename="transmission_roughness_add">
<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">
<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">
<multiply name="tangent_rotate_degree" type="float">
<input name="in1" type="float" interfacename="specular_rotation">
<input name="in2" type="float" value="360">
<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">
<normalize name="tangent_rotate_normalize" type="vector3">
<input name="in" type="vector3" nodename="tangent_rotate">
<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">
<multiply name="coat_tangent_rotate_degree" type="float">
<input name="in1" type="float" interfacename="coat_rotation">
<input name="in2" type="float" value="360">
<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">
<normalize name="coat_tangent_rotate_normalize" type="vector3">
<input name="in" type="vector3" nodename="coat_tangent_rotate">
<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">
<clamp name="coat_clamped" type="float">
<input name="in" type="float" interfacename="coat">
<multiply name="coat_gamma_multiply" type="float">
<input name="in1" type="float" nodename="coat_clamped">
<input name="in2" type="float" interfacename="coat_affect_color">
<add name="coat_gamma" type="float">
<input name="in1" type="float" nodename="coat_gamma_multiply">
<input name="in2" type="float" value="1.0">
<max name="base_color_nonnegative" type="color3">
<input name="in1" type="color3" interfacename="base_color">
<input name="in2" type="float" value="0.0">
<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">
<max name="subsurface_color_nonnegative" type="color3">
<input name="in1" type="color3" interfacename="subsurface_color">
<input name="in2" type="float" value="0.0">
<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">
<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">
<translucent_bsdf name="translucent_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="subsurface">
<input name="color" type="color3" nodename="coat_affected_subsurface_color">
<input name="normal" type="vector3" interfacename="normal">
<multiply name="subsurface_radius_scaled" type="color3">
<input name="in1" type="color3" interfacename="subsurface_radius">
<input name="in2" type="float" interfacename="subsurface_scale">
<subsurface_bsdf name="subsurface_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="subsurface">
<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">
<convert name="subsurface_selector" type="float">
<input name="in" type="boolean" interfacename="thin_walled">
<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">
<invert name="subsurface_inv" type="float">
<input name="in" type="float" interfacename="subsurface">
<multiply name="diffuse_bsdf_non_subsurface" type="BSDF">
<input name="in1" type="BSDF" nodename="diffuse_bsdf">
<input name="in2" type="float" nodename="subsurface_inv">
<add name="subsurface_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="selected_subsurface_bsdf">
<input name="in2" type="BSDF" nodename="diffuse_bsdf_non_subsurface">
<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">
<layer name="sheen_layer" type="BSDF">
<input name="top" type="BSDF" nodename="sheen_bsdf">
<input name="base" type="BSDF" nodename="subsurface_blend">
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="transmission">
<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">
<invert name="transmission_inv" type="float">
<input name="in" type="float" interfacename="transmission">
<multiply name="sheen_layer_non_transmission" type="BSDF">
<input name="in1" type="BSDF" nodename="sheen_layer">
<input name="in2" type="float" nodename="transmission_inv">
<add name="transmission_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="transmission_bsdf">
<input name="in2" type="BSDF" nodename="sheen_layer_non_transmission">
<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">
<layer name="specular_layer" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf">
<input name="base" type="BSDF" nodename="transmission_blend">
<multiply name="metal_reflectivity" type="color3">
<input name="in1" type="color3" interfacename="base_color">
<input name="in2" type="float" interfacename="base">
<multiply name="metal_edgecolor" type="color3">
<input name="in1" type="color3" interfacename="specular_color">
<input name="in2" type="float" interfacename="specular">
<artistic_ior name="artistic_ior" type="multioutput">
<input name="reflectivity" type="color3" nodename="metal_reflectivity">
<input name="edge_color" type="color3" nodename="metal_edgecolor">
<conductor_bsdf name="metal_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="metalness">
<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">
<invert name="metalness_inv" type="float">
<input name="in" type="float" interfacename="metalness">
<multiply name="specular_layer_non_metal" type="BSDF">
<input name="in1" type="BSDF" nodename="specular_layer">
<input name="in2" type="float" nodename="metalness_inv">
<add name="metalness_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="metal_bsdf">
<input name="in2" type="BSDF" nodename="specular_layer_non_metal">
<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">
<multiply name="thin_film_layer_attenuated" type="BSDF">
<input name="in1" type="BSDF" nodename="metalness_blend">
<input name="in2" type="color3" nodename="coat_attenuation">
<roughness_anisotropy name="coat_roughness_vector" type="vector2">
<input name="roughness" type="float" interfacename="coat_roughness">
<input name="anisotropy" type="float" interfacename="coat_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">
<layer name="coat_layer" type="BSDF">
<input name="top" type="BSDF" nodename="coat_bsdf">
<input name="base" type="BSDF" nodename="thin_film_layer_attenuated">
<subtract name="one_minus_coat_ior" type="float">
<input name="in1" type="float" value="1.0">
<input name="in2" type="float" interfacename="coat_IOR">
<add name="one_plus_coat_ior" type="float">
<input name="in1" type="float" value="1.0">
<input name="in2" type="float" interfacename="coat_IOR">
<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">
<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">
<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">
<multiply name="emission_weight" type="color3">
<input name="in1" type="color3" interfacename="emission_color">
<input name="in2" type="float" interfacename="emission">
<uniform_edf name="emission_edf" type="EDF">
<input name="color" type="color3" nodename="emission_weight">
<multiply name="coat_tinted_emission_edf" type="EDF">
<input name="in1" type="EDF" nodename="emission_edf">
<input name="in2" type="color3" interfacename="coat_color">
<convert name="emission_color0" type="color3">
<input name="in" type="float" nodename="one_minus_coat_ior_to_F0">
<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">
<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">
<luminance name="opacity_luminance" type="color3">
<input name="in" type="color3" interfacename="opacity">
<extract name="opacity_luminance_float" type="float">
<input name="in" type="color3" nodename="opacity_luminance">
<input name="index" type="integer" value="0">
<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">
<output name="out" type="surfaceshader" nodename="shader_constructor">
New functional 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.">
<implementation name="IMPL_standard_surface_surfaceshader_101" nodegraph="NG_standard_surface_surfaceshader_100">
<nodegraph name="NG_standard_surface_surfaceshader_optim" target="genglsl">
<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 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">
<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">
<roughness_anisotropy name="main_roughness" type="vector2">
<input name="roughness" type="float" nodename="coat_affected_roughness">
<input name="anisotropy" type="float" interfacename="specular_anisotropy">
<add name="transmission_roughness_add" type="float">
<input name="in1" type="float" interfacename="specular_roughness">
<input name="in2" type="float" interfacename="transmission_extra_roughness">
<clamp name="transmission_roughness_clamped" type="float">
<input name="in" type="float" nodename="transmission_roughness_add">
<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">
<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">
<multiply name="tangent_rotate_degree" type="float">
<input name="in1" type="float" interfacename="specular_rotation">
<input name="in2" type="float" value="360">
<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">
<normalize name="tangent_rotate_normalize" type="vector3">
<input name="in" type="vector3" nodename="tangent_rotate">
<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">
<multiply name="coat_tangent_rotate_degree" type="float">
<input name="in1" type="float" interfacename="coat_rotation">
<input name="in2" type="float" value="360">
<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">
<normalize name="coat_tangent_rotate_normalize" type="vector3">
<input name="in" type="vector3" nodename="coat_tangent_rotate">
<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">
<clamp name="coat_clamped" type="float">
<input name="in" type="float" interfacename="coat">
<multiply name="coat_gamma_multiply" type="float">
<input name="in1" type="float" nodename="coat_clamped">
<input name="in2" type="float" interfacename="coat_affect_color">
<add name="coat_gamma" type="float">
<input name="in1" type="float" nodename="coat_gamma_multiply">
<input name="in2" type="float" value="1.0">
<max name="base_color_nonnegative" type="color3">
<input name="in1" type="color3" interfacename="base_color">
<input name="in2" type="float" value="0.0">
<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">
<max name="subsurface_color_nonnegative" type="color3">
<input name="in1" type="color3" interfacename="subsurface_color">
<input name="in2" type="float" value="0.0">
<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">
<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">
<translucent_bsdf name="translucent_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="subsurface">
<input name="color" type="color3" nodename="coat_affected_subsurface_color">
<input name="normal" type="vector3" interfacename="normal">
<multiply name="subsurface_radius_scaled" type="color3">
<input name="in1" type="color3" interfacename="subsurface_radius">
<input name="in2" type="float" interfacename="subsurface_scale">
<subsurface_bsdf name="subsurface_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="subsurface">
<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">
<convert name="subsurface_selector" type="float">
<input name="in" type="boolean" interfacename="thin_walled">
<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">
<invert name="subsurface_inv" type="float">
<input name="in" type="float" interfacename="subsurface">
<multiply name="diffuse_bsdf_non_subsurface" type="BSDF">
<input name="in1" type="BSDF" nodename="diffuse_bsdf">
<input name="in2" type="float" nodename="subsurface_inv">
<add name="subsurface_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="selected_subsurface_bsdf">
<input name="in2" type="BSDF" nodename="diffuse_bsdf_non_subsurface">
<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">
<layer name="sheen_layer" type="BSDF">
<input name="top" type="BSDF" nodename="sheen_bsdf">
<input name="base" type="BSDF" nodename="subsurface_blend">
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="transmission">
<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">
<invert name="transmission_inv" type="float">
<input name="in" type="float" interfacename="transmission">
<multiply name="sheen_layer_non_transmission" type="BSDF">
<input name="in1" type="BSDF" nodename="sheen_layer">
<input name="in2" type="float" nodename="transmission_inv">
<add name="transmission_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="transmission_bsdf">
<input name="in2" type="BSDF" nodename="sheen_layer_non_transmission">
<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">
<layer name="specular_layer" type="BSDF">
<input name="top" type="BSDF" nodename="specular_bsdf">
<input name="base" type="BSDF" nodename="transmission_blend">
<multiply name="metal_reflectivity" type="color3">
<input name="in1" type="color3" interfacename="base_color">
<input name="in2" type="float" interfacename="base">
<multiply name="metal_edgecolor" type="color3">
<input name="in1" type="color3" interfacename="specular_color">
<input name="in2" type="float" interfacename="specular">
<artistic_ior name="artistic_ior" type="multioutput">
<input name="reflectivity" type="color3" nodename="metal_reflectivity">
<input name="edge_color" type="color3" nodename="metal_edgecolor">
<conductor_bsdf name="metal_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="metalness">
<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">
<invert name="metalness_inv" type="float">
<input name="in" type="float" interfacename="metalness">
<multiply name="specular_layer_non_metal" type="BSDF">
<input name="in1" type="BSDF" nodename="specular_layer">
<input name="in2" type="float" nodename="metalness_inv">
<add name="metalness_blend" type="BSDF">
<input name="in1" type="BSDF" nodename="metal_bsdf">
<input name="in2" type="BSDF" nodename="specular_layer_non_metal">
<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">
<multiply name="thin_film_layer_attenuated" type="BSDF">
<input name="in1" type="BSDF" nodename="metalness_blend">
<input name="in2" type="color3" nodename="coat_attenuation">
<roughness_anisotropy name="coat_roughness_vector" type="vector2">
<input name="roughness" type="float" interfacename="coat_roughness">
<input name="anisotropy" type="float" interfacename="coat_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">
<layer name="coat_layer" type="BSDF">
<input name="top" type="BSDF" nodename="coat_bsdf">
<input name="base" type="BSDF" nodename="thin_film_layer_attenuated">
<subtract name="one_minus_coat_ior" type="float">
<input name="in1" type="float" value="1.0">
<input name="in2" type="float" interfacename="coat_IOR">
<add name="one_plus_coat_ior" type="float">
<input name="in1" type="float" value="1.0">
<input name="in2" type="float" interfacename="coat_IOR">
<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">
<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">
<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">
<multiply name="emission_weight" type="color3">
<input name="in1" type="color3" interfacename="emission_color">
<input name="in2" type="float" interfacename="emission">
<uniform_edf name="emission_edf" type="EDF">
<input name="color" type="color3" nodename="emission_weight">
<multiply name="coat_tinted_emission_edf" type="EDF">
<input name="in1" type="EDF" nodename="emission_edf">
<input name="in2" type="color3" interfacename="coat_color">
<convert name="emission_color0" type="color3">
<input name="in" type="float" nodename="one_minus_coat_ior_to_F0">
<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">
<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">
<luminance name="opacity_luminance" type="color3">
<input name="in" type="color3" interfacename="opacity">
<extract name="opacity_luminance_float" type="float">
<input name="in" type="color3" nodename="opacity_luminance">
<input name="index" type="integer" value="0">
<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">
<output name="out" type="surfaceshader" nodename="shader_constructor">