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
6 changes: 3 additions & 3 deletions libraries/pbrlib/genmdl/pbrlib_genmdl_impl.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<materialx version="1.39">

<!-- <oren_nayar_diffuse_bsdf> -->
<implementation name="IM_oren_nayar_diffuse_bsdf_genmdl" nodedef="ND_oren_nayar_diffuse_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_oren_nayar_diffuse_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}})" target="genmdl" />
<implementation name="IM_oren_nayar_diffuse_bsdf_genmdl" nodedef="ND_oren_nayar_diffuse_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_oren_nayar_diffuse_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}}, mxp_energy_compensation:{{energy_compensation}})" target="genmdl" />

<!-- <burley_diffuse_bsdf> -->
<implementation name="IM_burley_diffuse_bsdf_genmdl" nodedef="ND_burley_diffuse_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_burley_diffuse_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_roughness:{{roughness}}, mxp_normal:{{normal}})" target="genmdl" />
Expand All @@ -11,13 +11,13 @@
<implementation name="IM_translucent_bsdf_genmdl" nodedef="ND_translucent_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_translucent_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_normal:{{normal}})" target="genmdl" />

<!-- <dielectric_bsdf> -->
<implementation name="IM_dielectric_bsdf_genmdl" nodedef="ND_dielectric_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_dielectric_bsdf(mxp_weight:{{weight}}, mxp_tint:{{tint}}, mxp_ior:{{ior}}, mxp_roughness:{{roughness}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}})" target="genmdl" />
<implementation name="IM_dielectric_bsdf_genmdl" nodedef="ND_dielectric_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_dielectric_bsdf(mxp_weight:{{weight}}, mxp_tint:{{tint}}, mxp_ior:{{ior}}, mxp_roughness:{{roughness}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}}, mxp_top_weight:{{top_weight}})" target="genmdl" />

<!-- <conductor_bsdf> -->
<implementation name="IM_conductor_bsdf_genmdl" nodedef="ND_conductor_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_conductor_bsdf(mxp_weight:{{weight}}, mxp_ior:{{ior}}, mxp_extinction:{{extinction}}, mxp_roughness:{{roughness}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}})" target="genmdl" />

<!-- <generalized_schlick_bsdf> -->
<implementation name="IM_generalized_schlick_bsdf_genmdl" nodedef="ND_generalized_schlick_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_generalized_schlick_bsdf(mxp_weight:{{weight}}, mxp_color0:{{color0}}, mxp_color90:{{color90}}, mxp_exponent:{{exponent}},mxp_roughness:{{roughness}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}})" target="genmdl" />
<implementation name="IM_generalized_schlick_bsdf_genmdl" nodedef="ND_generalized_schlick_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_generalized_schlick_bsdf(mxp_weight:{{weight}}, mxp_color0:{{color0}}, mxp_color82:{{color82}}, mxp_color90:{{color90}}, mxp_exponent:{{exponent}},mxp_roughness:{{roughness}}, mxp_thinfilm_thickness:{{thinfilm_thickness}}, mxp_thinfilm_ior:{{thinfilm_ior}}, mxp_normal:{{normal}}, mxp_tangent:{{tangent}}, mxp_distribution:{{distribution}}, mxp_scatter_mode:{{scatter_mode}}, mxp_base:{{base}}, mxp_top_weight:{{top_weight}})" target="genmdl" />

<!-- <subsurface_bsdf> -->
<implementation name="IM_subsurface_bsdf_genmdl" nodedef="ND_subsurface_bsdf" sourcecode="materialx::pbrlib_{{MDL_VERSION_SUFFIX}}::mx_subsurface_bsdf(mxp_weight:{{weight}}, mxp_color:{{color}}, mxp_radius:{{radius}}, mxp_anisotropy:{{anisotropy}}, mxp_normal:{{normal}})" target="genmdl" />
Expand Down
2 changes: 1 addition & 1 deletion libraries/stdlib/genmdl/stdlib_genmdl_impl.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@
<implementation name="IM_combine3_vector3_genmdl" nodedef="ND_combine3_vector3" target="genmdl" sourcecode="float3( {{in1}},{{in2}},{{in3}} )" />

<!-- <combine4> -->
<implementation name="IM_combine4_color4_genmdl" nodedef="ND_combine4_color4" target="genmdl" sourcecode="color4( {{in1}},{{in2}},{{in3}},{{in4}} )" />
<implementation name="IM_combine4_color4_genmdl" nodedef="ND_combine4_color4" target="genmdl" sourcecode="materialx::core::mk_color4( {{in1}},{{in2}},{{in3}},{{in4}} )" />
<implementation name="IM_combine4_vector4_genmdl" nodedef="ND_combine4_vector4" target="genmdl" sourcecode="float4( {{in1}},{{in2}},{{in3}},{{in4}} )" />

