From 04d44d8a158bedf6767f43c5126d416dd31e70d5 Mon Sep 17 00:00:00 2001 From: PrecisionRender Date: Wed, 24 Aug 2022 09:35:54 -0500 Subject: [PATCH 1/3] Add World Triplanar Texture node to shader editor --- Source/Editor/Surface/Archetypes/Textures.cs | 18 ++++++++ .../MaterialGenerator.Textures.cpp | 42 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index a7180f78e..a40179b3d 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -385,6 +385,24 @@ 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, 60), + DefaultValues = new object[] + { + 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.Output(0, "Color", typeof(Float3), 2) + } + }, }; } } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp index 5d19f46d2..738ad0c64 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp @@ -444,6 +444,48 @@ 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); + + 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]); + + auto result = writeLocal(Value::InitForZero(ValueType::Float4), node); + + const String triplanarTexture = String::Format(TEXT( + " float3 worldPos = input.WorldPosition.xyz * {1} / 1000;\n" + " float3 normal = input.TBN[2];\n" + + " {2} += {0}.Sample(SamplerLinearWrap, worldPos.yz) * abs(dot(normal, float3(1,0,0)));\n" + " {2} += {0}.Sample(SamplerLinearWrap, worldPos.xz) * abs(dot(normal, float3(0,1,0)));\n" + " {2} += {0}.Sample(SamplerLinearWrap, worldPos.xy) * abs(dot(normal, float3(0,0,1)));\n" + ), + texture.Value, // {0} + scale.Value, // {1} + result.Value // {2} + ); + + _writer.Write(*triplanarTexture); + value = result; + } default: break; } From 8f8df34342012b70571bebdf24b2c3f27e4ba288 Mon Sep 17 00:00:00 2001 From: PrecisionRender Date: Wed, 24 Aug 2022 09:35:54 -0500 Subject: [PATCH 2/3] 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; } From a1dea6a756bbcb365c7620dacfbc0778c3f31d05 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 31 Aug 2022 17:39:01 +0200 Subject: [PATCH 3/3] Adjust triplanar texture sample node #735 --- Source/Editor/Surface/Archetypes/Textures.cs | 2 +- .../MaterialGenerator.Textures.cpp | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index 9043d6ea3..2b566b0bd 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -391,7 +391,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "World Triplanar Texture", Description = "Projects a texture using world-space coordinates instead of UVs.", Flags = NodeFlags.MaterialGraph, - Size = new Float2(240, 80), + Size = new Float2(240, 60), DefaultValues = new object[] { 1.0f, diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp index 3c08f8fea..a29b3d0d9 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp @@ -467,18 +467,22 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value) } const auto texture = eatBox(textureBox->GetParent(), textureBox->FirstConnection()); - const auto scale = tryGetValue(scaleBox, node->Values[0]); - const auto blend = tryGetValue(blendBox, node->Values[1]); + const auto scale = tryGetValue(scaleBox, node->Values[0]).AsFloat(); + const auto blend = tryGetValue(blendBox, node->Values[1]).AsFloat(); auto result = writeLocal(Value::InitForZero(ValueType::Float4), node); const String triplanarTexture = String::Format(TEXT( + " {{\n" " float3 worldPos = input.WorldPosition.xyz * ({1} * 0.001f);\n" - " float3 normal = input.TBN[2];\n" + " float3 normal = abs(input.TBN[2]);\n" + " normal = pow(normal, {2});\n" + " normal = normal / (normal.x + normal.y + normal.z);\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" + " {3} += {0}.Sample(SamplerLinearWrap, worldPos.yz) * normal.x;\n" + " {3} += {0}.Sample(SamplerLinearWrap, worldPos.xz) * normal.y;\n" + " {3} += {0}.Sample(SamplerLinearWrap, worldPos.xy) * normal.z;\n" + " }}\n" ), texture.Value, // {0} scale.Value, // {1}