From d02bfe1e95387d139bfe189ae0fbc025f0b39096 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 6 Jan 2025 12:27:20 -0500 Subject: [PATCH] Add a case for shadows when blur_radius = 0 (#22441) Closes #22433 Before/After (macOS): ![CleanShot 2024-12-26 at 22 41 11@2x](https://github.com/user-attachments/assets/1701da2e-3db7-4dd1-a680-0f63824cbdf5) For some reason the non-blurred one seems much lower quality, so we may need to tinker with the samples, or something else. ![CleanShot 2024-12-26 at 22 42 12@2x](https://github.com/user-attachments/assets/5a43330d-137b-4d45-a67a-fd10ef6a8ff8) I'm unsure if this is a problem on Linux/in the Blade renderer, but since no changes were made outside of the medal shaders we can probably take this macOS-specific win for now. Release Notes: - gpui: Fixed an issue where shadows with a `blur_radius` of 0 would not render. --- crates/gpui/src/platform/mac/shaders.metal | 36 +++++++++++++--------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/crates/gpui/src/platform/mac/shaders.metal b/crates/gpui/src/platform/mac/shaders.metal index d8ad197a91d4f1b61d0840ca9cff1e5b3350f04e..7ee5d63add1516f5a9f9611cdf572ffd1aaf7210 100644 --- a/crates/gpui/src/platform/mac/shaders.metal +++ b/crates/gpui/src/platform/mac/shaders.metal @@ -227,21 +227,27 @@ fragment float4 shadow_fragment(ShadowFragmentInput input [[stage_in]], } } - // The signal is only non-zero in a limited range, so don't waste samples - float low = point.y - half_size.y; - float high = point.y + half_size.y; - float start = clamp(-3. * shadow.blur_radius, low, high); - float end = clamp(3. * shadow.blur_radius, low, high); - - // Accumulate samples (we can get away with surprisingly few samples) - float step = (end - start) / 4.; - float y = start + step * 0.5; - float alpha = 0.; - for (int i = 0; i < 4; i++) { - alpha += blur_along_x(point.x, point.y - y, shadow.blur_radius, - corner_radius, half_size) * - gaussian(y, shadow.blur_radius) * step; - y += step; + float alpha; + if (shadow.blur_radius == 0.) { + float distance = quad_sdf(input.position.xy, shadow.bounds, shadow.corner_radii); + alpha = saturate(0.5 - distance); + } else { + // The signal is only non-zero in a limited range, so don't waste samples + float low = point.y - half_size.y; + float high = point.y + half_size.y; + float start = clamp(-3. * shadow.blur_radius, low, high); + float end = clamp(3. * shadow.blur_radius, low, high); + + // Accumulate samples (we can get away with surprisingly few samples) + float step = (end - start) / 4.; + float y = start + step * 0.5; + alpha = 0.; + for (int i = 0; i < 4; i++) { + alpha += blur_along_x(point.x, point.y - y, shadow.blur_radius, + corner_radius, half_size) * + gaussian(y, shadow.blur_radius) * step; + y += step; + } } return input.color * float4(1., 1., 1., alpha);