From f66296b25e095aad135834aa8e59c13282adcdd7 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Mon, 2 Jan 2023 16:29:29 -0800 Subject: [PATCH] Simplify OSL node implementations (#1185) This changelist simplifies the OSL implementations of common nodes such as 'if', 'add', and 'subtract', removing duplicate code and harmonizing inline implementations where possible. --- libraries/stdlib/genosl/include/mx_funcs.h | 86 +++------------ libraries/stdlib/genosl/mx_add.inline | 2 +- .../stdlib/genosl/mx_fractal3d_color4.osl | 2 +- libraries/stdlib/genosl/mx_ifequal.inline | 1 + libraries/stdlib/genosl/mx_ifgreater.inline | 1 + libraries/stdlib/genosl/mx_ifgreatereq.inline | 1 + libraries/stdlib/genosl/mx_noise3d_color4.osl | 2 +- libraries/stdlib/genosl/mx_subtract.inline | 2 +- .../stdlib/genosl/stdlib_genosl_impl.mtlx | 100 +++++++++--------- source/MaterialXGenOsl/OslShaderGenerator.cpp | 29 ----- source/MaterialXGenShader/Nodes/IfNode.cpp | 94 ---------------- source/MaterialXGenShader/Nodes/IfNode.h | 74 ------------- 12 files changed, 74 insertions(+), 320 deletions(-) create mode 100644 libraries/stdlib/genosl/mx_ifequal.inline create mode 100644 libraries/stdlib/genosl/mx_ifgreater.inline create mode 100644 libraries/stdlib/genosl/mx_ifgreatereq.inline delete mode 100644 source/MaterialXGenShader/Nodes/IfNode.cpp delete mode 100644 source/MaterialXGenShader/Nodes/IfNode.h diff --git a/libraries/stdlib/genosl/include/mx_funcs.h b/libraries/stdlib/genosl/include/mx_funcs.h index 531b13cd4d..4db654c6fa 100644 --- a/libraries/stdlib/genosl/include/mx_funcs.h +++ b/libraries/stdlib/genosl/include/mx_funcs.h @@ -5,49 +5,25 @@ // http://www.materialx.org/ #pragma once + #include "color4.h" #include "vector2.h" #include "vector4.h" #include "matrix33.h" +// +// Support functions for OSL implementations of the MaterialX nodes. +// + +float mx_ternary(int expr, float v1, float v2) { if (expr) return v1; else return v2; } +color mx_ternary(int expr, color v1, color v2) { if (expr) return v1; else return v2; } +color4 mx_ternary(int expr, color4 v1, color4 v2) { if (expr) return v1; else return v2; } +vector mx_ternary(int expr, vector v1, vector v2) { if (expr) return v1; else return v2; } +vector2 mx_ternary(int expr, vector2 v1, vector2 v2) { if (expr) return v1; else return v2; } +vector4 mx_ternary(int expr, vector4 v1, vector4 v2) { if (expr) return v1; else return v2; } +matrix mx_ternary(int expr, matrix v1, matrix v2) { if (expr) return v1; else return v2; } +matrix33 mx_ternary(int expr, matrix33 v1, matrix33 v2) { if (expr) return v1; else return v2; } -/////////////////////////////////////////////////////////////////////////// -// This file contains lots of functions helpful in the implementation of -// the MaterialX nodes. -/////////////////////////////////////////////////////////////////////////// - - -// Define mx_convert_type -// float -> colvecN -color mx_convert (float a) { return color(a); } -color4 mx_convert (float a) { return color4(a,a); } -vector mx_convert (float a) { return vector(a); } -vector2 mx_convert (float a) { return vector2(a,a); } -vector4 mx_convert (float a) { return vector4(a,a,a,a); } -// colN <-> vecN -vector mx_convert (color a) { return (vector)a; } -vector4 mx_convert (color4 a) { return vector4 (a.rgb[0], a.rgb[1], a.rgb[2], a.a); } -color mx_convert (vector a) { return (color)a; } -color4 mx_convert (vector4 a) { return color4 (color(a.x,a.y,a.z), a.w); } -// col3 <-> col4 -color mx_convert (color4 a) { return a.rgb; } -color4 mx_convert (color a) { return color4(a,1.0); } - -// Define mx_add() overloaded for all MX types. -float mx_add (float a, float b) { return a+b; } -point mx_add (point a, point b) { return a+b; } -point mx_add (point a, float b) { return a+b; } -vector mx_add (vector a, vector b) { return a+b; } -vector mx_add (vector a, float b) { return a+b; } -vector2 mx_add (vector2 a, vector2 b) { return a+b; } -vector2 mx_add (vector2 a, float b) { return a+b; } -vector4 mx_add (vector4 a, vector4 b) { return a+b; } -vector4 mx_add (vector4 a, float b) { return a+b; } -color mx_add (color a, color b) { return a+b; } -color mx_add (color a, float b) { return a+b; } -color4 mx_add (color4 a, color4 b) { return a+b; } -color4 mx_add (color4 a, float b) { return a+b; } -closure color mx_add (closure color a, closure color b) { return a+b; } matrix33 mx_add(matrix33 a, matrix33 b) { @@ -86,22 +62,7 @@ matrix mx_add(matrix a, float b) } -// Define mx_sub() overloaded for all MX types. -float mx_sub (float a, float b) { return a-b; } -point mx_sub (point a, point b) { return a-b; } -point mx_sub (point a, float b) { return a-b; } -vector mx_sub (vector a, vector b) { return a-b; } -vector mx_sub (vector a, float b) { return a-b; } -vector2 mx_sub (vector2 a, vector2 b) { return a-b; } -vector2 mx_sub (vector2 a, float b) { return a-b; } -vector4 mx_sub (vector4 a, vector4 b) { return a-b; } -vector4 mx_sub (vector4 a, float b) { return a-b; } -color mx_sub (color a, color b) { return a-b; } -color mx_sub (color a, float b) { return a-b; } -color4 mx_sub (color4 a, color4 b) { return a-b; } -color4 mx_sub (color4 a, float b) { return a-b; } - -matrix33 mx_sub(matrix33 a, matrix33 b) +matrix33 mx_subtract(matrix33 a, matrix33 b) { return matrix33(matrix( a.m[0][0]-b.m[0][0], a.m[0][1]-b.m[0][1], a.m[0][2]-b.m[0][2], 0.0, @@ -110,7 +71,7 @@ matrix33 mx_sub(matrix33 a, matrix33 b) 0.0, 0.0, 0.0, 1.0)); } -matrix33 mx_sub(matrix33 a, float b) +matrix33 mx_subtract(matrix33 a, float b) { return matrix33(matrix( a.m[0][0]-b, a.m[0][1]-b, a.m[0][2]-b, 0.0, @@ -119,7 +80,7 @@ matrix33 mx_sub(matrix33 a, float b) 0.0, 0.0, 0.0, 1.0)); } -matrix mx_sub(matrix a, matrix b) +matrix mx_subtract(matrix a, matrix b) { return matrix( a[0][0]-b[0][0], a[0][1]-b[0][1], a[0][2]-b[0][2], a[0][3]-b[0][3], @@ -128,7 +89,7 @@ matrix mx_sub(matrix a, matrix b) a[3][0]-b[3][0], a[3][1]-b[3][1], a[3][2]-b[3][2], a[3][3]-b[3][3]); } -matrix mx_sub(matrix a, float b) +matrix mx_subtract(matrix a, float b) { return matrix( a[0][0]-b, a[0][1]-b, a[0][2]-b, a[0][3]-b, @@ -138,7 +99,6 @@ matrix mx_sub(matrix a, float b) } -// remap `in` from [inLow, inHigh] to [outLow, outHigh], optionally clamping to the new range. float mx_remap(float in, float inLow, float inHigh, float outLow, float outHigh, int doClamp) { float x = (in - inLow)/(inHigh-inLow); @@ -210,9 +170,6 @@ vector4 mx_remap(vector4 in, float inLow, float inHigh, float outLow, float outH } -// -// mx_contrast scales the input around a central `pivot` value. -// float mx_contrast(float in, float amount, float pivot) { float out = in - pivot; @@ -317,9 +274,6 @@ vector4 mx_noise(string noisetype, point position) } -// -// fractional Brownian motion -// float mx_fbm(point position, int octaves, float lacunarity, float diminish, string noisetype) { float out = 0; @@ -574,9 +528,3 @@ vector mx_worley_noise_vector3(vector p, float jitter, int metric) result = sqrt(result); return result; } - - -color4 mx_combine(float a, float b, float c, float d) -{ - return color4(color(a,b,c), d); -} diff --git a/libraries/stdlib/genosl/mx_add.inline b/libraries/stdlib/genosl/mx_add.inline index d16f1ab8c7..71277cdec7 100644 --- a/libraries/stdlib/genosl/mx_add.inline +++ b/libraries/stdlib/genosl/mx_add.inline @@ -1 +1 @@ -mx_add({{in1}}, {{in2}}) +{{in1}} + {{in2}} diff --git a/libraries/stdlib/genosl/mx_fractal3d_color4.osl b/libraries/stdlib/genosl/mx_fractal3d_color4.osl index cc90ea2667..9943a92dfd 100644 --- a/libraries/stdlib/genosl/mx_fractal3d_color4.osl +++ b/libraries/stdlib/genosl/mx_fractal3d_color4.osl @@ -1,5 +1,5 @@ void mx_fractal3d_color4(vector4 amplitude, int octaves, float lacunarity, float diminish, vector position, output color4 result) { color4 f = mx_fbm(position, octaves, lacunarity, diminish, "snoise"); - result = f * mx_combine(amplitude.x, amplitude.y, amplitude.z, amplitude.w); + result = f * color4(color(amplitude.x, amplitude.y, amplitude.z), amplitude.w); } diff --git a/libraries/stdlib/genosl/mx_ifequal.inline b/libraries/stdlib/genosl/mx_ifequal.inline new file mode 100644 index 0000000000..c03ffbea92 --- /dev/null +++ b/libraries/stdlib/genosl/mx_ifequal.inline @@ -0,0 +1 @@ +mx_ternary({{value1}} == {{value2}}, {{in1}}, {{in2}}) diff --git a/libraries/stdlib/genosl/mx_ifgreater.inline b/libraries/stdlib/genosl/mx_ifgreater.inline new file mode 100644 index 0000000000..e4de3d8ef6 --- /dev/null +++ b/libraries/stdlib/genosl/mx_ifgreater.inline @@ -0,0 +1 @@ +mx_ternary({{value1}} > {{value2}}, {{in1}}, {{in2}}) diff --git a/libraries/stdlib/genosl/mx_ifgreatereq.inline b/libraries/stdlib/genosl/mx_ifgreatereq.inline new file mode 100644 index 0000000000..9075acea63 --- /dev/null +++ b/libraries/stdlib/genosl/mx_ifgreatereq.inline @@ -0,0 +1 @@ +mx_ternary({{value1}} >= {{value2}}, {{in1}}, {{in2}}) diff --git a/libraries/stdlib/genosl/mx_noise3d_color4.osl b/libraries/stdlib/genosl/mx_noise3d_color4.osl index f7ec23ef94..c522f81493 100644 --- a/libraries/stdlib/genosl/mx_noise3d_color4.osl +++ b/libraries/stdlib/genosl/mx_noise3d_color4.osl @@ -1,5 +1,5 @@ void mx_noise3d_color4(vector4 amplitude, float pivot, vector position, output color4 result) { color4 value = mx_noise("snoise", position); - result = value * mx_combine(amplitude.x, amplitude.y, amplitude.z, amplitude.w) + pivot; + result = value * color4(color(amplitude.x, amplitude.y, amplitude.z), amplitude.w) + pivot; } diff --git a/libraries/stdlib/genosl/mx_subtract.inline b/libraries/stdlib/genosl/mx_subtract.inline index a70d4a12da..afa4339659 100644 --- a/libraries/stdlib/genosl/mx_subtract.inline +++ b/libraries/stdlib/genosl/mx_subtract.inline @@ -1 +1 @@ -mx_sub({{in1}}, {{in2}}) +{{in1}} - {{in2}} diff --git a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx index ce99191a1a..61728cc20e 100644 --- a/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx +++ b/libraries/stdlib/genosl/stdlib_genosl_impl.mtlx @@ -221,10 +221,10 @@ - - - - + + + + @@ -238,10 +238,10 @@ - - - - + + + + @@ -615,52 +615,52 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp index efcdb92755..37e4fac0fa 100644 --- a/source/MaterialXGenOsl/OslShaderGenerator.cpp +++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -38,34 +37,6 @@ OslShaderGenerator::OslShaderGenerator() : { // Register build-in implementations - // - static const string SEPARATOR = "_"; - static const string INT_SEPARATOR = "I_"; - static const string BOOL_SEPARATOR = "B_"; - static const StringVec IMPL_PREFIXES = { "IM_ifgreater_", "IM_ifgreatereq_", "IM_ifequal_" }; - static const vector> IMPL_CREATE_FUNCTIONS = - { IfGreaterNode::create, IfGreaterEqNode::create, IfEqualNode::create }; - static const vector IMPL_HAS_INTVERSION = { true, true, true }; - static const vector IMPL_HAS_BOOLVERSION = { false, false, true }; - static const StringVec IMPL_TYPES = { "float", "color3", "color4", "vector2", "vector3", "vector4" }; - for (size_t i = 0; i < IMPL_PREFIXES.size(); i++) - { - const string& implPrefix = IMPL_PREFIXES[i]; - for (const string& implType : IMPL_TYPES) - { - const string implRoot = implPrefix + implType; - registerImplementation(implRoot + SEPARATOR + OslShaderGenerator::TARGET, IMPL_CREATE_FUNCTIONS[i]); - if (IMPL_HAS_INTVERSION[i]) - { - registerImplementation(implRoot + INT_SEPARATOR + OslShaderGenerator::TARGET, IMPL_CREATE_FUNCTIONS[i]); - } - if (IMPL_HAS_BOOLVERSION[i]) - { - registerImplementation(implRoot + BOOL_SEPARATOR + OslShaderGenerator::TARGET, IMPL_CREATE_FUNCTIONS[i]); - } - } - } - // // registerImplementation("IM_switch_float_" + OslShaderGenerator::TARGET, SwitchNode::create); diff --git a/source/MaterialXGenShader/Nodes/IfNode.cpp b/source/MaterialXGenShader/Nodes/IfNode.cpp deleted file mode 100644 index 4ae81f9298..0000000000 --- a/source/MaterialXGenShader/Nodes/IfNode.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// TM & (c) 2017 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd. -// All rights reserved. See LICENSE.txt for license. -// - -#include -#include -#include -#include -#include - -MATERIALX_NAMESPACE_BEGIN - -const StringVec IfNode::INPUT_NAMES = { "value1", "value2", "in1", "in2" }; -string IfGreaterEqNode::EQUALITY_STRING = " >= "; -string IfGreaterNode::EQUALITY_STRING = " > "; -string IfEqualNode::EQUALITY_STRING = " == "; - -void IfNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - - const ShaderGraph& graph = *node.getParent(); - - // Declare the output variable - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, true, context, stage); - shadergen.emitLineEnd(stage); - - const ShaderInput* value1 = node.getInput(INPUT_NAMES[0]); - const ShaderInput* value2 = node.getInput(INPUT_NAMES[1]); - - // Process the if and else branches of the conditional - for (int branch = 2; branch <= 3; ++branch) - { - const ShaderInput* input = node.getInput(INPUT_NAMES[branch]); - - if (branch > 2) - { - shadergen.emitLine("else", stage, false); - } - else - { - shadergen.emitLineBegin(stage); - shadergen.emitString("if (", stage); - shadergen.emitInput(value1, context, stage); - shadergen.emitString(equalityString(), stage); - shadergen.emitInput(value2, context, stage); - shadergen.emitString(")", stage); - shadergen.emitLineEnd(stage, false); - } - - shadergen.emitScopeBegin(stage); - - // Emit function calls for nodes that are ONLY needed in this scope - for (const ShaderNode* otherNode : graph.getNodes()) - { - const ShaderNode::ScopeInfo& scope = otherNode->getScopeInfo(); - if (scope.conditionalNode == &node && scope.usedByBranch(branch)) - { - // Force ignore scope otherwise the function call will be omitted. - shadergen.emitFunctionCall(*otherNode, context, stage, false); - } - } - - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), false, false, context, stage); - shadergen.emitString(" = ", stage); - shadergen.emitInput(input, context, stage); - shadergen.emitLineEnd(stage); - - shadergen.emitScopeEnd(stage); - } - } -} - -ShaderNodeImplPtr IfGreaterNode::create() -{ - return std::make_shared(); -} - -ShaderNodeImplPtr IfGreaterEqNode::create() -{ - return std::make_shared(); -} - -ShaderNodeImplPtr IfEqualNode::create() -{ - return std::make_shared(); -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenShader/Nodes/IfNode.h b/source/MaterialXGenShader/Nodes/IfNode.h deleted file mode 100644 index c8a74d9dfe..0000000000 --- a/source/MaterialXGenShader/Nodes/IfNode.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// TM & (c) 2017 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd. -// All rights reserved. See LICENSE.txt for license. -// - -#ifndef MATERIALX_IFNODE_H -#define MATERIALX_IFNODE_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// @class IfNode -/// Abstract base class for implementions which handle if conditions. -class MX_GENSHADER_API IfNode : public ShaderNodeImpl -{ - public: - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - private: - /// Provides the shader code equality operator string to use - virtual const string& equalityString() const = 0; - - static const StringVec INPUT_NAMES; -}; - -/// @class IfGreaterNode -/// "ifgreater" node implementation -class MX_GENSHADER_API IfGreaterNode : public IfNode -{ - public: - static ShaderNodeImplPtr create(); - - private: - const string& equalityString() const override - { - return EQUALITY_STRING; - } - static string EQUALITY_STRING; -}; - -/// @class IfGreaterEqNode -/// "ifgreatereq" node implementation -class MX_GENSHADER_API IfGreaterEqNode : public IfNode -{ - public: - static ShaderNodeImplPtr create(); - - private: - const string& equalityString() const override - { - return EQUALITY_STRING; - } - static string EQUALITY_STRING; -}; - -/// @class IfEqualNode -/// "ifequal" node implementation -class MX_GENSHADER_API IfEqualNode : public IfNode -{ - public: - static ShaderNodeImplPtr create(); - - private: - const string& equalityString() const override - { - return EQUALITY_STRING; - } - static string EQUALITY_STRING; -}; - -MATERIALX_NAMESPACE_END - -#endif