<!-- <creatematrix> -->
Expand Down
89 changes: 77 additions & 12 deletions source/MaterialXGenMdl/MdlShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ const string IMPORT_ALL = " import *";
const string MDL_VERSION_1_6 = "1.6";
const string MDL_VERSION_1_7 = "1.7";
const string MDL_VERSION_1_8 = "1.8";
const string MDL_VERSION_1_9 = "1.9";
const string MDL_VERSION_SUFFIX_1_6 = "1_6";
const string MDL_VERSION_SUFFIX_1_7 = "1_7";
const string MDL_VERSION_SUFFIX_1_8 = "1_8";
const string MDL_VERSION_SUFFIX_1_9 = "1_9";

} // anonymous namespace

Expand Down Expand Up @@ -191,6 +193,27 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G
emitLineBreak(stage);
}

// Emit shader inputs that have been filtered during printing of the public interface
const string uniformPrefix = _syntax->getUniformQualifier() + " ";
for (ShaderGraphInputSocket* inputSocket : graph.getInputSockets())
{
if (inputSocket->getConnections().size() &&
(inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_SHADER ||
inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_CLOSURE ||
inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_MATERIAL))
{
const string& qualifier = inputSocket->isUniform() || inputSocket->getType() == Type::FILENAME
? uniformPrefix
: EMPTY_STRING;
const string& type = _syntax->getTypeName(inputSocket->getType());

emitLineBegin(stage);
emitString(qualifier + type + " " + inputSocket->getVariable() + " = ", stage);
emitString(_syntax->getDefaultValue(inputSocket->getType(), true), stage);
emitLineEnd(stage, true);
}
}

// Emit all texturing nodes. These are inputs to any
// closure/shader nodes and need to be emitted first.
emitFunctionCalls(graph, context, stage, ShaderNode::Classification::TEXTURE);
Expand All @@ -215,6 +238,7 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G
const string result = getUpstreamResult(outputSocket, context);

