diff --git a/native/cultmath-core/src/lib.rs b/native/cultmath-core/src/lib.rs index 5a48460..46e7ced 100644 --- a/native/cultmath-core/src/lib.rs +++ b/native/cultmath-core/src/lib.rs @@ -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, diff --git a/src/CultMath/Voronoi.cs b/src/CultMath/Voronoi.cs index 52e6acb..9791a8e 100644 --- a/src/CultMath/Voronoi.cs +++ b/src/CultMath/Voronoi.cs @@ -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)));