-
-
Notifications
You must be signed in to change notification settings - Fork 63
Closed
Labels
Description
When authoring a connection to UsdPreviewSurface.inputs:diffuseColor, TinyUSDZ does not serialize the relationship into USDA. I tested both ways:
Setting the connection on the typed attribute (UsdPreviewSurface::diffuseColor.connect.set(Path(...)))
Setting a relationship via Shader.props["inputs:diffuseColor.connect"]
In both cases, the generated USDA is missing the expected
rel inputs:diffuseColor.connect = </.../Image_Texture.outputs:rgb>
Note: A connection for UsdUVTexture.inputs:st does serialize correctly when authored as texShader.props["inputs:st.connect"], so the issue appears specific to UsdPreviewSurface.inputs:diffuseColor.
To Reproduce
#include <iostream>
#include "tinyusdz.hh"
int main() {
using namespace tinyusdz;
Stage stage;
// /Materials scope
Scope s; s.name = "Materials";
Prim matScope(s);
stage.add_root_prim(Prim(s));
stage.commit();
// Material "M"
Material m; m.name = "M";
Prim matPrim(m);
// Shader "Principled_BSDF" (UsdPreviewSurface)
Shader pbr; pbr.name = "Principled_BSDF"; pbr.info_id = kUsdPreviewSurface;
UsdPreviewSurface surf;
surf.outputsSurface.set_authored(true);
// IMPORTANT: do NOT author a default diffuseColor when connecting
pbr.value = surf;
Prim pbrPrim(pbr);
matPrim.add_child(std::move(pbrPrim), /*rename=*/true, nullptr);
// Shader "Image_Texture" (UsdUVTexture)
Shader tex; tex.name = "Image_Texture"; tex.info_id = kUsdUVTexture;
UsdUVTexture uvtex;
uvtex.outputsRgb.set_authored(true);
uvtex.file = value::AssetPath("./textures/bk.png");
tex.value = uvtex;
Prim texPrim(tex);
matPrim.add_child(std::move(texPrim), /*rename=*/true, nullptr);
// Shader "uvmap" (UsdPrimvarReader_float2)
Shader uv; uv.name = "uvmap"; uv.info_id = kUsdPrimvarReader_float2;
UsdPrimvarReader_float2 stnode;
stnode.result.set_authored(true);
stnode.varname.set_value(std::string("st"));
uv.value = stnode;
Prim uvPrim(uv);
matPrim.add_child(std::move(uvPrim), /*rename=*/true, nullptr);
// Put Material under /Materials and commit to stabilize paths
// (re-fetch scope since we moved it into Stage)
Prim *materials = nullptr;
for (auto &r : stage.root_prims()) if (r.element_name() == "Materials") materials = &r;
materials->add_child(std::move(matPrim), /*rename=*/true, nullptr);
stage.commit();
// Resolve children
Prim &addedMat = materials->children().back();
Prim *pPrincipled=nullptr, *pTex=nullptr, *pUvmap=nullptr;
for (auto &ch : addedMat.children()) {
if (const Shader* s = ch.as<Shader>()) {
if (s->info_id == kUsdPreviewSurface) pPrincipled = &ch;
else if (s->info_id == kUsdUVTexture) pTex = &ch;
else if (s->info_id == kUsdPrimvarReader_float2) pUvmap = &ch;
}
}
// Hook Material.outputs:surface -> Principled_BSDF.outputs:surface
if (pPrincipled) {
Material mm = *addedMat.as<Material>();
mm.surface.set(Path(pPrincipled->absolute_path().full_path_name(), "outputs:surface"));
addedMat.set_primdata(addedMat.element_name(), mm);
}
// inputs:st.connect (works)
if (pTex && pUvmap) {
Shader texS = *pTex->as<Shader>();
Relationship r; r.set(Path(pUvmap->absolute_path().full_path_name(), "outputs:result"));
texS.props["inputs:st.connect"] = Property(r);
pTex->set_primdata(pTex->element_name(), texS);
}
// inputs:diffuseColor.connect (DOES NOT SERIALIZE)
// A) Typed-attribute way (expected to work, but currently does not)
if (pPrincipled && pTex) {
Shader pv = *pPrincipled->as<Shader>();
if (auto *node = pv.value.as<UsdPreviewSurface>()) {
node->diffuseColor.connect.set(
Path(pTex->absolute_path().full_path_name(), "outputs:rgb"));
pv.value = *node;
pPrincipled->set_primdata(pPrincipled->element_name(), pv);
}
}
// // B) Props way (also does not serialize for UsdPreviewSurface)
// if (pPrincipled && pTex) {
// Shader pv = *pPrincipled->as<Shader>();
// Relationship r; r.set(Path(pTex->absolute_path().full_path_name(), "outputs:rgb"));
// pv.props["inputs:diffuseColor.connect"] = Property(r);
// pPrincipled->set_primdata(pPrincipled->element_name(), pv);
// }
stage.commit();
std::string warn, err;
usda::SaveAsUSDA("repro.usda", stage, &warn, &err);
if (!warn.empty()) std::cout << "WARN: " << warn << "\n";
if (!err.empty()) std::cout << "ERR : " << err << "\n";
return 0;
}
Actual USDA
def Material "M" {
token outputs:surface.connect = </Materials/M/Principled_BSDF.outputs:surface>
def Shader "Principled_BSDF" {
uniform token info:id = "UsdPreviewSurface"
token outputs:surface
// Missing: rel inputs:diffuseColor.connect = </Materials/M/Image_Texture.outputs:rgb>
}
def Shader "Image_Texture" {
uniform token info:id = "UsdUVTexture"
asset inputs:file = @./textures/bk.png@
float3 outputs:rgb
}
def Shader "uvmap" {
uniform token info:id = "UsdPrimvarReader_float2"
string inputs:varname = "st"
float2 outputs:result
}
}
Expected behavior / Expected USDA
def Material "M" {
token outputs:surface.connect = </Materials/M/Principled_BSDF.outputs:surface>
def Shader "Principled_BSDF" {
uniform token info:id = "UsdPreviewSurface"
token outputs:surface
rel inputs:diffuseColor.connect = </Materials/M/Image_Texture.outputs:rgb>
}
def Shader "Image_Texture" {
uniform token info:id = "UsdUVTexture"
asset inputs:file = @./textures/bk.png@
float3 outputs:rgb
}
def Shader "uvmap" {
uniform token info:id = "UsdPrimvarReader_float2"
string inputs:varname = "st"
float2 outputs:result
}
}