From 044645345bd491250ff6041489b83b28640e54bb Mon Sep 17 00:00:00 2001 From: Andy <94316446+beersandrew@users.noreply.github.com> Date: Sat, 14 Oct 2023 22:56:53 +0300 Subject: [PATCH 1/3] Restructure Add Node List (#1562) Added a list of nodes to the best of my ability to be the order they should be displayed --- source/MaterialXGraphEditor/Graph.cpp | 166 ++++++++++++++------------ source/MaterialXGraphEditor/Graph.h | 27 ++++- 2 files changed, 112 insertions(+), 81 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 522280cb08..849b8607b4 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -236,9 +236,6 @@ void Graph::addExtraNodes() return; } - // Clear any old nodes, if we previously used tab with another graph doc - _extraNodes.clear(); - // Get all types from the doc std::vector types; std::vector typeDefs = _graphDoc->getTypeDefs(); @@ -252,18 +249,16 @@ void Graph::addExtraNodes() for (const std::string& type : types) { std::string nodeName = "ND_input_" + type; - _extraNodes["Input Nodes"].push_back({ nodeName, type, "input" }); + _nodesToAdd.emplace_back(nodeName, type, "input", "Input Nodes"); nodeName = "ND_output_" + type; - _extraNodes["Output Nodes"].push_back({ nodeName, type, "output" }); + _nodesToAdd.emplace_back(nodeName, type, "output", "Output Nodes"); } // Add group node - std::vector groupNode{ "ND_group", "", "group" }; - _extraNodes["Group Nodes"].push_back(groupNode); + _nodesToAdd.emplace_back("ND_group", "", "group", "Group Nodes"); // Add nodegraph node - std::vector nodeGraph{ "ND_nodegraph", "", "nodegraph" }; - _extraNodes["Node Graph"].push_back(nodeGraph); + _nodesToAdd.emplace_back("ND_nodegraph", "", "nodegraph", "Node Graph"); } ed::PinId Graph::getOutputPin(UiNodePtr node, UiNodePtr upNode, UiPinPtr input) @@ -1224,20 +1219,63 @@ void Graph::setUiNodeInfo(UiNodePtr node, const std::string& type, const std::st void Graph::createNodeUIList(mx::DocumentPtr doc) { _nodesToAdd.clear(); - const std::string EXTRA_GROUP_NAME = "extra"; - for (mx::NodeDefPtr nodeDef : doc->getNodeDefs()) + + std::vector ordered_groups = { + "texture2d", + "texture3d", + "procedural", + "procedural2d", + "procedural3d", + "geometric", + "translation", + "convolution2d", + "math", + "adjustment", + "compositing", + "conditional", + "channel", + "organization", + "global", + "application", + "material", + "shader", + "pbr", + "light", + "colortransform", + "no_group" + }; + + auto nodeDefs = doc->getNodeDefs(); + std::unordered_map> groupToNodeDef; + + for (const auto& nodeDef : nodeDefs) { - // NodeDef is the key for the map std::string group = nodeDef->getNodeGroup(); + if (group.empty()) { - group = EXTRA_GROUP_NAME; + group = "no_group"; } - if (_nodesToAdd.find(group) == _nodesToAdd.end()) + + if (groupToNodeDef.find(group) == groupToNodeDef.end()) { - _nodesToAdd[group] = std::vector(); + groupToNodeDef[group] = std::vector(); + } + groupToNodeDef[group].push_back(nodeDef); + } + + for (const auto& group : ordered_groups) + { + auto it = groupToNodeDef.find(group); + if (it != groupToNodeDef.end()) + { + const auto& groupNodeDefs = it->second; + + for (const auto& nodeDef : groupNodeDefs) + { + _nodesToAdd.emplace_back(nodeDef->getName(), nodeDef->getType(), nodeDef->getNodeString(), group); + } } - _nodesToAdd[group].push_back(nodeDef); } addExtraNodes(); @@ -3595,96 +3633,66 @@ void Graph::addNodePopup(bool cursor) // Input string length // Filter extra nodes - includes inputs, outputs, groups, and node graphs const std::string NODEGRAPH_ENTRY = "Node Graph"; - for (std::unordered_map>>::iterator it = _extraNodes.begin(); it != _extraNodes.end(); ++it) + + // Filter nodedefs and add to menu if matches filter + for (auto node : _nodesToAdd) { // Filter out list of nodes if (subs.size() > 0) { ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f)); - for (size_t i = 0; i < it->second.size(); i++) - { - std::string str(it->second[i][0]); - std::string nodeName = it->second[i][0]; + std::string str(node.getName()); + std::string nodeName = node.getName(); - // Disallow creating nested nodegraphs - if (_isNodeGraph && it->first == NODEGRAPH_ENTRY) - { - continue; - } + // Disallow creating nested nodegraphs + if (_isNodeGraph && node.getGroup() == NODEGRAPH_ENTRY) + { + continue; + } - // Allow spaces to be used to search for node names - std::replace(subs.begin(), subs.end(), ' ', '_'); + // Allow spaces to be used to search for node names + std::replace(subs.begin(), subs.end(), ' ', '_'); - if (str.find(subs) != std::string::npos) + if (str.find(subs) != std::string::npos) + { + if (ImGui::MenuItem(getUserNodeDefName(nodeName).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { - if (ImGui::MenuItem(getUserNodeDefName(nodeName).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) - { - addNode(it->second[i][2], getUserNodeDefName(nodeName), it->second[i][1]); - _addNewNode = true; - memset(input, '\0', sizeof(input)); - } + addNode(node.getCategory(), getUserNodeDefName(nodeName), node.getType()); + _addNewNode = true; + memset(input, '\0', sizeof(input)); } } } else { ImGui::SetNextWindowSizeConstraints(ImVec2(100, 10), ImVec2(-1, 300)); - if (ImGui::BeginMenu(it->first.c_str())) + if (ImGui::BeginMenu(node.getGroup().c_str())) { ImGui::SetWindowFontScale(_fontScale); - for (size_t j = 0; j < it->second.size(); j++) + std::string name = node.getName(); + std::string prefix = "ND_"; + if (name.compare(0, prefix.size(), prefix) == 0 && name.compare(prefix.size(), std::string::npos, node.getCategory()) == 0) { - std::string name = it->second[j][0]; if (ImGui::MenuItem(getUserNodeDefName(name).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { - addNode(it->second[j][2], getUserNodeDefName(name), it->second[j][1]); - _addNewNode = true; - } - } - ImGui::EndMenu(); - } - } - } - - // Filter nodedefs and add to menu if matches filter - for (std::unordered_map>::iterator it = _nodesToAdd.begin(); it != _nodesToAdd.end(); ++it) - { - // Filter out list of nodes - if (subs.size() > 0) - { - ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f)); - for (size_t i = 0; i < it->second.size(); i++) - { - std::string str(it->second[i]->getName()); - std::string nodeName = it->second[i]->getName(); - if (str.find(subs) != std::string::npos) - { - std::string val = getUserNodeDefName(nodeName); - if (ImGui::MenuItem(val.c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) - { - addNode(it->second[i]->getNodeString(), val, it->second[i]->getType()); + addNode(node.getCategory(), getUserNodeDefName(name), node.getType()); _addNewNode = true; - memset(input, '\0', sizeof(input)); } } - } - } - else - { - ImGui::SetNextWindowSizeConstraints(ImVec2(100, 10), ImVec2(-1, 300)); - if (ImGui::BeginMenu(it->first.c_str())) - { - ImGui::SetWindowFontScale(_fontScale); - for (size_t i = 0; i < it->second.size(); i++) + else { - std::string name = it->second[i]->getName(); - std::string val = getUserNodeDefName(name); - if (ImGui::MenuItem(val.c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) + if (ImGui::BeginMenu(node.getCategory().c_str())) { - addNode(it->second[i]->getNodeString(), val, it->second[i]->getType()); - _addNewNode = true; + if (ImGui::MenuItem(getUserNodeDefName(name).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) + { + addNode(node.getCategory(), getUserNodeDefName(name), node.getType()); + _addNewNode = true; + } + ImGui::EndMenu(); } } + + ImGui::EndMenu(); } } diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 9b9857c69a..87d4119c2a 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -14,6 +14,30 @@ #include +class MenuItem +{ + public: + MenuItem(const std::string& name, const std::string& type, const std::string& category, const std::string& group) : + name(name), type(type), category(category), group(group) { } + + // getters + std::string getName() const { return name; } + std::string getType() const { return type; } + std::string getCategory() const { return category; } + std::string getGroup() const { return group; } + + // setters + void setName(const std::string& newName) { this->name = newName; } + void setType(const std::string& newType) { this->type = newType; } + void setCategory(const std::string& newCategory) { this->category = newCategory; } + void setGroup(const std::string& newGroup) { this->group = newGroup; } + + private: + std::string name; + std::string type; + std::string category; + std::string group; +}; namespace ed = ax::NodeEditor; namespace mx = MaterialX; @@ -248,8 +272,7 @@ class Graph std::vector _currGraphName; // for adding new nodes - std::unordered_map> _nodesToAdd; - std::unordered_map>> _extraNodes; + std::vector _nodesToAdd; // stacks to dive into and out of node graphs std::stack> _graphStack; From 74462510a32948341131b93d1695514cfc283927 Mon Sep 17 00:00:00 2001 From: iukpo-lucasfilm <145880411+iukpo-lucasfilm@users.noreply.github.com> Date: Sat, 14 Oct 2023 15:26:23 -0700 Subject: [PATCH 2/3] Stop Graph Editor from creating imgui.ini file (#1570) Added code to stop creation of imgui.ini after saving material after saving then closing Graph Editor --- source/MaterialXGraphEditor/Main.cpp | 51 ++++------------------------ 1 file changed, 7 insertions(+), 44 deletions(-) diff --git a/source/MaterialXGraphEditor/Main.cpp b/source/MaterialXGraphEditor/Main.cpp index 754d766798..5bbcbdad66 100644 --- a/source/MaterialXGraphEditor/Main.cpp +++ b/source/MaterialXGraphEditor/Main.cpp @@ -23,44 +23,6 @@ static void errorCallback(int error, const char* description) fprintf(stderr, "Glfw Error %d: %s\n", error, description); } -mx::FilePath getConfigPath() -{ - mx::FilePath configPath; - auto xdgConfigHome = mx::getEnviron("XDG_CONFIG_HOME"); - auto homeDirectory = mx::getEnviron("HOME"); - if (!xdgConfigHome.empty()) - { - configPath = mx::FilePath(xdgConfigHome); - } - else if (!homeDirectory.empty()) - { -#if defined(__APPLE__) - configPath = mx::FilePath(homeDirectory) / "Library" / "Preferences"; -#else - configPath = mx::FilePath(homeDirectory) / ".config"; - if (!configPath.exists()) - { - configPath.createDirectory(); - } -#endif - } - else - { - return {}; - } - - configPath = configPath / "MaterialX"; - configPath.createDirectory(); - - if (!configPath.exists()) - { - std::cerr << "Failed to create MaterialX config directory at " << configPath.asString() << std::endl; - return {}; - } - - return configPath / "GraphEditor.imgui.ini"; -} - const std::string options = " Options: \n" " --material [FILENAME] Specify the filename of the MTLX document to be displayed in the graph editor\n" @@ -197,13 +159,14 @@ int main(int argc, char* const argv[]) IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); - io.Fonts->AddFontDefault(); - mx::FilePath configPath = getConfigPath(); - if (!configPath.isEmpty()) - { - io.IniFilename = configPath.asString().c_str(); - } + // Set ini and log filename to NULL. This will prevent the automatic creation of imgui.ini + // in the same folder as the saved material. + // TODO: Consider setting the ini and log file paths to an application directory. + io.IniFilename = NULL; + io.LogFilename = NULL; + + io.Fonts->AddFontDefault(); // Setup Dear ImGui style ImGui::StyleColorsDark(); From a62a468ed80f4a6830950cc7a9ff7e544567d669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ars=C3=A8ne=20P=C3=A9rard-Gayot?= Date: Sun, 15 Oct 2023 20:18:43 +0200 Subject: [PATCH 3/3] Fix edge case in HW shader generation for transform nodes (#1560) This merges the TransformXXXNodeGlsl and TransformXXXNodeMsl classes into a HwTransformNode which has 3 subclasses, HwTransformVectorNode, HwTransformPointNode, and HwTransformNormalNode, all of which can be configured by overriding the virtual methods of HwTransformNode. --- .../MaterialXGenGlsl/GlslShaderGenerator.cpp | 15 +-- source/MaterialXGenGlsl/GlslShaderGenerator.h | 5 - .../Nodes/TransformNormalNodeGlsl.cpp | 43 ------- .../Nodes/TransformNormalNodeGlsl.h | 27 ----- .../Nodes/TransformPointNodeGlsl.cpp | 23 ---- .../Nodes/TransformPointNodeGlsl.h | 25 ---- .../Nodes/TransformVectorNodeGlsl.cpp | 84 ------------- .../Nodes/TransformVectorNodeGlsl.h | 30 ----- source/MaterialXGenMsl/MslShaderGenerator.cpp | 15 +-- source/MaterialXGenMsl/MslShaderGenerator.h | 5 - .../Nodes/TransformNormalNodeMsl.cpp | 43 ------- .../Nodes/TransformNormalNodeMsl.h | 27 ----- .../Nodes/TransformPointNodeMsl.cpp | 23 ---- .../Nodes/TransformPointNodeMsl.h | 25 ---- .../Nodes/TransformVectorNodeMsl.cpp | 84 ------------- .../Nodes/TransformVectorNodeMsl.h | 30 ----- .../Nodes/HwTransformNode.cpp | 110 ++++++++++++++++++ .../Nodes/HwTransformNode.h | 71 +++++++++++ source/MaterialXGenShader/ShaderNode.cpp | 5 + source/MaterialXGenShader/ShaderNode.h | 3 + .../PyMaterialXGenShader/PyShaderPort.cpp | 1 + 21 files changed, 198 insertions(+), 496 deletions(-) delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp delete mode 100644 source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h delete mode 100644 source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h delete mode 100644 source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h delete mode 100644 source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp delete mode 100644 source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h create mode 100644 source/MaterialXGenShader/Nodes/HwTransformNode.cpp create mode 100644 source/MaterialXGenShader/Nodes/HwTransformNode.h diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp index 87582c8f50..ec5e48d4ec 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp @@ -22,9 +22,6 @@ #include #include #include -#include -#include -#include #include #include @@ -34,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -228,13 +226,13 @@ GlslShaderGenerator::GlslShaderGenerator() : registerImplementation(elementNames, BlurNodeGlsl::create); // elementNames = { @@ -902,11 +900,6 @@ ShaderNodeImplPtr GlslShaderGenerator::getImplementation(const NodeDef& nodedef, } const string GlslImplementation::SPACE = "space"; -const string GlslImplementation::TO_SPACE = "tospace"; -const string GlslImplementation::FROM_SPACE = "fromspace"; -const string GlslImplementation::WORLD = "world"; -const string GlslImplementation::OBJECT = "object"; -const string GlslImplementation::MODEL = "model"; const string GlslImplementation::INDEX = "index"; const string GlslImplementation::GEOMPROP = "geomprop"; diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.h b/source/MaterialXGenGlsl/GlslShaderGenerator.h index 4464f5d47c..acc8b0d6ee 100644 --- a/source/MaterialXGenGlsl/GlslShaderGenerator.h +++ b/source/MaterialXGenGlsl/GlslShaderGenerator.h @@ -110,11 +110,6 @@ class MX_GENGLSL_API GlslImplementation : public ShaderNodeImpl /// Internal string constants static const string SPACE; - static const string TO_SPACE; - static const string FROM_SPACE; - static const string WORLD; - static const string OBJECT; - static const string MODEL; static const string INDEX; static const string GEOMPROP; }; diff --git a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp deleted file mode 100644 index 0800fb4bf3..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformNormalNodeGlsl::create() -{ - return std::make_shared(); -} - -void TransformNormalNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - TransformVectorNodeGlsl::emitFunctionCall(node, context, stage); - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - const ShaderOutput* output = node.getOutput(); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(output, false, false, context, stage); - shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage); - shadergen.emitLineEnd(stage); - } -} - -const string& TransformNormalNodeGlsl::getMatrix(const string& fromSpace, const string& toSpace) const -{ - if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) - { - return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX; - } - else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) - { - return HW::T_WORLD_TRANSPOSE_MATRIX; - } - return EMPTY_STRING; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h deleted file mode 100644 index f08ec564d9..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMNORMALNODEGLSL_H -#define MATERIALX_TRANSFORMNORMALNODEGLSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformNormal node implementation for GLSL -class MX_GENGLSL_API TransformNormalNodeGlsl : public TransformVectorNodeGlsl -{ - public: - static ShaderNodeImplPtr create(); - - protected: - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - const string& getMatrix(const string& fromSpace, const string& toSpace) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp deleted file mode 100644 index 1570939bfe..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformPointNodeGlsl::create() -{ - return std::make_shared(); -} - -string TransformPointNodeGlsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const -{ - const ShaderGenerator& shadergen = context.getShaderGenerator(); - return "vec4(" + shadergen.getUpstreamResult(in, context) + ", 1.0)"; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h deleted file mode 100644 index eb366d8190..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMPOINTNODEGLSL_H -#define MATERIALX_TRANSFORMPOINTNODEGLSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformPoint node implementation for GLSL -class MX_GENGLSL_API TransformPointNodeGlsl : public TransformVectorNodeGlsl -{ - public: - static ShaderNodeImplPtr create(); - - protected: - virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp deleted file mode 100644 index df1e921497..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformVectorNodeGlsl::create() -{ - return std::make_shared(); -} - -void TransformVectorNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - const ShaderInput* toSpaceInput = node.getInput(TO_SPACE); - string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE); - string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const string& matrix = getMatrix(fromSpace, toSpace); - if (!matrix.empty()) - { - ShaderStage& ps = shader.getStage(Stage::PIXEL); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps); - } -} - -void TransformVectorNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - - const ShaderInput* inInput = node.getInput("in"); - if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4) - { - throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4."); - } - - const ShaderInput* toSpaceInput = node.getInput(TO_SPACE); - string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE); - string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = (", stage); - const string& matrix = getMatrix(fromSpace, toSpace); - if (!matrix.empty()) - { - shadergen.emitString(matrix + " * ", stage); - } - shadergen.emitString(getHomogeneousCoordinate(inInput, context), stage); - shadergen.emitString(").xyz", stage); - shadergen.emitLineEnd(stage); - } -} - -const string& TransformVectorNodeGlsl::getMatrix(const string& fromSpace, const string& toSpace) const -{ - if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) - { - return HW::T_WORLD_MATRIX; - } - else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) - { - return HW::T_WORLD_INVERSE_MATRIX; - } - return EMPTY_STRING; -} - -string TransformVectorNodeGlsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const -{ - const ShaderGenerator& shadergen = context.getShaderGenerator(); - return "vec4(" + shadergen.getUpstreamResult(in, context) + ", 0.0)"; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h deleted file mode 100644 index e9861650b3..0000000000 --- a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMVECTORNODEGLSL_H -#define MATERIALX_TRANSFORMVECTORNODEGLSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformVector node implementation for GLSL -class MX_GENGLSL_API TransformVectorNodeGlsl : public GlslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - protected: - virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const; - virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp index 1d93104ce8..ea3fb7112d 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.cpp +++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp @@ -22,9 +22,6 @@ #include #include #include -#include -#include -#include #include #include @@ -34,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -232,13 +230,13 @@ MslShaderGenerator::MslShaderGenerator() : registerImplementation(elementNames, BlurNodeMsl::create); // elementNames = { @@ -1404,11 +1402,6 @@ ShaderNodeImplPtr MslShaderGenerator::getImplementation(const NodeDef& nodedef, } const string MslImplementation::SPACE = "space"; -const string MslImplementation::TO_SPACE = "tospace"; -const string MslImplementation::FROM_SPACE = "fromspace"; -const string MslImplementation::WORLD = "world"; -const string MslImplementation::OBJECT = "object"; -const string MslImplementation::MODEL = "model"; const string MslImplementation::INDEX = "index"; const string MslImplementation::GEOMPROP = "geomprop"; diff --git a/source/MaterialXGenMsl/MslShaderGenerator.h b/source/MaterialXGenMsl/MslShaderGenerator.h index 631c38f33d..21817db735 100644 --- a/source/MaterialXGenMsl/MslShaderGenerator.h +++ b/source/MaterialXGenMsl/MslShaderGenerator.h @@ -137,11 +137,6 @@ class MX_GENMSL_API MslImplementation : public ShaderNodeImpl /// Internal string constants static const string SPACE; - static const string TO_SPACE; - static const string FROM_SPACE; - static const string WORLD; - static const string OBJECT; - static const string MODEL; static const string INDEX; static const string GEOMPROP; }; diff --git a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp deleted file mode 100644 index 98810c025b..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformNormalNodeMsl::create() -{ - return std::make_shared(); -} - -void TransformNormalNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - TransformVectorNodeMsl::emitFunctionCall(node, context, stage); - - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - const ShaderOutput* output = node.getOutput(); - shadergen.emitLineBegin(stage); - shadergen.emitOutput(output, false, false, context, stage); - shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage); - shadergen.emitLineEnd(stage); - } -} - -const string& TransformNormalNodeMsl::getMatrix(const string& fromSpace, const string& toSpace) const -{ - if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) - { - return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX; - } - else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) - { - return HW::T_WORLD_TRANSPOSE_MATRIX; - } - return EMPTY_STRING; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h deleted file mode 100644 index 603ba3771c..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMNORMALNODEMSL_H -#define MATERIALX_TRANSFORMNORMALNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformNormal node implementation for MSL -class MX_GENMSL_API TransformNormalNodeMsl : public TransformVectorNodeMsl -{ - public: - static ShaderNodeImplPtr create(); - - protected: - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - const string& getMatrix(const string& fromSpace, const string& toSpace) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp deleted file mode 100644 index 38db776855..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformPointNodeMsl::create() -{ - return std::make_shared(); -} - -string TransformPointNodeMsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const -{ - const ShaderGenerator& shadergen = context.getShaderGenerator(); - return "float4(" + shadergen.getUpstreamResult(in, context) + ", 1.0)"; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h deleted file mode 100644 index 9fc2361d7d..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMPOINTNODEMSL_H -#define MATERIALX_TRANSFORMPOINTNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformPoint node implementation for MSL -class MX_GENMSL_API TransformPointNodeMsl : public TransformVectorNodeMsl -{ - public: - static ShaderNodeImplPtr create(); - - protected: - virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const override; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp deleted file mode 100644 index c5d6ce242a..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#include - -#include - -MATERIALX_NAMESPACE_BEGIN - -ShaderNodeImplPtr TransformVectorNodeMsl::create() -{ - return std::make_shared(); -} - -void TransformVectorNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const -{ - const ShaderInput* toSpaceInput = node.getInput(TO_SPACE); - string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE); - string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const string& matrix = getMatrix(fromSpace, toSpace); - if (!matrix.empty()) - { - ShaderStage& ps = shader.getStage(Stage::PIXEL); - addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps); - } -} - -void TransformVectorNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const -{ - DEFINE_SHADER_STAGE(stage, Stage::PIXEL) - { - const ShaderGenerator& shadergen = context.getShaderGenerator(); - - const ShaderInput* inInput = node.getInput("in"); - if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4) - { - throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4."); - } - - const ShaderInput* toSpaceInput = node.getInput(TO_SPACE); - string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE); - string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING; - - shadergen.emitLineBegin(stage); - shadergen.emitOutput(node.getOutput(), true, false, context, stage); - shadergen.emitString(" = (", stage); - const string& matrix = getMatrix(fromSpace, toSpace); - if (!matrix.empty()) - { - shadergen.emitString(matrix + " * ", stage); - } - shadergen.emitString(getHomogeneousCoordinate(inInput, context), stage); - shadergen.emitString(").xyz", stage); - shadergen.emitLineEnd(stage); - } -} - -const string& TransformVectorNodeMsl::getMatrix(const string& fromSpace, const string& toSpace) const -{ - if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) - { - return HW::T_WORLD_MATRIX; - } - else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) - { - return HW::T_WORLD_INVERSE_MATRIX; - } - return EMPTY_STRING; -} - -string TransformVectorNodeMsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const -{ - const ShaderGenerator& shadergen = context.getShaderGenerator(); - return "float4(" + shadergen.getUpstreamResult(in, context) + ", 0.0)"; -} - -MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h deleted file mode 100644 index 013a3db29a..0000000000 --- a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright Contributors to the MaterialX Project -// SPDX-License-Identifier: Apache-2.0 -// - -#ifndef MATERIALX_TRANSFORMVECTORNODEMSL_H -#define MATERIALX_TRANSFORMVECTORNODEMSL_H - -#include - -MATERIALX_NAMESPACE_BEGIN - -/// TransformVector node implementation for MSL -class MX_GENMSL_API TransformVectorNodeMsl : public MslImplementation -{ - public: - static ShaderNodeImplPtr create(); - - void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; - - void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; - - protected: - virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const; - virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const; -}; - -MATERIALX_NAMESPACE_END - -#endif diff --git a/source/MaterialXGenShader/Nodes/HwTransformNode.cpp b/source/MaterialXGenShader/Nodes/HwTransformNode.cpp new file mode 100644 index 0000000000..018924855d --- /dev/null +++ b/source/MaterialXGenShader/Nodes/HwTransformNode.cpp @@ -0,0 +1,110 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include +#include + +MATERIALX_NAMESPACE_BEGIN + +const string HwTransformNode::FROM_SPACE = "fromspace"; +const string HwTransformNode::TO_SPACE = "tospace"; +const string HwTransformNode::MODEL = "model"; +const string HwTransformNode::OBJECT = "object"; +const string HwTransformNode::WORLD = "world"; + +void HwTransformNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const +{ + const string toSpace = getToSpace(node); + const string fromSpace = getFromSpace(node); + const string& matrix = getMatrix(fromSpace, toSpace); + if (!matrix.empty()) + { + ShaderStage& ps = shader.getStage(Stage::PIXEL); + addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps); + } +} + +void HwTransformNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const +{ + DEFINE_SHADER_STAGE(stage, Stage::PIXEL) + { + const ShaderGenerator& shadergen = context.getShaderGenerator(); + + const ShaderOutput* output = node.getOutput(); + const ShaderInput* inInput = node.getInput("in"); + if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4) + { + throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4."); + } + + shadergen.emitLineBegin(stage); + shadergen.emitOutput(output, true, false, context, stage); + shadergen.emitString(" = (", stage); + + const string toSpace = getToSpace(node); + const string fromSpace = getFromSpace(node); + const string& matrix = getMatrix(fromSpace, toSpace); + if (!matrix.empty()) + { + shadergen.emitString(matrix + " * ", stage); + } + + const string type = shadergen.getSyntax().getTypeName(Type::VECTOR4); + const string input = shadergen.getUpstreamResult(inInput, context); + shadergen.emitString(type + "(" + input + ", " + getHomogeneousCoordinate() + ")).xyz", stage); + shadergen.emitLineEnd(stage); + + if (shouldNormalize()) + { + shadergen.emitLineBegin(stage); + shadergen.emitOutput(output, false, false, context, stage); + shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage); + shadergen.emitLineEnd(stage); + } + } +} + +string HwTransformNode::getFromSpace(const ShaderNode& node) const +{ + const ShaderInput* input = node.getInput(FROM_SPACE); + return input ? input->getValueString() : EMPTY_STRING; +} + +string HwTransformNode::getToSpace(const ShaderNode& node) const +{ + const ShaderInput* input = node.getInput(TO_SPACE); + return input ? input->getValueString() : EMPTY_STRING; +} + +const string& HwTransformNode::getMatrix(const string& fromSpace, const string& toSpace) const +{ + if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD) + { + return getModelToWorldMatrix(); + } + else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT)) + { + return getWorldToModelMatrix(); + } + return EMPTY_STRING; +} + +ShaderNodeImplPtr HwTransformVectorNode::create() +{ + return std::make_shared(); +} + +ShaderNodeImplPtr HwTransformPointNode::create() +{ + return std::make_shared(); +} + +ShaderNodeImplPtr HwTransformNormalNode::create() +{ + return std::make_shared(); +} + +MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenShader/Nodes/HwTransformNode.h b/source/MaterialXGenShader/Nodes/HwTransformNode.h new file mode 100644 index 0000000000..a97e57405c --- /dev/null +++ b/source/MaterialXGenShader/Nodes/HwTransformNode.h @@ -0,0 +1,71 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#ifndef MATERIALX_HWTRANSFORMNODE_H +#define MATERIALX_HWTRANSFORMNODE_H + +#include + +MATERIALX_NAMESPACE_BEGIN + +/// Generic transformation node for hardware languages +class MX_GENSHADER_API HwTransformNode : public ShaderNodeImpl +{ + public: + void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override; + void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override; + + protected: + virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const; + virtual const string& getModelToWorldMatrix() const = 0; + virtual const string& getWorldToModelMatrix() const = 0; + virtual string getHomogeneousCoordinate() const = 0; + virtual bool shouldNormalize() const { return false; } + + virtual string getFromSpace(const ShaderNode&) const; + virtual string getToSpace(const ShaderNode&) const; + + static const string FROM_SPACE; + static const string TO_SPACE; + static const string MODEL; + static const string OBJECT; + static const string WORLD; +}; + +class MX_GENSHADER_API HwTransformVectorNode : public HwTransformNode +{ + public: + static ShaderNodeImplPtr create(); + + protected: + const string& getModelToWorldMatrix() const override { return HW::T_WORLD_MATRIX; } + const string& getWorldToModelMatrix() const override { return HW::T_WORLD_INVERSE_MATRIX; } + string getHomogeneousCoordinate() const override { return "0.0"; } +}; + +class MX_GENSHADER_API HwTransformPointNode : public HwTransformVectorNode +{ + public: + static ShaderNodeImplPtr create(); + + protected: + string getHomogeneousCoordinate() const override { return "1.0"; } +}; + +class MX_GENSHADER_API HwTransformNormalNode : public HwTransformNode +{ + public: + static ShaderNodeImplPtr create(); + + protected: + const string& getModelToWorldMatrix() const override { return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX; } + const string& getWorldToModelMatrix() const override { return HW::T_WORLD_TRANSPOSE_MATRIX; } + string getHomogeneousCoordinate() const override { return "0.0"; } + bool shouldNormalize() const override { return true; } +}; + +MATERIALX_NAMESPACE_END + +#endif diff --git a/source/MaterialXGenShader/ShaderNode.cpp b/source/MaterialXGenShader/ShaderNode.cpp index 04551cb6d2..3e393178f1 100644 --- a/source/MaterialXGenShader/ShaderNode.cpp +++ b/source/MaterialXGenShader/ShaderNode.cpp @@ -32,6 +32,11 @@ string ShaderPort::getFullName() const return (_node->getName() + "_" + _name); } +string ShaderPort::getValueString() const +{ + return getValue() ? getValue()->getValueString() : EMPTY_STRING; +} + // // ShaderInput methods // diff --git a/source/MaterialXGenShader/ShaderNode.h b/source/MaterialXGenShader/ShaderNode.h index 536e0adc1e..dd74269764 100644 --- a/source/MaterialXGenShader/ShaderNode.h +++ b/source/MaterialXGenShader/ShaderNode.h @@ -170,6 +170,9 @@ class MX_GENSHADER_API ShaderPort : public std::enable_shared_from_this