diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index ee70c2b5e..43110a9de 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -672,6 +672,35 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Output(0, string.Empty, typeof(Vector2), 3), } }, + new NodeArchetype + { + TypeID = 28, + Title = "Sphere Mask", + Description = "Creates a sphere mask", + Flags = NodeFlags.MaterialGraph, + Size = new Vector2(150, 100), + ConnectionsHints = ConnectionsHint.Vector, + IndependentBoxes = new[] + { + 0, + 1 + }, + DefaultValues = new object[] + { + 0.3f, + 0.5f, + false + }, + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "A", true, null, 0), + NodeElementArchetype.Factory.Input(1, "B", true, null, 1), + NodeElementArchetype.Factory.Input(2, "Radius", true, typeof(float), 2, 0), + NodeElementArchetype.Factory.Input(3, "Hardness", true, typeof(float), 3, 1), + NodeElementArchetype.Factory.Input(4, "Invert", true, typeof(bool), 4, 2), + NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 5), + } + }, }; } } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index c4d7c39e5..79a18bde4 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -363,6 +363,24 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) value = writeLocal(ValueType::Vector2, String::Format(TEXT("{3} + float2(dot({0},{1}), dot({0},{2}))"), x1.Value, dotB1.Value, dotB2.Value, center.Value), node); break; + } + // SphereMask + case 28: + { + Value a = tryGetValue(node->GetBox(0), 0, Value::Zero); + Value b = tryGetValue(node->GetBox(1), 1, Value::Zero).Cast(a.Type); + Value radius = tryGetValue(node->GetBox(2), node->Values[0]).AsFloat(); + Value hardness = tryGetValue(node->GetBox(3), node->Values[1]).AsFloat(); + Value invert = tryGetValue(node->GetBox(4), node->Values[2]).AsBool(); + + // Get distance and apply radius + auto x1 = writeLocal(ValueType::Float, String::Format(TEXT("distance({0},{1}) * (1 / {2})"), a.Value, b.Value, radius.Value), node); + + // Apply hardness, use 0.991 as max since any value above will result in harsh aliasing + auto x2 = writeLocal(ValueType::Float, String::Format(TEXT("saturate((1 - {0}) * (1 / (1 - clamp({1}, 0, 0.991f))))"), x1.Value, hardness.Value), node); + + value = writeLocal(ValueType::Float, String::Format(TEXT("{0} ? (1 - {1}) : {1}"), invert.Value, x2.Value), node); + break; } default: break;