Skip to content

Commit

Permalink
Enable color and unit transforms on root nodes (#1757)
Browse files Browse the repository at this point in the history
This changelist adds support for color and unit transforms on the root nodes that are passed into shader generation, where previously they were only supported on non-root nodes in the material graph.

In MaterialX 1.38.9, a special-case pathway for root surface shader nodes was merged into the main logic, causing color transforms in some USD/MaterialX contexts to be omitted, and this changelist restores and generalizes the original approach to handle all root nodes.
  • Loading branch information
jstone-lucasfilm committed Apr 1, 2024
1 parent 281320c commit 710f272
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 44 deletions.
98 changes: 54 additions & 44 deletions source/MaterialXGenShader/ShaderGraph.cpp
Expand Up @@ -569,6 +569,7 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name
}
}

input->setBindInput();
const string path = nodeInput->getNamePath();
if (!path.empty())
{
Expand Down Expand Up @@ -596,6 +597,9 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name
inputSocket->setMetadata(input->getMetadata());
}

// Apply color and unit transforms to each input.
graph->applyInputTransforms(node, newNode, context);

// Set root for upstream dependency traversal
root = node;
}
Expand All @@ -616,6 +620,54 @@ ShaderGraphPtr ShaderGraph::create(const ShaderGraph* parent, const string& name
return graph;
}

void ShaderGraph::applyInputTransforms(ConstNodePtr node, ShaderNodePtr shaderNode, GenContext& context)
{
ColorManagementSystemPtr colorManagementSystem = context.getShaderGenerator().getColorManagementSystem();
UnitSystemPtr unitSystem = context.getShaderGenerator().getUnitSystem();

const string& targetColorSpace = context.getOptions().targetColorSpaceOverride.empty() ?
_document->getActiveColorSpace() :
context.getOptions().targetColorSpaceOverride;
const string& targetDistanceUnit = context.getOptions().targetDistanceUnit;

for (InputPtr input : node->getInputs())
{
if (input->hasValue() || input->hasInterfaceName())
{
string sourceColorSpace = input->getActiveColorSpace();
if (input->getType() == FILENAME_TYPE_STRING && node->isColorType())
{
// Adjust the source color space for filename interface names.
if (input->hasInterfaceName())
{
for (ConstNodePtr parentNode : context.getParentNodes())
{
if (!parentNode->isColorType())
{
InputPtr interfaceInput = parentNode->getInput(input->getInterfaceName());
string interfaceColorSpace = interfaceInput ? interfaceInput->getActiveColorSpace() : EMPTY_STRING;
if (!interfaceColorSpace.empty())
{
sourceColorSpace = interfaceColorSpace;
}
}
}
}

ShaderOutput* shaderOutput = shaderNode->getOutput();
populateColorTransformMap(colorManagementSystem, shaderOutput, sourceColorSpace, targetColorSpace, false);
populateUnitTransformMap(unitSystem, shaderOutput, input, targetDistanceUnit, false);
}
else
{
ShaderInput* shaderInput = shaderNode->getInput(input->getName());
populateColorTransformMap(colorManagementSystem, shaderInput, sourceColorSpace, targetColorSpace, true);
populateUnitTransformMap(unitSystem, shaderInput, input, targetDistanceUnit, true);
}
}
}
}

ShaderNode* ShaderGraph::createNode(ConstNodePtr node, GenContext& context)
{
NodeDefPtr nodeDef = node->getNodeDef();
Expand Down Expand Up @@ -669,50 +721,8 @@ ShaderNode* ShaderGraph::createNode(ConstNodePtr node, GenContext& context)
}
}

// Handle colorspace and unit conversion if needed.
ColorManagementSystemPtr colorManagementSystem = context.getShaderGenerator().getColorManagementSystem();
UnitSystemPtr unitSystem = context.getShaderGenerator().getUnitSystem();
const string& targetColorSpace = context.getOptions().targetColorSpaceOverride.empty() ?
_document->getActiveColorSpace() :
context.getOptions().targetColorSpaceOverride;
const string& targetDistanceUnit = context.getOptions().targetDistanceUnit;

for (InputPtr input : node->getInputs())
{
if (input->hasValue() || input->hasInterfaceName())
{
string sourceColorSpace = input->getActiveColorSpace();
if (input->getType() == FILENAME_TYPE_STRING && node->isColorType())
{
// Adjust the source color space for filename interface names.
if (input->hasInterfaceName())
{
for (ConstNodePtr parentNode : context.getParentNodes())
{
if (!parentNode->isColorType())
{
InputPtr interfaceInput = parentNode->getInput(input->getInterfaceName());
string interfaceColorSpace = interfaceInput ? interfaceInput->getActiveColorSpace() : EMPTY_STRING;
if (!interfaceColorSpace.empty())
{
sourceColorSpace = interfaceColorSpace;
}
}
}
}

ShaderOutput* shaderOutput = newNode->getOutput();
populateColorTransformMap(colorManagementSystem, shaderOutput, sourceColorSpace, targetColorSpace, false);
populateUnitTransformMap(unitSystem, shaderOutput, input, targetDistanceUnit, false);
}
else
{
ShaderInput* shaderInput = newNode->getInput(input->getName());
populateColorTransformMap(colorManagementSystem, shaderInput, sourceColorSpace, targetColorSpace, true);
populateUnitTransformMap(unitSystem, shaderInput, input, targetDistanceUnit, true);
}
}
}
// Apply color and unit transforms to each input.
applyInputTransforms(node, newNode, context);

return newNode.get();
}
Expand Down
3 changes: 3 additions & 0 deletions source/MaterialXGenShader/ShaderGraph.h
Expand Up @@ -92,6 +92,9 @@ class MX_GENSHADER_API ShaderGraph : public ShaderNode
const vector<ShaderGraphInputSocket*>& getInputSockets() const { return _outputOrder; }
const vector<ShaderGraphOutputSocket*>& getOutputSockets() const { return _inputOrder; }

/// Apply color and unit transforms to each input of a node.
void applyInputTransforms(ConstNodePtr node, ShaderNodePtr shaderNode, GenContext& context);

/// Create a new node in the graph
ShaderNode* createNode(ConstNodePtr node, GenContext& context);

Expand Down

0 comments on commit 710f272

Please sign in to comment.