diff --git a/crates/gpui/src/platform/blade/shaders.wgsl b/crates/gpui/src/platform/blade/shaders.wgsl index 324a920d65..0d8c43a55a 100644 --- a/crates/gpui/src/platform/blade/shaders.wgsl +++ b/crates/gpui/src/platform/blade/shaders.wgsl @@ -532,6 +532,12 @@ fn fs_quad(input: QuadVarying) -> @location(0) vec4 { quad.border_widths.top, center_to_point.y < 0.0)); + // 0-width borders are reduced so that `inner_sdf >= antialias_threshold`. + // The purpose of this is to not draw antialiasing pixels in this case. + let reduced_border = + vec2(select(border.x, -antialias_threshold, border.x == 0.0), + select(border.y, -antialias_threshold, border.y == 0.0)); + // Vector from the corner of the quad bounds to the point, after mirroring // the point into the bottom right quadrant. Both components are <= 0. let corner_to_point = abs(center_to_point) - half_size; @@ -546,15 +552,15 @@ fn fs_quad(input: QuadVarying) -> @location(0) vec4 { corner_center_to_point.y >= 0; // Vector from straight border inner corner to point. - let straight_border_inner_corner_to_point = corner_to_point + border; + let straight_border_inner_corner_to_point = corner_to_point + reduced_border; // Whether the point is beyond the inner edge of the straight border. let is_beyond_inner_straight_border = straight_border_inner_corner_to_point.x > 0 || straight_border_inner_corner_to_point.y > 0; - // Whether the point is far enough inside the straight border such that - // pixels are not affected by it. + // Whether the point is far enough inside the quad, such that the pixels are + // not affected by the straight border. let is_within_inner_straight_border = straight_border_inner_corner_to_point.x < -antialias_threshold && straight_border_inner_corner_to_point.y < -antialias_threshold; @@ -589,11 +595,11 @@ fn fs_quad(input: QuadVarying) -> @location(0) vec4 { } else if (is_beyond_inner_straight_border) { // Fast path for points that must be outside the inner edge. inner_sdf = -1.0; - } else if (border.x == border.y) { + } else if (reduced_border.x == reduced_border.y) { // Fast path for circular inner edge. - inner_sdf = -(outer_sdf + border.x); + inner_sdf = -(outer_sdf + reduced_border.x); } else { - let ellipse_radii = max(vec2(0.0), corner_radius - border); + let ellipse_radii = max(vec2(0.0), corner_radius - reduced_border); inner_sdf = quarter_ellipse_sdf(corner_center_to_point, ellipse_radii); } diff --git a/crates/gpui/src/platform/mac/shaders.metal b/crates/gpui/src/platform/mac/shaders.metal index 62bcf26f06..85e2f439e2 100644 --- a/crates/gpui/src/platform/mac/shaders.metal +++ b/crates/gpui/src/platform/mac/shaders.metal @@ -133,6 +133,12 @@ fragment float4 quad_fragment(QuadFragmentInput input [[stage_in]], center_to_point.y < 0.0 ? quad.border_widths.top : quad.border_widths.bottom ); + // 0-width borders are reduced so that `inner_sdf >= antialias_threshold`. + // The purpose of this is to not draw antialiasing pixels in this case. + float2 reduced_border = float2( + border.x == 0.0 ? -antialias_threshold : border.x, + border.y == 0.0 ? -antialias_threshold : border.y); + // Vector from the corner of the quad bounds to the point, after mirroring // the point into the bottom right quadrant. Both components are <= 0. float2 corner_to_point = fabs(center_to_point) - half_size; @@ -146,16 +152,20 @@ fragment float4 quad_fragment(QuadFragmentInput input [[stage_in]], corner_center_to_point.x >= 0.0 && corner_center_to_point.y >= 0.0; - // Vector from straight border inner corner to point - float2 straight_border_inner_corner_to_point = corner_to_point + border; + // Vector from straight border inner corner to point. + // + // 0-width borders are turned into width -1 so that inner_sdf is > 1.0 near + // the border. Without this, antialiasing pixels would be drawn. + float2 straight_border_inner_corner_to_point = corner_to_point + reduced_border; // Whether the point is beyond the inner edge of the straight border bool is_beyond_inner_straight_border = straight_border_inner_corner_to_point.x > 0.0 || straight_border_inner_corner_to_point.y > 0.0; - // Whether the point is far enough inside the straight border such that - // pixels are not affected by it + + // Whether the point is far enough inside the quad, such that the pixels are + // not affected by the straight border. bool is_within_inner_straight_border = straight_border_inner_corner_to_point.x < -antialias_threshold && straight_border_inner_corner_to_point.y < -antialias_threshold; @@ -184,11 +194,11 @@ fragment float4 quad_fragment(QuadFragmentInput input [[stage_in]], } else if (is_beyond_inner_straight_border) { // Fast path for points that must be outside the inner edge inner_sdf = -1.0; - } else if (border.x == border.y) { + } else if (reduced_border.x == reduced_border.y) { // Fast path for circular inner edge. - inner_sdf = -(outer_sdf + border.x); + inner_sdf = -(outer_sdf + reduced_border.x); } else { - float2 ellipse_radii = max(float2(0.0), float2(corner_radius) - border); + float2 ellipse_radii = max(float2(0.0), float2(corner_radius) - reduced_border); inner_sdf = quarter_ellipse_sdf(corner_center_to_point, ellipse_radii); }