git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commite933422c4efd8066f8fe1596348d9e14ae6f227e
parent94ebff4b66
authorLucas Galante <[email protected]>
date2026-09-20 20:35
Frost: compression 0 is the identity — the near-black guard only runs with compression

resolve_blur cross-faded any backdrop darker than 5% linear to a neutral
grey of equal luminance, unconditionally. The guard exists for the
luminance-remap ratio blowing up near black, a hazard only a non-zero
compression creates; at k = 0 the remap is already the identity. Over a
dark scene every frosted plate lost its hue — the designer's navy
viewport read as grey through its plates (measured 2026-09-20: cell
14,14,15 against scene 13,13,26). Now k = 0 passes the backdrop through
exactly; configs using compression keep the guard.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

 src/vk/shader2d.wgsl | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/vk/shader2d.wgsl b/src/vk/shader2d.wgsl
index 89ab916..0709526 100644
--- a/src/vk/shader2d.wgsl
+++ b/src/vk/shader2d.wgsl
@@ -1091,7 +1091,15 @@ fn resolve_blur(pos: vec2f, color: vec4f, refract: vec2f, clarity: f32, k_in: f3
     // ratio explodes (and a lift past 1 would clip a channel), so cross-fade
     // to the neutral luminance over the bottom of the range instead.
     let scaled = backdrop_color.rgb * (keyed / max(bl, 1e-4));
-    let compressed = mix(vec3f(keyed), scaled, smoothstep(0.0, 0.05, bl));
+    let guarded = mix(vec3f(keyed), scaled, smoothstep(0.0, 0.05, bl));
+    // At k = 0 the remap is the identity (keyed == bl, scaled == backdrop),
+    // and the near-black guard must not run either: it cross-fades any
+    // backdrop darker than 5% linear to a neutral grey of equal luminance,
+    // which stripped the hue from every frosted plate over a dark scene
+    // (the designer's navy viewport came through as grey — measured
+    // 2026-09-20). The guard exists for the ratio's blow-up near black,
+    // a hazard only a non-zero k creates, so it applies only then.
+    let compressed = select(guarded, backdrop_color.rgb, k <= 0.0);
 
     return vec4f(mix(compressed, color.rgb, opacity), 1.0);
 }