Fix drawing of 0-width borders when quad has other borders (#27511)
Closes #27485 Release Notes: - N/A
This commit is contained in:
parent
130abc8998
commit
7e4320f587
2 changed files with 29 additions and 13 deletions
|
@ -532,6 +532,12 @@ fn fs_quad(input: QuadVarying) -> @location(0) vec4<f32> {
|
||||||
quad.border_widths.top,
|
quad.border_widths.top,
|
||||||
center_to_point.y < 0.0));
|
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
|
// Vector from the corner of the quad bounds to the point, after mirroring
|
||||||
// the point into the bottom right quadrant. Both components are <= 0.
|
// the point into the bottom right quadrant. Both components are <= 0.
|
||||||
let corner_to_point = abs(center_to_point) - half_size;
|
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;
|
corner_center_to_point.y >= 0;
|
||||||
|
|
||||||
// Vector from straight border inner corner to point.
|
// 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.
|
// Whether the point is beyond the inner edge of the straight border.
|
||||||
let is_beyond_inner_straight_border =
|
let is_beyond_inner_straight_border =
|
||||||
straight_border_inner_corner_to_point.x > 0 ||
|
straight_border_inner_corner_to_point.x > 0 ||
|
||||||
straight_border_inner_corner_to_point.y > 0;
|
straight_border_inner_corner_to_point.y > 0;
|
||||||
|
|
||||||
// Whether the point is far enough inside the straight border such that
|
// Whether the point is far enough inside the quad, such that the pixels are
|
||||||
// pixels are not affected by it.
|
// not affected by the straight border.
|
||||||
let is_within_inner_straight_border =
|
let is_within_inner_straight_border =
|
||||||
straight_border_inner_corner_to_point.x < -antialias_threshold &&
|
straight_border_inner_corner_to_point.x < -antialias_threshold &&
|
||||||
straight_border_inner_corner_to_point.y < -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) {
|
} else if (is_beyond_inner_straight_border) {
|
||||||
// Fast path for points that must be outside the inner edge.
|
// Fast path for points that must be outside the inner edge.
|
||||||
inner_sdf = -1.0;
|
inner_sdf = -1.0;
|
||||||
} else if (border.x == border.y) {
|
} else if (reduced_border.x == reduced_border.y) {
|
||||||
// Fast path for circular inner edge.
|
// Fast path for circular inner edge.
|
||||||
inner_sdf = -(outer_sdf + border.x);
|
inner_sdf = -(outer_sdf + reduced_border.x);
|
||||||
} else {
|
} 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);
|
inner_sdf = quarter_ellipse_sdf(corner_center_to_point, ellipse_radii);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
// Vector from the corner of the quad bounds to the point, after mirroring
|
||||||
// the point into the bottom right quadrant. Both components are <= 0.
|
// the point into the bottom right quadrant. Both components are <= 0.
|
||||||
float2 corner_to_point = fabs(center_to_point) - half_size;
|
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.x >= 0.0 &&
|
||||||
corner_center_to_point.y >= 0.0;
|
corner_center_to_point.y >= 0.0;
|
||||||
|
|
||||||
// Vector from straight border inner corner to point
|
// Vector from straight border inner corner to point.
|
||||||
float2 straight_border_inner_corner_to_point = corner_to_point + border;
|
//
|
||||||
|
// 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
|
// Whether the point is beyond the inner edge of the straight border
|
||||||
bool is_beyond_inner_straight_border =
|
bool is_beyond_inner_straight_border =
|
||||||
straight_border_inner_corner_to_point.x > 0.0 ||
|
straight_border_inner_corner_to_point.x > 0.0 ||
|
||||||
straight_border_inner_corner_to_point.y > 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 =
|
bool is_within_inner_straight_border =
|
||||||
straight_border_inner_corner_to_point.x < -antialias_threshold &&
|
straight_border_inner_corner_to_point.x < -antialias_threshold &&
|
||||||
straight_border_inner_corner_to_point.y < -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) {
|
} else if (is_beyond_inner_straight_border) {
|
||||||
// Fast path for points that must be outside the inner edge
|
// Fast path for points that must be outside the inner edge
|
||||||
inner_sdf = -1.0;
|
inner_sdf = -1.0;
|
||||||
} else if (border.x == border.y) {
|
} else if (reduced_border.x == reduced_border.y) {
|
||||||
// Fast path for circular inner edge.
|
// Fast path for circular inner edge.
|
||||||
inner_sdf = -(outer_sdf + border.x);
|
inner_sdf = -(outer_sdf + reduced_border.x);
|
||||||
} else {
|
} 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);
|
inner_sdf = quarter_ellipse_sdf(corner_center_to_point, ellipse_radii);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue