I was debating if I should tag this beginner or not, but I’ve been googling a bunch and haven’t been able to figure it out. But I’m pretty new to Usd Shaders and Materials.
Basically: I want to add a UsdShade.Shader that’s an instantiation of a MaterialX Standard Surface. (Or also non-MaterialX shaders - but this originally came up because I was trying to wrap my head around MaterialX.)
The basic shader tutorials make it look like I would do something that’s essentially
shader = UsdShade.Shader.Define(stage, shader_primpath)
shader.CreateIdAttr("ND_standard_surface_surfaceshader")
# hunt down the MaterialX docs and shader.CreateInput(...) each of the inputs
# and the outputs.
but I keep thinking… that can’t be right.
Though that is basically how the tutorial puts together a preview shader.
I know there’s a UsdMtlx, but I can only find an overview doc, but not an api description, and am having a heck of a time trying to figure out what I can do with it.
I found some code - I think in the USD source for parsing materialx, and found out about Sdr.Registry(). With that, it looks like maybe I can:
>>> sdr = Sdr.Registry()
>>> sdn = sdr.GetShaderNodeByIdentifier("ND_standard_surface_surfaceshader")
>>> sdn.GetInputNames()
['base', 'base_color', 'diffuse_roughness', 'metalness', 'specular', 'specular_color', 'specula
r_roughness', 'specular_IOR', 'specular_anisotropy', 'specular_rotation', 'transmission', 'tran
smission_color', 'transmission_depth', 'transmission_scatter', 'transmission_scatter_anisotropy
', 'transmission_dispersion', 'transmission_extra_roughness', 'subsurface', 'subsurface_color',
'subsurface_radius', 'subsurface_scale', 'subsurface_anisotropy', 'sheen', 'sheen_color', 'she
en_roughness', 'coat', 'coat_color', 'coat_roughness', 'coat_anisotropy', 'coat_rotation', 'coa
t_IOR', 'coat_normal', 'coat_affect_color', 'coat_affect_roughness', 'thin_film_thickness', 'th
in_film_IOR', 'emission', 'emission_color', 'opacity', 'thin_walled', 'normal', 'tangent']
# then loop through those, getting the shader properties like
>>> base_color_input = sdn.GetShaderInput("base_color")
>>> base_color_input.GetDefaultValue()
Gf.Vec3f(0.800000011920929, 0.800000011920929, 0.800000011920929)
>>> base_color_input.GetType()
'float'
And use the properties to shader.CreateInput(…)
Though… in the above example, I notice that the default is a Vec3f, but the type is only given as “float” - not even “float3”, so I was also wondering if there’s another function I can use to find out that it is a vector?
It feels like this is a little bit better, but still feels like there would be an easier way like:
-
Can I more directly CreateInput(some pxr.Sdr.ShaderProperty) ?
-
Better yet, can I more directly do something like sdn.Define(shader_primpath) where sdn is a pxr.Sdr.ShaderNode that would set up all the inputs and outputs, maybe even with their default values?
-
Did the “ND_standard_surface_surfaceshader” come from Usd? I’m in HoudiniSolaris (in a python shell pane), so I wasn’t sure if it came from Solaris, or if it’s natively defined in Usd? In some of the random code I found googling, it looked like the ND_ was maybe a standard in USD? Also, here it looked like though it is materialx, it considered its render context to be “karma”. I guess what I’m getting at is: do I get these shaders outside of houdini - like in usdview? Who populates the registry and when?