Fix drawing of 0-width borders when quad has other borders (#27511)

Closes #27485

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2025-03-26 11:13:34 -06:00 committed by GitHub
parent 130abc8998
commit 7e4320f587
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 13 deletions

View file

@ -532,6 +532,12 @@ fn fs_quad(input: QuadVarying) -> @location(0) vec4<f32> {
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<f32>(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<f32> {
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<f32> {
} 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<f32>(0.0), corner_radius - border);
let ellipse_radii = max(vec2<f32>(0.0), corner_radius - reduced_border);
inner_sdf = quarter_ellipse_sdf(corner_center_to_point, ellipse_radii);
}