Hi,
I’m getting a little hung up on textures and materials in Omniverse Connectors.
We have a database of materials and textures that we’re pulling from. The source file going into the connector eventually returns a material name and subidentifier for an mdl that are then used to look up that material in the database and append it to the relevant mesh. This has generally worked very well, but textures have to be reapplied manually to the resulting USD file.
Right now I have this function that I made based off of the CreateMaterial function in the connect sample:
static void appendMaterialtoMesh(UsdGeomMesh meshIn, std::string& materialName, std::string& materialPath, UsdStageRefPtr stagePointer)
{
// Create a material instance for this in USD
TfToken materialNameToken(materialName);
// Make path in the tree structure of the USD file;
SdfPath matPath = SdfPath::AbsoluteRootPath()
.AppendChild(_tokens->Root)
.AppendChild(_tokens->Looks)
.AppendChild(materialNameToken);
UsdShadeMaterial newMat = UsdShadeMaterial::Define(stagePointer, matPath);
// MDL Shader
{
// Create the MDL shader to bind to the material
SdfAssetPath mdlShaderModule = SdfAssetPath(materialPath);
SdfPath shaderPath = matPath.AppendChild(materialNameToken);
UsdShadeShader mdlShader = UsdShadeShader::Define(stagePointer, shaderPath);
mdlShader.CreateIdAttr(VtValue(_tokens->shaderId)); //this line will break if we don't associate our stage properly - check stagePointer if this breaks
// These attributes will be reworked or replaced in the official MDL schema for USD.
// https://developer.nvidia.com/usd/MDLschema
mdlShader.SetSourceAsset(mdlShaderModule, _tokens->mdl);
mdlShader.GetPrim().CreateAttribute(TfToken("info:mdl:sourceAsset:subIdentifier"), SdfValueTypeNames->Token, false, SdfVariabilityUniform).Set(materialNameToken);
// Set the linkage between material and MDL shader
UsdShadeOutput mdlOutput = newMat.CreateSurfaceOutput(_tokens->mdl);
mdlOutput.ConnectToSource(mdlShader, _tokens->out);
}
// Final step, associate the material with the face
UsdShadeMaterialBindingAPI usdMaterialBinding(meshIn);
usdMaterialBinding.Bind(newMat);
// Commit the changes to the USD
stagePointer->Save();
omniUsdLiveProcess();
}
which gives me this in the property window upon conversion (no texture selection):
I can then go into Create and edit the parent material inside the material graph - adding a bitmap texture giving me the file selection box I’m looking for. (as well as bump/normal maps)
My main question is: How do I automate the addition of textures (albedo/color map most importantly) like this via c++? I assume it’s going to be similar to the way the ‘subIdentifier’ was defined as a parameter but I can’t seem to find any example.
It doesn’t have to be defined as a NodeGraph either, that’s just the way I know how to do it in Create. I have conversions of materials out of IRay that don’t rely on Create’s Node Graph at all. Here’s what they look like:
I can’t use these in my material library though because they’re generated at runtime as part of the USD in this IRay->USD conversion, and it appears Create doesn’t support exporting mdls.
Two other important considerations are:
-How do materials and textures combine for rendering in Create? Do textures replace or multiply/modulate? Can I control which?
-I will likely need the same material multiple times with different textures, meaning I’ll need multiple instances of the same material unless there’s some way to designate a texture subidentifier on the mesh itself.
I appreciate any insight, thank you!
-Matthew