|
@@ -17,6 +17,13 @@ public class BuiltInFunctions
|
|
|
return new Expression($"{nameof(HslToRgb)}({hsla.ExpressionValue})");
|
|
|
}
|
|
|
|
|
|
+ public Expression GetRgbToHsl(Expression rgba)
|
|
|
+ {
|
|
|
+ Require(BuiltInFunctionType.RgbToHsl);
|
|
|
+
|
|
|
+ return new Expression($"{nameof(RgbToHsl)}({rgba.ExpressionValue})");
|
|
|
+ }
|
|
|
+
|
|
|
public Expression GetHslToRgb(Expression h, Expression s, Expression l, Expression a) =>
|
|
|
GetHslToRgb(Half4.Constructor(h, s, l, a));
|
|
|
|
|
@@ -25,7 +32,10 @@ public class BuiltInFunctions
|
|
|
var builder = new StringBuilder();
|
|
|
|
|
|
AppendIf(BuiltInFunctionType.HueToRgb, HueToRgb);
|
|
|
+ AppendIf(BuiltInFunctionType.RgbToHcv, RgbToHcv);
|
|
|
+
|
|
|
AppendIf(BuiltInFunctionType.HslToRgb, HslToRgb);
|
|
|
+ AppendIf(BuiltInFunctionType.RgbToHsl, RgbToHsl);
|
|
|
|
|
|
return builder.ToString();
|
|
|
|
|
@@ -33,7 +43,7 @@ public class BuiltInFunctions
|
|
|
{
|
|
|
if (usedFunctions.Contains(type))
|
|
|
{
|
|
|
- builder.Append(source);
|
|
|
+ builder.AppendLine(source);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -45,11 +55,16 @@ public class BuiltInFunctions
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (type is BuiltInFunctionType.HslToRgb)
|
|
|
+ switch (type)
|
|
|
{
|
|
|
- Require(BuiltInFunctionType.HueToRgb);
|
|
|
+ case BuiltInFunctionType.HslToRgb:
|
|
|
+ Require(BuiltInFunctionType.HueToRgb);
|
|
|
+ break;
|
|
|
+ case BuiltInFunctionType.RgbToHsl:
|
|
|
+ Require(BuiltInFunctionType.RgbToHcv);
|
|
|
+ break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
usedFunctions.Add(type);
|
|
|
}
|
|
|
|
|
@@ -73,33 +88,34 @@ public class BuiltInFunctions
|
|
|
}
|
|
|
""";
|
|
|
|
|
|
- // private const string RgbToHcv =
|
|
|
- // """
|
|
|
- // half4 RGBtoHSL(half4 rgba)
|
|
|
- // {
|
|
|
- // half4 p = (rgba.g < rgba.b) ? half4(rgba.bg, -1., 2. / 3.) : half4(rgba.gb, 0., -1. / 3.);
|
|
|
- // half4 q = (rgba.r < p.x) ? half4(p.xyw, rgba.r) : half4(rgba.r, p.yzx);
|
|
|
- // float c = q.x - min(q.w, q.y);
|
|
|
- // float h = abs((q.w - q.y) / (6. * c + EPSILON) + q.z);
|
|
|
- // return half4(h, c, q.x, rgba.w);
|
|
|
- // }
|
|
|
- // """;
|
|
|
- //
|
|
|
- // private const string RgbToHsl =
|
|
|
- // """
|
|
|
- // half4 RGBtoHSL(half4 rgba)
|
|
|
- // {
|
|
|
- // // RGB [0..1] to Hue-Saturation-Lightness [0..1]
|
|
|
- // half3 hcv = RGBtoHCV(rgba.xyz);
|
|
|
- // half z = hcv.z - hcv.y * 0.5;
|
|
|
- // half s = hcv.y / (1. - abs(z * 2. - 1.) + EPSILON);
|
|
|
- // return half4(hcv.x, s, z, rgba.w);
|
|
|
- // }
|
|
|
- // """;
|
|
|
+ private const string RgbToHcv =
|
|
|
+ $$"""
|
|
|
+ half3 {{nameof(RgbToHcv)}}(half3 rgba)
|
|
|
+ {
|
|
|
+ half4 p = (rgba.g < rgba.b) ? half4(rgba.bg, -1., 2. / 3.) : half4(rgba.gb, 0., -1. / 3.);
|
|
|
+ half4 q = (rgba.r < p.x) ? half4(p.xyw, rgba.r) : half4(rgba.r, p.yzx);
|
|
|
+ float c = q.x - min(q.w, q.y);
|
|
|
+ float h = abs((q.w - q.y) / (6. * c) + q.z);
|
|
|
+ return half3(h, c, q.x);
|
|
|
+ }
|
|
|
+ """;
|
|
|
+
|
|
|
+ private const string RgbToHsl =
|
|
|
+ $$"""
|
|
|
+ half4 {{nameof(RgbToHsl)}}(half4 rgba)
|
|
|
+ {
|
|
|
+ half3 hcv = {{nameof(RgbToHcv)}}(rgba.xyz);
|
|
|
+ half z = hcv.z - hcv.y * 0.5;
|
|
|
+ half s = hcv.y / (1. - abs(z * 2. - 1.));
|
|
|
+ return half4(hcv.x, s, z, rgba.w);
|
|
|
+ }
|
|
|
+ """;
|
|
|
|
|
|
enum BuiltInFunctionType
|
|
|
{
|
|
|
HueToRgb,
|
|
|
+ RgbToHcv,
|
|
|
+
|
|
|
RgbToHsl,
|
|
|
HslToRgb,
|
|
|
RgbToHsv,
|