Closed zanazakaryaie closed 2 years ago
Hi @zanazakaryaie ,
In general, there may be no single purpose for a given texture, as it is common to pack three or four scalar signals into an RGB or RGBA texture. To determine intent for a given texture, you will need to follow the connection from an input attribute that consumes it. This implies you need to do a specialized sub-traversal when you see a UsdShadeMaterial prim.
So, in your code, dispense with the global variable for accessing a Material
, and instead call out to your fillMaterial() which takes a UsdShadeMaterial as its USD-side argument. It will then follow the outputs:surface
terminal's connection to find the UsdPreviewSurface Shader prim (and if it doesn't find a shader whose info:id
is not "UsdPreviewSurface" you probably can't do anything with the Material). Then you can iterate through the Shader's inputs, looking for connections or values, processing the connected prims if needed.
The are API's to help you do this... I would suggest looking at the simple shading tutorial script, which although Python, shows you the principal API's involved. I think you'll find UsdShadeUtils::GetValueProducingAttributes()
quite handy as it embodies all the logic for finding the attribute that will be of interest to you, given an input on the PreviewSurface prim.
There are also facilities for performing traversals, some that even allow pruning (as you would want to do when you hit a Material), e.g. UsdPrimRange::iterator
has a PruneChildren()
method.
Finally, rather than comparing hardcoded strings to identify prim types, it is both more efficient and much more robust to do:
if (prim.IsA<UsdShadeMaterial>()) ...
Cheers!
Hi @spiffmon Thanks a lot for your guide. It was very informative
Description of Issue
I'm using USD for loading a .usdc file. I have successfully extracted mesh information (number of vertices, normals, etc.) from UsdGeomMesh. I can also get the texture filepath from UsdShadeShader but can't figure out the texture type (diffuse, normal, ambient occlusion, etc.) of the file. I need to know this for rendering in my own engine.
Steps to Reproduce
void Traverse(const UsdPrim &prim, int depth) { if (prim.GetTypeName().GetString() == "Xform") { getGeometricTransformations(prim); } else if (prim.GetTypeName().GetString() == "Mesh") { auto mesh = getMesh(prim); //some code for printing mesh } else if (prim.GetTypeName().GetString() == "Material") { material = new Material(); //my own class for represnting material } else if (prim.GetTypeName().GetString() == "Shader") { fillMaterial(prim, material); }
for (UsdPrim const& c : prim.GetChildren()) Traverse(c, depth + 1); }
void fillMaterial(const UsdPrim &prim, Material* material) { UsdShadeShader shader(prim); std::vector inputs = shader.GetInputs();
for (const auto& shadeinput : inputs) { const auto shaderName = shadeinput.GetFullName().GetString();
} }