From f7955a5c4e15b7c32633d7d6b52520ffb7c55a66 Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Thu, 12 May 2022 13:44:57 +0200 Subject: [PATCH] Add support for custom location of Custom Global Code in generated material source code --- Source/Editor/Surface/Archetypes/Material.cs | 40 ++++++++++++++- .../MaterialGenerator/MaterialGenerator.cpp | 49 +++++++++++++------ .../MaterialGenerator/MaterialGenerator.h | 1 + 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index 424511cce..f7ce33c92 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -236,6 +236,39 @@ namespace FlaxEditor.Surface.Archetypes } } + internal enum MaterialTemplateInputsMapping + { + /// + /// Constant buffers. + /// + Constants = 1, + + /// + /// Shader resources such as textures and buffers. + /// + ShaderResources = 2, + + /// + /// Pre-processor definitions. + /// + Defines = 3, + + /// + /// Included files. + /// + Includes = 7, + + /// + /// Default location after all shader resources and methods but before actual material code. + /// + Utilities = 8, + + /// + /// Shader functions location after all material shaders. + /// + Shaders = 9, + } + /// /// The nodes for that group. /// @@ -814,17 +847,20 @@ namespace FlaxEditor.Surface.Archetypes Title = "Custom Global Code", Description = "Custom global HLSL shader code expression (placed before material shader code). Can contain includes to shader utilities or declare functions to reuse later.", Flags = NodeFlags.MaterialGraph, - Size = new Vector2(300, 220), + Size = new Vector2(300, 240), DefaultValues = new object[] { "// Here you can add HLSL code\nfloat4 GetCustomColor()\n{\n\treturn float4(1, 0, 0, 1);\n}", true, + (int)MaterialTemplateInputsMapping.Utilities, }, Elements = new[] { NodeElementArchetype.Factory.Bool(0, 0, 1), NodeElementArchetype.Factory.Text(20, 0, "Enabled"), - NodeElementArchetype.Factory.TextBox(0, 20, 300, 200, 0), + NodeElementArchetype.Factory.Text(0, 20, "Location"), + NodeElementArchetype.Factory.Enum(50, 20, 120, 2, typeof(MaterialTemplateInputsMapping)), + NodeElementArchetype.Factory.TextBox(0, 40, 300, 200, 0), } }, }; diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index f1d5b5840..42b57c341 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -392,6 +392,21 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo // Update material usage based on material generator outputs materialInfo.UsageFlags = baseLayer->UsageFlags; + // Find all Custom Global Code nodes + Array> customGlobalCodeNodes; + Array> graphs; + _functions.GetValues(graphs); + for (MaterialLayer* layer : _layers) + graphs.Add(&layer->Graph); + for (Graph* graph : graphs) + { + for (const MaterialGraph::Node& node : graph->Nodes) + { + if (node.Type == GRAPH_NODE_MAKE_TYPE(1, 38) && (bool)node.Values[1]) + customGlobalCodeNodes.Add(&node); + } + } + #define WRITE_FEATURES(input) FeaturesLock.Lock(); for (auto f : features) _writer.Write(Features[f].Inputs[(int32)FeatureTemplateInputsMapping::input]); FeaturesLock.Unlock(); // Defines { @@ -408,6 +423,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo } WRITE_FEATURES(Defines); inputs[In_Defines] = _writer.ToString(); + WriteCustomGlobalCode(customGlobalCodeNodes, In_Defines); _writer.Clear(); } @@ -416,6 +432,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo for (auto& include : _includes) _writer.Write(TEXT("#include \"{0}\"\n"), include.Item); WRITE_FEATURES(Includes); + WriteCustomGlobalCode(customGlobalCodeNodes, In_Includes); inputs[In_Includes] = _writer.ToString(); _writer.Clear(); } @@ -425,6 +442,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo WRITE_FEATURES(Constants); if (_parameters.HasItems()) ShaderGraphUtilities::GenerateShaderConstantBuffer(_writer, _parameters); + WriteCustomGlobalCode(customGlobalCodeNodes, In_Constants); inputs[In_Constants] = _writer.ToString(); _writer.Clear(); } @@ -485,6 +503,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo return true; } } + WriteCustomGlobalCode(customGlobalCodeNodes, In_ShaderResources); inputs[In_ShaderResources] = _writer.ToString(); _writer.Clear(); } @@ -492,21 +511,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo // Utilities { WRITE_FEATURES(Utilities); - Array> graphs; - _functions.GetValues(graphs); - for (MaterialLayer* layer : _layers) - graphs.Add(&layer->Graph); - for (Graph* graph : graphs) - { - for (const MaterialGraph::Node& node : graph->Nodes) - { - if (node.Type == GRAPH_NODE_MAKE_TYPE(1, 38) && (bool)node.Values[1]) - { - // Custom Global Code - _writer.Write((StringView)node.Values[0]); - } - } - } + WriteCustomGlobalCode(customGlobalCodeNodes, In_Utilities); inputs[In_Utilities] = _writer.ToString(); _writer.Clear(); } @@ -514,6 +519,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo // Shaders { WRITE_FEATURES(Shaders); + WriteCustomGlobalCode(customGlobalCodeNodes, In_Shaders); inputs[In_Shaders] = _writer.ToString(); _writer.Clear(); } @@ -799,4 +805,17 @@ void MaterialGenerator::ProcessGroupMath(Box* box, Node* node, Value& value) } } +void MaterialGenerator::WriteCustomGlobalCode(const Array>& nodes, int32 templateInputsMapping) +{ + for (const MaterialGraph::Node* node : nodes) + { + if ((int32)node->Values[2] == templateInputsMapping) + { + _writer.Write(TEXT("\n")); + _writer.Write((StringView)node->Values[0]); + _writer.Write(TEXT("\n")); + } + } +} + #endif diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h index 48cd21cb4..9a8aa5290 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h @@ -205,6 +205,7 @@ private: MaterialValue AccessParticleAttribute(Node* caller, const StringView& name, ParticleAttributeValueTypes valueType, const Char* index = nullptr, ParticleAttributeSpace space = ParticleAttributeSpace::AsIs); void prepareLayer(MaterialLayer* layer, bool allowVisibleParams); + void WriteCustomGlobalCode(const Array>& nodes, int32 templateInputsMapping); public: