diff --git a/crates/gpui_macos/src/shaders.metal b/crates/gpui_macos/src/shaders.metal index 3c6adac3359ac41ee0cc265480dae6e63a2c2136..4dc2d334e1e0929cc2ee7369ecce2f074b919366 100644 --- a/crates/gpui_macos/src/shaders.metal +++ b/crates/gpui_macos/src/shaders.metal @@ -1215,6 +1215,20 @@ float4 fill_color(Background background, break; } } + + // Dither to reduce banding in gradients (especially dark/alpha). + // Triangular-distributed noise breaks up 8-bit quantization steps. + // ±2/255 for RGB (enough for dark-on-dark compositing), + // ±3/255 for alpha (needs more because alpha × dark color = tiny steps). + { + float2 seed = position * 0.6180339887; // golden ratio spread + float r1 = fract(sin(dot(seed, float2(12.9898, 78.233))) * 43758.5453); + float r2 = fract(sin(dot(seed, float2(39.3460, 11.135))) * 24634.6345); + float tri = r1 + r2 - 1.0; // triangular PDF, range [-1, +1] + color.rgb += tri * 2.0 / 255.0; + color.a += tri * 3.0 / 255.0; + } + break; } case 2: { diff --git a/crates/gpui_windows/src/shaders.hlsl b/crates/gpui_windows/src/shaders.hlsl index f508387daf9c98ffcce521209d2c981cf04db983..646cfd61cc37c31fade09d427c6d7c8f87519fa6 100644 --- a/crates/gpui_windows/src/shaders.hlsl +++ b/crates/gpui_windows/src/shaders.hlsl @@ -384,6 +384,20 @@ float4 gradient_color(Background background, break; } } + + // Dither to reduce banding in gradients (especially dark/alpha). + // Triangular-distributed noise breaks up 8-bit quantization steps. + // ±2/255 for RGB (enough for dark-on-dark compositing), + // ±3/255 for alpha (needs more because alpha × dark color = tiny steps). + { + float2 seed = position * 0.6180339887; // golden ratio spread + float r1 = frac(sin(dot(seed, float2(12.9898, 78.233))) * 43758.5453); + float r2 = frac(sin(dot(seed, float2(39.3460, 11.135))) * 24634.6345); + float tri = r1 + r2 - 1.0; // triangular PDF, range [-1, +1] + color.rgb += tri * 2.0 / 255.0; + color.a += tri * 3.0 / 255.0; + } + break; } case 2: {