Broaden Voronoi color spectrum

This commit is contained in:
Meta Vens 2026-06-03 04:08:48 +01:00
commit b79b6d047f
2 changed files with 79 additions and 16 deletions

View file

@ -55,9 +55,9 @@ fn tone_color(px: f32, py: f32, resolution_y: f32, frame_index: i32, tone: u8, s
}
_ => {
let (gain, lift) = match tone {
1 => (0.25, 6.0),
2 => (0.95, 20.0),
_ => (0.16, 2.0),
1 => (0.42, 14.0),
2 => (1.05, 24.0),
_ => (0.24, 4.0),
};
color(
lift + sample.0 * 255.0 * gain,
@ -102,9 +102,8 @@ fn voronoi(px: f32, py: f32, resolution_y: f32, frame_index: i32) -> (f32, f32,
let dy = (gy - fy + oy).abs();
let d = dx.max(dy) * weight;
let seed = hash1((nx + gx) * 7.0 + (ny + gy) * 113.0);
let candidate_red = 0.5 + 0.5 * (seed * 2.5 + 3.5 + 2.0).sin();
let candidate_green = 0.5 + 0.5 * (seed * 2.5 + 3.5 + 3.0).sin();
let candidate_blue = 0.5 + 0.5 * (seed * 2.5 + 3.5 + 2.0).sin();
let hue = frac((nx + gx) * 0.173 + (ny + gy) * 0.379 + seed * 0.431);
let (candidate_red, candidate_green, candidate_blue) = pastel_spectrum(hue);
let h = smoothstep(0.0, 1.0, 0.5 + 0.5 * (distance - d) / smoothness);
let correction = h * (1.0 - h) * smoothness / (1.0 + 3.0 * smoothness);
distance = lerp(distance, d, h) - correction;
@ -150,6 +149,32 @@ fn lerp(start: f32, end: f32, amount: f32) -> f32 {
start + (end - start) * amount
}
fn pastel_spectrum(hue: f32) -> (f32, f32, f32) {
hsv_to_rgb(hue, 0.52, 0.98)
}
fn hsv_to_rgb(hue: f32, saturation: f32, value: f32) -> (f32, f32, f32) {
let h = frac(hue) * 6.0;
let c = value * saturation;
let x = c * (1.0 - ((h % 2.0) - 1.0).abs());
let m = value - c;
let (r, g, b) = if h < 1.0 {
(c, x, 0.0)
} else if h < 2.0 {
(x, c, 0.0)
} else if h < 3.0 {
(0.0, c, x)
} else if h < 4.0 {
(0.0, x, c)
} else if h < 5.0 {
(x, 0.0, c)
} else {
(c, 0.0, x)
};
(r + m, g + m, b + m)
}
fn color(r: f32, g: f32, b: f32) -> CultMathColor32 {
CultMathColor32 {
r: r.clamp(0.0, 255.0) as u8,

View file

@ -109,15 +109,15 @@ public static class Voronoi
var gain = tone switch
{
CultMathTone.Panel => 0.25f,
CultMathTone.Edge => 0.95f,
_ => 0.16f,
CultMathTone.Panel => 0.42f,
CultMathTone.Edge => 1.05f,
_ => 0.24f,
};
var lift = tone switch
{
CultMathTone.Panel => 6.0f,
CultMathTone.Edge => 20.0f,
_ => 2.0f,
CultMathTone.Panel => 14.0f,
CultMathTone.Edge => 24.0f,
_ => 4.0f,
};
return new Color32(
(byte)Math.Clamp(lift + sample.x * 255.0f * gain, 0, 255),
@ -152,10 +152,8 @@ public static class Voronoi
var d2 = math.abs(g - f + o);
var d = Math.Max(d2.x, d2.y) * weight;
var seed = Hash1(math.dot(n + g, new float2(7.0f, 113.0f)));
var candidate = 0.5f + 0.5f * new float3(
math.sin(seed * 2.5f + 3.5f + 2.0f),
math.sin(seed * 2.5f + 3.5f + 3.0f),
math.sin(seed * 2.5f + 3.5f + 2.0f));
var hue = math.frac((n.x + g.x) * 0.173f + (n.y + g.y) * 0.379f + seed * 0.431f);
var candidate = PastelSpectrum(hue);
var h = math.smoothstep(0.0f, 1.0f, 0.5f + 0.5f * (distance - d) / smoothness);
var correction = h * (1.0f - h) * smoothness / (1.0f + 3.0f * smoothness);
distance = math.lerp(distance, d, h) - correction;
@ -168,6 +166,46 @@ public static class Voronoi
private static float Hash1(float value) => math.frac(math.sin(value) * 43758.5453f);
private static float3 PastelSpectrum(float hue)
{
return HsvToRgb(hue, 0.52f, 0.98f);
}
private static float3 HsvToRgb(float hue, float saturation, float value)
{
var h = math.frac(hue) * 6.0f;
var c = value * saturation;
var x = c * (1.0f - Math.Abs(h % 2.0f - 1.0f));
var m = value - c;
float3 rgb;
if (h < 1.0f)
{
rgb = new float3(c, x, 0.0f);
}
else if (h < 2.0f)
{
rgb = new float3(x, c, 0.0f);
}
else if (h < 3.0f)
{
rgb = new float3(0.0f, c, x);
}
else if (h < 4.0f)
{
rgb = new float3(0.0f, x, c);
}
else if (h < 5.0f)
{
rgb = new float3(x, 0.0f, c);
}
else
{
rgb = new float3(c, 0.0f, x);
}
return rgb + m;
}
private static float2 Hash2(float2 value)
{
var p = new float2(math.dot(value, new float2(127.1f, 311.7f)), math.dot(value, new float2(269.5f, 183.3f)));