UsdPrimVar fails to generate code in GLSL
Unknown if this is a regression as there is not current test for this, but if you create a UsePrimVar and connect it to
a shader downstream then it seems to never pick up the interfacename value varname for the geomprop which
is used as the implementation. Instead it throws an exception when trying to get the ShaderNode value -- even though it's
connected.
Example graph (simpler code is with an unlit so that's hooked up). std surf (commented out) gives the same results.
<?xml version="1.0"?>
<materialx version="1.38">
<UsdPrimvarReader name="UsdPrimvarReader_vector3" type="vector3">
<input name="varname" type="string" value="geompropvalue_vector3" />
</UsdPrimvarReader>
<convert name="vec3_to_color3" type="color3">
<input name="in" type="vector3" nodename="UsdPrimvarReader_vector3" />
</convert>
<surface_unlit name="surface_unlit" type="surfaceshader">
<input name="emission_color" type="color3" nodename="vec3_to_color3" />
</surface_unlit>
<surfacematerial name="surfacematerial" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="surface_unlit" />
</surfacematerial>
<!--<standard_surface name="standard_surface_surfaceshader" type="surfaceshader" >
<input name="base_color" type="color3" nodename="vec3_to_color3" />
</standard_surface>
<surfacematerial name="surfacematerial" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="standard_surface_surfaceshader" />
</surfacematerial>
-->
</materialx>
Seems to work okay for OSL. You get this header:
shader surfacematerial
[[
string mtlx_category = "surfacematerial",
string mtlx_name = "surfacematerial"
]]
(
displacementshader displacementshader1 = vector(0.0),
string UsdPrimvarReader_vector3_varname = "geompropvalue_vector3",
vector UsdPrimvarReader_vector3_fallback = vector(0, 0, 0),
float surface_unlit_emission = 1
[[
string widget = "number"
]],
float surface_unlit_transmission = 0
[[
string widget = "number"
]],
color surface_unlit_transmission_color = color(1, 1, 1),
float surface_unlit_opacity = 1
[[
string widget = "number"
]],
output MATERIAL out = 0
)
Also for MDL
export material surfacematerial
(
float3 displacementshader = float3(0.0),
uniform string UsdPrimvarReader_vector3_varname = "geompropvalue_vector3",
float3 UsdPrimvarReader_vector3_fallback = float3(0, 0, 0),
float surface_unlit_emission = 1,
float surface_unlit_transmission = 0,
color surface_unlit_transmission_color = color(1, 1, 1),
float surface_unlit_opacity = 1
)
For GLSL you get this error:
"No 'geomprop' parameter found on geompropvalue node 'primvar'. Don't know what property to bind"
Found this issue while wanting to open one myself, but I'm on Metal –
My understanding is that this should simply return the fallback value, and not "break rendering":
<?xml version="1.0"?>
<materialx version="1.39">
<UsdPreviewSurface name="UsdPreviewSurface_surfaceshader" type="surfaceshader" xpos="18.869566" ypos="0.991379">
<input name="diffuseColor" type="color3" output="out" nodename="convert_vector3_color3" />
</UsdPreviewSurface>
<convert name="convert_vector3_color3" type="color3" xpos="15.355072" ypos="0.844828">
<output name="out" type="color3" />
<input name="in" type="vector3" nodename="UsdPrimvarReader_vector3" />
</convert>
<UsdPrimvarReader name="UsdPrimvarReader_vector3" type="vector3" xpos="11.442029" ypos="0.318966">
<input name="varname" type="string" value="myColor" />
<input name="fallback" type="vector3" value="0, 1, 0" />
</UsdPrimvarReader>
</materialx>
I was testing with MateiralXViewer and there are a few different things going on here....
First MaterialXView fails to recognize the surfacehshader element as a renderable element. Thats just a difference in behavior between MaterialXGraphEditor and MaterialXViewer - which I believe we should fix, but easily resolved here by adding a surfacematerial element.
<?xml version="1.0"?>
<materialx version="1.39">
<surfacematerial name="mtl" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="UsdPreviewSurface_surfaceshader"/>
</surfacematerial>
<UsdPreviewSurface name="UsdPreviewSurface_surfaceshader" type="surfaceshader" xpos="18.869566" ypos="0.991379">
<input name="diffuseColor" type="color3" output="out" nodename="convert_vector3_color3" />
</UsdPreviewSurface>
<convert name="convert_vector3_color3" type="color3" xpos="15.355072" ypos="0.844828">
<output name="out" type="color3" />
<input name="in" type="vector3" nodename="UsdPrimvarReader_vector3" />
</convert>
<UsdPrimvarReader name="UsdPrimvarReader_vector3" type="vector3" xpos="11.442029" ypos="0.318966">
<input name="varname" type="string" value="myColor" />
<input name="fallback" type="vector3" value="0, 1, 0" />
</UsdPrimvarReader>
</materialx>
The next issue I hit was that the UsdPrimvarReader is just a nodegraph wrapper around geompropvalue, and for some reason in this example, the code is not able to correctly derive the varname input to the wrapped geompropvalue node. For testing purposes this can be resolved by manually expanding UsdPrimvarReader.
<?xml version="1.0"?>
<materialx version="1.39">
<surfacematerial name="mtl" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="UsdPreviewSurface_surfaceshader"/>
</surfacematerial>
<UsdPreviewSurface name="UsdPreviewSurface_surfaceshader" type="surfaceshader" xpos="18.869566" ypos="0.991379">
<input name="diffuseColor" type="color3" nodename="convert_vector3_color3" />
</UsdPreviewSurface>
<convert name="convert_vector3_color3" type="color3" xpos="15.355072" ypos="0.844828">
<input name="in" type="vector3" nodename="primvar" />
</convert>
<geompropvalue name="primvar" type="vector3">
<input name="geomprop" type="string" value="myColor" />
<input name="default" type="vector3" value="0, 1, 0" />
</geompropvalue>
</materialx>
This example still doesn't render as I would expect, and on a MacOS platform I then get an MSL bind attribute error reported in a dialog box in MaterialXView.
I didn't have a chance to test this final example on a GLSL based system, perhaps the final issue is a Metal specific error - which still needs to be fixed.
I think this really breaks down in to three separate issues.
-
MaterialXViewdoesn't recognize the same renderable elements asMaterialXGraphEditor - The
geompropvaluenode inside the nodegraph implementation forUsdPrimvarReaderis not correctly processed during code generation. - Missing geometry properties are not correctly handled correctly in (at least the Metal case) for
geompropvalue. They fail the render, instead of falling back to thedefaultvalue.