From 8f8df34342012b70571bebdf24b2c3f27e4ba288 Mon Sep 17 00:00:00 2001 From: PrecisionRender Date: Wed, 24 Aug 2022 09:35:54 -0500 Subject: [PATCH] Add World Triplanar Texture node to shader editor --- Source/Editor/Surface/Archetypes/Textures.cs | 20 +++++++++ .../MaterialGenerator.Textures.cpp | 45 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index a7180f78e..9043d6ea3 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -385,6 +385,26 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Input(0, "World Position", true, typeof(Float3), 1), } }, + new NodeArchetype + { + TypeID = 16, + Title = "World Triplanar Texture", + Description = "Projects a texture using world-space coordinates instead of UVs.", + Flags = NodeFlags.MaterialGraph, + Size = new Float2(240, 80), + DefaultValues = new object[] + { + 1.0f, + 1.0f + }, + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "Texture", true, typeof(FlaxEngine.Object), 0), + NodeElementArchetype.Factory.Input(1, "Scale", true, typeof(float), 1, 0), + NodeElementArchetype.Factory.Input(2, "Blend", true, typeof(float), 2, 1), + NodeElementArchetype.Factory.Output(0, "Color", typeof(Float3), 3) + } + }, }; } } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp index 5d19f46d2..3c08f8fea 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp @@ -444,6 +444,51 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value) value = box == gradientBox ? gradient : distance; break; } + // World Triplanar Texture + case 16: + { + // Get input boxes + auto textureBox = node->GetBox(0); + auto scaleBox = node->GetBox(1); + auto blendBox = node->GetBox(2); + + if (!textureBox->HasConnection()) + { + // No texture to sample + value = Value::Zero; + break; + } + + if (!CanUseSample(_treeType)) + { + // Must sample texture in pixel shader + value = Value::Zero; + break; + } + + const auto texture = eatBox(textureBox->GetParent(), textureBox->FirstConnection()); + const auto scale = tryGetValue(scaleBox, node->Values[0]); + const auto blend = tryGetValue(blendBox, node->Values[1]); + + auto result = writeLocal(Value::InitForZero(ValueType::Float4), node); + + const String triplanarTexture = String::Format(TEXT( + " float3 worldPos = input.WorldPosition.xyz * ({1} * 0.001f);\n" + " float3 normal = input.TBN[2];\n" + + " {3} += {0}.Sample(SamplerLinearWrap, worldPos.yz) * pow(abs(dot(normal, float3(1,0,0))), {2});\n" + " {3} += {0}.Sample(SamplerLinearWrap, worldPos.xz) * pow(abs(dot(normal, float3(0,1,0))), {2});\n" + " {3} += {0}.Sample(SamplerLinearWrap, worldPos.xy) * pow(abs(dot(normal, float3(0,0,1))), {2});\n" + ), + texture.Value, // {0} + scale.Value, // {1} + blend.Value, // {2} + result.Value // {3} + ); + + _writer.Write(*triplanarTexture); + value = result; + } default: break; }