const TypeDesc outputType = outputSocket->getType();
// Try to return some meaningful color in case the output is not a material
if (graph.hasClassification(ShaderNode::Classification::TEXTURE))
{
if (outputType == Type::DISPLACEMENTSHADER)
Expand All @@ -229,7 +253,25 @@ ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, G
else
{
emitLine("float3 displacement__ = float3(0.0)", stage);
emitLine("color finalOutput__ = mk_color3(" + result + ")", stage);
std::string finalOutput = "mk_color3(0.0)";
if (outputType == Type::BOOLEAN)
finalOutput = result + " ? mk_color3(0.0, 1.0, 0.0) : mk_color3(1.0, 0.0, 0.0)";
else if (outputType == Type::INTEGER)
finalOutput = "mk_color3(" + result + " / 100)"; // arbitrary
else if (outputType == Type::FLOAT)
finalOutput = "mk_color3(" + result + ")";
else if (outputType == Type::VECTOR2)
finalOutput = "mk_color3(" + result + ".x, " + result + ".y, 0.0)";
else if (outputType == Type::VECTOR3)
finalOutput = "mk_color3(" + result + ")";
else if (outputType == Type::COLOR3)
finalOutput = result;
else if (outputType == Type::COLOR4)
finalOutput = result + ".rgb";
else if (outputType == Type::MATRIX33 || outputType == Type::MATRIX44)
finalOutput = "mk_color3(" + result + "[0][0], " + result + "[1][1], " + result + "[2][2])";

emitLine("color finalOutput__ = " + finalOutput, stage);
}

// End shader body
Expand Down Expand Up @@ -527,6 +569,13 @@ ShaderPtr MdlShaderGenerator::createShader(const string& name, ElementPtr elemen
// and are editable by users.
if (inputSocket->getConnections().size() && graph->isEditable(*inputSocket))
{
if (inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_SHADER ||
inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_CLOSURE ||
inputSocket->getType().getSemantic() == TypeDesc::SEMANTIC_MATERIAL)
{
continue;
}

inputs->add(inputSocket->getSelf());
}
}
Expand All @@ -537,7 +586,7 @@ ShaderPtr MdlShaderGenerator::createShader(const string& name, ElementPtr elemen
outputs->add(outputSocket->getSelf());
}

// MDL does not allow varying data connected to transmission IOR.
// MDL does not allow varying data connected to transmission IOR until MDL 1.9.
// We must find all uses of transmission IOR and make sure we don't
// have a varying connection to it. If a varying connection is found
// we break that connection and revert to using default value on that
Expand All @@ -552,8 +601,14 @@ ShaderPtr MdlShaderGenerator::createShader(const string& name, ElementPtr elemen
// this fix will disconnect the transmission IOR on the inside, but
// still support the connection to reflection IOR.
//
if (graph->hasClassification(ShaderNode::Classification::SHADER) ||
graph->hasClassification(ShaderNode::Classification::CLOSURE))
GenMdlOptions::MdlVersion version = getMdlVersion(context);
bool uniformIorRequired =
version == GenMdlOptions::MdlVersion::MDL_1_6 ||
version == GenMdlOptions::MdlVersion::MDL_1_7 ||
version == GenMdlOptions::MdlVersion::MDL_1_8;
if (uniformIorRequired && (
graph->hasClassification(ShaderNode::Classification::SHADER) ||
graph->hasClassification(ShaderNode::Classification::CLOSURE)))
{
// Find dependencies on transmission IOR.
std::set<ShaderGraph*> graphsWithIorDependency;
Expand Down Expand Up @@ -641,10 +696,15 @@ void MdlShaderGenerator::emitShaderInputs(const DocumentPtr doc, const VariableB
}
}

void MdlShaderGenerator::emitMdlVersionNumber(GenContext& context, ShaderStage& stage) const
GenMdlOptions::MdlVersion MdlShaderGenerator::getMdlVersion(GenContext& context) const
{
GenMdlOptionsPtr options = context.getUserData<GenMdlOptions>(GenMdlOptions::GEN_CONTEXT_USER_DATA_KEY);
GenMdlOptions::MdlVersion version = options ? options->targetVersion : GenMdlOptions::MdlVersion::MDL_LATEST;
return options ? options->targetVersion : GenMdlOptions::MdlVersion::MDL_LATEST;
}

void MdlShaderGenerator::emitMdlVersionNumber(GenContext& context, ShaderStage& stage) const
{
GenMdlOptions::MdlVersion version = getMdlVersion(context);

emitLineBegin(stage);
emitString("mdl ", stage);
Expand All @@ -656,30 +716,35 @@ void MdlShaderGenerator::emitMdlVersionNumber(GenContext& context, ShaderStage&
case GenMdlOptions::MdlVersion::MDL_1_7:
emitString(MDL_VERSION_1_7, stage);
break;
case GenMdlOptions::MdlVersion::MDL_1_8:
emitString(MDL_VERSION_1_8, stage);
break;
default:
// GenMdlOptions::MdlVersion::MDL_1_8
// GenMdlOptions::MdlVersion::MDL_1_9
// GenMdlOptions::MdlVersion::MDL_LATEST
emitString(MDL_VERSION_1_8, stage);
emitString(MDL_VERSION_1_9, stage);
break;
}
emitLineEnd(stage, true);
}


const string& MdlShaderGenerator::getMdlVersionFilenameSuffix(GenContext& context) const
{
GenMdlOptionsPtr options = context.getUserData<GenMdlOptions>(GenMdlOptions::GEN_CONTEXT_USER_DATA_KEY);
GenMdlOptions::MdlVersion version = options ? options->targetVersion : GenMdlOptions::MdlVersion::MDL_LATEST;
GenMdlOptions::MdlVersion version = getMdlVersion(context);

switch (version)
{
case GenMdlOptions::MdlVersion::MDL_1_6:
return MDL_VERSION_SUFFIX_1_6;
case GenMdlOptions::MdlVersion::MDL_1_7:
return MDL_VERSION_SUFFIX_1_7;
case GenMdlOptions::MdlVersion::MDL_1_8:
return MDL_VERSION_SUFFIX_1_8;
default:
// GenMdlOptions::MdlVersion::MDL_1_8
// GenMdlOptions::MdlVersion::MDL_1_9
// GenMdlOptions::MdlVersion::MDL_LATEST
return MDL_VERSION_SUFFIX_1_8;
return MDL_VERSION_SUFFIX_1_9;
}
}

Expand Down
9 changes: 7 additions & 2 deletions source/MaterialXGenMdl/MdlShaderGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class MX_GENMDL_API GenMdlOptions : public GenUserData
MDL_1_6,
MDL_1_7,
MDL_1_8,
MDL_LATEST = MDL_1_8
MDL_1_9,
MDL_LATEST = MDL_1_9
};

/// Create MDL code generator options with default values.
Expand Down Expand Up @@ -76,7 +77,11 @@ class MX_GENMDL_API MdlShaderGenerator : public ShaderGenerator
/// Map of code snippets for geomprops in MDL.
static const std::unordered_map<string, string> GEOMPROP_DEFINITIONS;

/// Add the MDL file header containing the version number of the generated module..
/// Get the selected MDL target language version number from the context option.
/// If not set, the latest version supported by GenMdl is returned.
GenMdlOptions::MdlVersion getMdlVersion(GenContext& context) const;

/// Add the MDL file header containing the version number of the generated module.
void emitMdlVersionNumber(GenContext& context, ShaderStage& stage) const;

/// Add the version number suffix appended to MDL modules that use versions.
Expand Down
45 changes: 45 additions & 0 deletions source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ MATERIALX_NAMESPACE_BEGIN

const string StringConstantsMdl::TOP = "top";
const string StringConstantsMdl::BASE = "base";
const string StringConstantsMdl::FG = "fg";
const string StringConstantsMdl::BG = "bg";
const string StringConstantsMdl::MIX = "mix";
const string StringConstantsMdl::TOP_WEIGHT = "top_weight";

ShaderNodeImplPtr ClosureLayerNodeMdl::create()
{
Expand Down Expand Up @@ -101,6 +105,7 @@ void ClosureLayerNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext&

// Transport the base bsdf further than one layer
ShaderNode* baseReceiverNode = top;
ShaderNode* mixTopWeightNode = nullptr;
while (true)
{
// If the top node is again a layer, we don't want to override the base
Expand All @@ -111,6 +116,26 @@ void ClosureLayerNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext&
}
else
{
// TODO is there a more efficient way to check if the node is a mix_bsdf?
std::string name = top->getImplementation().getName();
if (name == "IM_mix_bsdf_genmdl")
{
// handle one special case: the top node is a mix where either fg or bg is empty
// so basically a scale factor
ShaderOutput* fgOutput = top->getInput(StringConstantsMdl::FG)->getConnection();
ShaderOutput* bgOutput = top->getInput(StringConstantsMdl::BG)->getConnection();
ShaderOutput* mixOutput = top->getInput(StringConstantsMdl::MIX)->getConnection();
ShaderNode* fg = fgOutput ? fgOutput->getNode() : nullptr;
ShaderNode* bg = bgOutput ? bgOutput->getNode() : nullptr;
ShaderNode* mix = mixOutput ? mixOutput->getNode() : nullptr;
if ((fg && !bg) || (!fg && bg))
{
baseReceiverNode = fg ? fg : bg; // take the node that is valid
top = baseReceiverNode;
mixTopWeightNode = mix;
}
break;
}
// we stop at elemental bsdfs
// TODO handle mix, add, and multiply
break;
Expand Down Expand Up @@ -150,6 +175,11 @@ void ClosureLayerNodeMdl::emitFunctionCall(const ShaderNode& _node, GenContext&
// base BSDF connection and output variable name from the
// layer operator itself.
topNodeBaseInput->makeConnection(base->getOutput());
if (mixTopWeightNode)
{
ShaderInput* topNodeTopWeightInput = baseReceiverNode->getInput(StringConstantsMdl::TOP_WEIGHT);
topNodeTopWeightInput->makeConnection(mixTopWeightNode->getOutput());
}
ScopedSetVariableName setVariable(output->getVariable(), top->getOutput());

// Make the call.
Expand All @@ -171,6 +201,21 @@ void LayerableNodeMdl::addInputs(ShaderNode& node, GenContext& /*context*/) cons
{
// Add the input to hold base layer BSDF.
node.addInput(StringConstantsMdl::BASE, Type::BSDF);

// Set the top level weight default to 1.0
ShaderInput* topWeightNode = node.addInput(StringConstantsMdl::TOP_WEIGHT, Type::FLOAT);
ValuePtr value = TypedValue<float>::createValue(1.0f);
topWeightNode->setValue(value);
}

bool LayerableNodeMdl::isEditable(const ShaderInput& input) const
{
if (input.getName() == StringConstantsMdl::BASE ||
input.getName() == StringConstantsMdl::TOP_WEIGHT)
{
return false;
}
return BASE::isEditable(input);
}

MATERIALX_NAMESPACE_END
7 changes: 7 additions & 0 deletions source/MaterialXGenMdl/Nodes/ClosureLayerNodeMdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class MX_GENMDL_API StringConstantsMdl
/// String constants
static const string TOP; ///< layer parameter name of the top component
static const string BASE; ///< layer parameter name of the base component
static const string FG; ///< mix parameter name of the foreground
static const string BG; ///< mix parameter name of the background
static const string MIX; ///< mix parameter name of the amount
static const string TOP_WEIGHT; ///< mix amount forwarded into layer top component
};

/// Closure layer node implementation for MDL.
Expand All @@ -40,11 +44,14 @@ class MX_GENMDL_API ClosureLayerNodeMdl : public ShaderNodeImpl
/// Note, not all elemental bsdfs support this kind of transformation.
class MX_GENMDL_API LayerableNodeMdl : public SourceCodeNodeMdl
{
using BASE = SourceCodeNodeMdl;

public:
virtual ~LayerableNodeMdl() = default;
static ShaderNodeImplPtr create();

void addInputs(ShaderNode& node, GenContext&) const override;
bool isEditable(const ShaderInput& input) const override;
};

MATERIALX_NAMESPACE_END
Expand Down
Loading