Added RGBToHSV

This commit is contained in:
W2.Wizard
2021-02-20 15:44:06 +01:00
parent da24a474ea
commit c475e83aa3
2 changed files with 37 additions and 7 deletions

View File

@@ -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),
}
}
};
}

View File

@@ -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);
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
// 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);
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: