Skip to content

Commit

Permalink
connect the opacity on the transmission (Autodesk#1252)
Browse files Browse the repository at this point in the history
* connect the opacity on the transmission

* remove useless cout

* add constant string "transmission"

* add a substract node to convert opacity to transmission in the procedural

* add testsuite for issue Autodesk#1204

* remap opacity after converting it

* fix type mismatch resulting from a GfVec4 multiplication

* interpret primvarreader_xxx::varname as a string as well as a token

* reorder alphabetically

* add reference image and bigger donuts

(cherry picked from commit 9c28596)
  • Loading branch information
cpichard authored and sebastienblor committed Aug 18, 2022
1 parent 8cb7544 commit b724ec2
Show file tree
Hide file tree
Showing 7 changed files with 397 additions and 11 deletions.
3 changes: 3 additions & 0 deletions common/constant_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ ASTR(indirect_sample_clamp);
ASTR(inherit_xform);
ASTR(input);
ASTR(inputs);
ASTR(input1);
ASTR(input2);
ASTR(instance_inherit_xform);
ASTR(instance_matrix);
ASTR(instance_motion_end);
Expand Down Expand Up @@ -427,6 +429,7 @@ ASTR(threads);
ASTR(top);
ASTR(total_progress);
ASTR(translation);
ASTR(transmission);
ASTR(twrap);
ASTR(uniform);
ASTR(useMetadata);
Expand Down
22 changes: 19 additions & 3 deletions render_delegate/node_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,14 @@ RemapNodeFunc previewSurfaceRemap = [](MaterialEditContext* ctx) {
ctx->RenameParam(str::t_metalness, str::t_metallic);
}

// Float opacity needs to be remapped to color.
// Float opacity needs to be remapped to 1 - transmission
const auto opacityValue = ctx->GetParam(str::t_opacity);
if (opacityValue.IsHolding<float>()) {
const auto opacity = opacityValue.UncheckedGet<float>();
ctx->SetParam(str::t_opacity, VtValue(GfVec3f(opacity, opacity, opacity)));
ctx->SetParam(str::t_opacity, VtValue(1.f - opacity));
}

ctx->RenameParam(str::t_opacity, str::t_transmission);

ctx->RenameParam(str::t_diffuseColor, str::t_base_color);
ctx->RenameParam(str::t_emissiveColor, str::t_emission_color);
ctx->RenameParam(str::t_roughness, str::t_specular_roughness);
Expand Down Expand Up @@ -402,6 +403,21 @@ void _RemapNetwork(HdMaterialNetwork& network, bool isDisplacement)
relationship.outputId = SdfPath();
}
}
// We test if a texture is connected to the opacity, and if it is we invert it as later on we remap
// the opacity to the transparency. It is a workaround and might be problematic if the texture is
// connected to other nodes which don't expect an inverted texture.
if (relationship.outputName == str::t_opacity) {
for (auto& material : network.nodes) {
if (material.path == relationship.inputId && material.identifier == str::t_UsdUVTexture) {
auto scaleFound = material.parameters.find(str::t_scale);
auto biasFound = material.parameters.find(str::t_bias);
GfVec4f oriBias = (biasFound == material.parameters.end()) ? GfVec4f(0.f) : biasFound->second.Get<GfVec4f>();
GfVec4f oriScale = (scaleFound == material.parameters.end()) ? GfVec4f(1.f) : scaleFound->second.Get<GfVec4f>();
material.parameters[str::t_scale] = VtValue(oriScale*-1.f);
material.parameters[str::t_bias] = VtValue(GfVec4f(1.f)-oriBias);
}
}
}
}

for (auto& material : network.nodes) {
Expand Down
7 changes: 7 additions & 0 deletions testsuite/test_1204/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Surface opacity should translate to arnold transmission

See #1204

author: cyril.pichard

PARAMS: {'scene':'test.usd', 'resaved':'scene.ass'}
Binary file added testsuite/test_1204/data/opacity.exr
Binary file not shown.
341 changes: 341 additions & 0 deletions testsuite/test_1204/data/test.usd

Large diffs are not rendered by default.

Binary file added testsuite/test_1204/ref/reference.tif
Binary file not shown.
35 changes: 27 additions & 8 deletions translator/reader/read_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,17 +224,24 @@ void UsdArnoldReadShader::Read(const UsdPrim &prim, UsdArnoldReaderContext &cont

// Opacity is a bit complicated as it's a scalar value in USD, but a color in Arnold.
// So we need to set it properly (see #998)
AiNodeSetRGB(node, str::opacity, 1.f, 1.f, 1.f);
// Arnold RGB opacity 1, 1, 1
// Arnold FLOAT transmission 0
// USD FLOAT opacity
//AiNodeSetRGB(node, str::opacity, 1.f, 1.f, 1.f);
UsdShadeInput opacityInput = shader.GetInput(str::t_opacity);
if (opacityInput) {
float opacity;
// if the opacity attribute is linked, we can go through the usual read function
const std::string subtractNodeName = nodeName + "@subtract";
AtNode *subtractNode = context.CreateArnoldNode("subtract", subtractNodeName.c_str());
AiNodeSetRGB(subtractNode, str::input1, 1.f, 1.f, 1.f);
float opacity;
if (opacityInput.HasConnectedSource()) {
_ReadBuiltinShaderParameter(shader, node, "opacity", "opacity", context);
_ReadBuiltinShaderParameter(shader, subtractNode, "opacity", "input2", context);
} else if (opacityInput.Get(&opacity, time.frame)) {
// convert the input float value as RGB in the arnold shader
AiNodeSetRGB(node, str::opacity, opacity, opacity, opacity);
AiNodeSetRGB(subtractNode, str::input2, opacity, opacity, opacity);
}
AiNodeLink(subtractNode, "transmission", node);
}

UsdShadeInput normalInput = shader.GetInput(str::t_normal);
Expand Down Expand Up @@ -272,11 +279,23 @@ void UsdArnoldReadShader::Read(const UsdPrim &prim, UsdArnoldReaderContext &cont
std::string uvShaderId = uvId.GetString();
if (uvShaderId.length() > 18 && uvShaderId.substr(0, 17) == "UsdPrimvarReader_") {
// get uvShader attribute inputs:varname and set it as uvset
// From version 2.3 of the USD Preview Surface Proposal
// varname input type is changed from token to string. We check both as we can be
// reading files authored with old usd versions
UsdShadeInput varnameInput = uvShader.GetInput(str::t_varname);
TfToken varname;
if (varnameInput.Get(&varname, time.frame)) {
AiNodeSetStr(node, str::uvset, AtString(varname.GetText()));
exportSt = false;
const SdfValueTypeName varnameInputType = varnameInput.GetTypeName();
if (varnameInputType==SdfValueTypeNames->String) {
std::string varname;
if (varnameInput.Get(&varname, time.frame)) {
AiNodeSetStr(node, str::uvset, AtString(varname.c_str()));
exportSt = false;
}
} else if (varnameInputType==SdfValueTypeNames->Token) {
TfToken varname;
if (varnameInput.Get(&varname, time.frame)) {
AiNodeSetStr(node, str::uvset, AtString(varname.GetText()));
exportSt = false;
}
}
}
}
Expand Down

0 comments on commit b724ec2

Please sign in to comment.