Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion source/MaterialXCore/Material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ vector<NodePtr> getShaderNodes(NodePtr materialNode, const string& nodeType, con
}
}

if (inputs.empty())
if (shaderNodeVec.empty())
{
// Try to find material nodes in the implementation graph if any.
// If a target is specified the nodedef for the given target is searched for.
Expand Down
9 changes: 8 additions & 1 deletion source/MaterialXGenHw/HwShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <MaterialXGenHw/HwConstants.h>
#include <MaterialXGenHw/HwLightShaders.h>
#include <MaterialXGenHw/Nodes/HwLightCompoundNode.h>
#include <MaterialXGenHw/Nodes/HwMaterialCompoundNode.h>
#include <MaterialXGenShader/Exception.h>
#include <MaterialXGenShader/Nodes/CompoundNode.h>
#include <MaterialXGenShader/GenContext.h>
Expand Down Expand Up @@ -400,11 +401,17 @@ ShaderNodeImplPtr HwShaderGenerator::createShaderNodeImplForNodeGraph(const Node

const TypeDesc outputType = _typeSystem->getType(outputs[0]->getType());

// Use a compound implementation.
// Use specialized implementations for nodes that output light shaders and materials.
if (outputType == Type::LIGHTSHADER)
{
return HwLightCompoundNode::create();
}
if (outputType == Type::MATERIAL)
{
return HwMaterialCompoundNode::create();
}

// Use the base implementation for nodes that output other types.
return CompoundNode::create();
}

Expand Down
99 changes: 99 additions & 0 deletions source/MaterialXGenHw/Nodes/HwMaterialCompoundNode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#include <MaterialXGenHw/Nodes/HwMaterialCompoundNode.h>

#include <MaterialXGenShader/ShaderNode.h>

#include <MaterialXCore/Definition.h>
#include <MaterialXCore/Node.h>

MATERIALX_NAMESPACE_BEGIN

namespace
{

const string MATERIAL_TYPE = "material";
const string SURFACE_CATEGORY = "surface";

} // anonymous namespace

ShaderNodeImplPtr HwMaterialCompoundNode::create()
{
return std::make_shared<HwMaterialCompoundNode>();
}

void HwMaterialCompoundNode::initialize(const InterfaceElement& element, GenContext& context)
{
ShaderNodeImpl::initialize(element, context);

if (!element.isA<NodeGraph>())
{
return;
}

const NodeGraph& graph = static_cast<const NodeGraph&>(element);

// Find the material-type output and traverse upstream to discover the
// surface node, reading its bsdf/edf/opacity interface name mappings.
for (OutputPtr output : graph.getOutputs())
{
if (output->getType() == MATERIAL_TYPE)
{
for (Edge edge : output->traverseGraph())
{
ElementPtr upstream = edge.getUpstreamElement();
NodePtr upstreamNode = upstream ? upstream->asA<Node>() : nullptr;
if (upstreamNode && upstreamNode->getCategory() == SURFACE_CATEGORY)
{
InputPtr bsdfIn = upstreamNode->getInput("bsdf");
if (bsdfIn && !bsdfIn->getInterfaceName().empty())
{
_bsdfInputName = bsdfIn->getInterfaceName();
}

InputPtr edfIn = upstreamNode->getInput("edf");
if (edfIn && !edfIn->getInterfaceName().empty())
{
_edfInputName = edfIn->getInterfaceName();
}

InputPtr opacityIn = upstreamNode->getInput("opacity");
if (opacityIn && !opacityIn->getInterfaceName().empty())
{
_opacityInputName = opacityIn->getInterfaceName();
}

return;
}
}
}
}
}

void HwMaterialCompoundNode::addClassification(ShaderNode& node) const
{
// Add SHADER|SURFACE so the top-level graph triggers the
// surface shader code path in the HW pixel shader generators.
node.addClassification(ShaderNode::Classification::SHADER |
ShaderNode::Classification::SURFACE);
}

const string& HwMaterialCompoundNode::getBsdfInputName() const
{
return _bsdfInputName;
}

const string& HwMaterialCompoundNode::getEdfInputName() const
{
return _edfInputName;
}

const string& HwMaterialCompoundNode::getOpacityInputName() const
{
return _opacityInputName;
}

MATERIALX_NAMESPACE_END
36 changes: 36 additions & 0 deletions source/MaterialXGenHw/Nodes/HwMaterialCompoundNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#ifndef MATERIALX_HWMATERIALCOMPOUNDNODE_H
#define MATERIALX_HWMATERIALCOMPOUNDNODE_H

#include <MaterialXGenHw/Nodes/HwSurfaceNode.h>

MATERIALX_NAMESPACE_BEGIN

/// MaterialCompound node implementation for hardware languages.
/// Used for nodegraphs that output material type, such as LamaSurface.
class MX_GENHW_API HwMaterialCompoundNode : public HwSurfaceNode
{
public:
static ShaderNodeImplPtr create();

void initialize(const InterfaceElement& element, GenContext& context) override;
void addClassification(ShaderNode& node) const override;

protected:
const string& getBsdfInputName() const override;
const string& getEdfInputName() const override;
const string& getOpacityInputName() const override;

private:
string _bsdfInputName;
string _edfInputName;
string _opacityInputName;
};

MATERIALX_NAMESPACE_END

#endif
Loading
Loading