From c475e83aa3910756a9e7f78a04fded1fead78bb4 Mon Sep 17 00:00:00 2001 From: "W2.Wizard" Date: Sat, 20 Feb 2021 15:44:06 +0100 Subject: [PATCH] Added RGBToHSV --- Source/Editor/Surface/Archetypes/Material.cs | 19 +++++++++++++- .../MaterialGenerator.Material.cpp | 25 ++++++++++++++----- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index 1c679a039..2b3bb4703 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -819,7 +819,7 @@ namespace FlaxEditor.Surface.Archetypes { TypeID = 36, Title = "HSVToRGB", - Description = "Converts a HSV value to linear RGB", + Description = "Converts a HSV value to linear RGB [X = 0/360, Y = 0/1, Z = 0/1]", Flags = NodeFlags.MaterialGraph, Size = new Vector2(160, 25), DefaultValues = new object[] @@ -831,6 +831,23 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Input(0, "HSV", true, typeof(Vector3), 0, 0), NodeElementArchetype.Factory.Output(0, "RGB", typeof(Vector3), 1), } + }, + new NodeArchetype + { + TypeID = 37, + Title = "RGBToHSV", + Description = "Converts a linear RGB value to HSV [X = 0/360, Y = 0/1, Z = 0/1]", + Flags = NodeFlags.MaterialGraph, + Size = new Vector2(160, 25), + DefaultValues = new object[] + { + new Vector3(0, 1, 0), + }, + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "RGB", true, typeof(Vector3), 0, 0), + NodeElementArchetype.Factory.Output(0, "HSV", typeof(Vector3), 1), + } } }; } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index 2abae3622..4866b3483 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -463,15 +463,28 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) { const auto hsv = tryGetValue(node->GetBox(0), node->Values[0]).AsVector3(); - // Normalize - auto color = writeLocal(ValueType::Vector3, String::Format(TEXT("float3({0}.x / 360, {0}.y, {0}.z)"), hsv.Value), node); + // Normalize from 360 + auto color = writeLocal(ValueType::Vector3, String::Format(TEXT("float3({0}.x / 360.0f, {0}.y, {0}.z)"), hsv.Value), node); auto x1 = writeLocal(ValueType::Vector3, String::Format(TEXT("clamp(abs(fmod({0}.x * 6.0 + float3(0.0f, 4.0f, 2.0f), 6.0f) - 3.0f) - 1.0f, 0.0f, 1.0f)"), color.Value), node); - - // Smooth out - auto x2 = writeLocal(ValueType::Vector3, String::Format(TEXT("{0} * {0} * (3.0 - 2.0 * {0})"), x1.Value), node); - value = writeLocal(ValueType::Vector3, String::Format(TEXT("{1}.z * lerp(float3(1.0, 1.0, 1.0), {0}, {1}.y)"), x2.Value, color.Value), node); + value = writeLocal(ValueType::Vector3, String::Format(TEXT("{1}.z * lerp(float3(1.0, 1.0, 1.0), {0}, {1}.y)"), x1.Value, color.Value), node); + break; + } + // RGBToHSV + case 37: + { + // Reference: Ian Taylor, https://www.chilliant.com/rgb2hsv.html + const auto rgb = tryGetValue(node->GetBox(0), node->Values[0]).AsVector3(); + const auto epsilon = writeLocal(ValueType::Float, TEXT("1e-10"), node); + + auto p = writeLocal(ValueType::Vector4, String::Format(TEXT("({0}.g < {0}.b) ? float4({0}.bg, -1.0f, 2.0f/3.0f) : float4({0}.gb, 0.0f, -1.0f/3.0f)"), rgb.Value), node); + auto q = writeLocal(ValueType::Vector4, String::Format(TEXT("({0}.r < {1}.x) ? float4({1}.xyw, {0}.r) : float4({0}.r, {1}.yzx)"), rgb.Value, p.Value), node); + auto c = writeLocal(ValueType::Float, String::Format(TEXT("{0}.x - min({0}.w, {0}.y)"), q.Value), node); + auto h = writeLocal(ValueType::Float , String::Format(TEXT("abs(({0}.w - {0}.y) / (6 * {1} + {2}) + {0}.z)"), q.Value, c.Value, epsilon.Value), node); + + auto hcv = writeLocal(ValueType::Vector3, String::Format(TEXT("float3({0}, {1}, {2}.x)"), h.Value, c.Value, q.Value), node); + value = writeLocal(ValueType::Vector3, String::Format(TEXT("float3({0}.x * 360.0f, {0}.y / ({0}.z + {1}), {0}.z)"), hcv.Value, epsilon.Value), node); break; } default: