Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly handle disjoint bounding-box intersections in binning #335

Merged
merged 2 commits into from
Jun 29, 2023

Conversation

armansito
Copy link
Collaborator

@armansito armansito commented Jun 29, 2023

When the bounding boxes of a path and its clip are disjoint (i.e. they do not intersect) the result of their intersection is a negative rectangle.

When calculating the intersection of the bboxes, the binning stage ensures that the bbox is non-negative. It then normalizes the coordinates to bin dimensions and rounds the top-left corner down to the neareast integer and the bottom-right corner up.

However this rounding causes zero-area bounding boxes to have a non-zero area and sends the bottom-right corner to be placed in the next bin. This causes fully clipped out draw objects to be included in binning, with an incorrect clip bounding box that causes them to be erroneously drawn with partial clipping.

binning now takes care around this logic to make sure that a zero-area intersected-bbox gets skipped and clipped out. tile_alloc, also takes care in its own similar logic over intersected-bbox contents.

Fixes #286 and #333

Added a test scene that demonstrates the clipping bugs reported in
vello#286 and vello#333.
@armansito armansito requested a review from raphlinus June 29, 2023 01:41
This was referenced Jun 29, 2023
@armansito armansito requested a review from dfrg June 29, 2023 01:43
@armansito armansito linked an issue Jun 29, 2023 that may be closed by this pull request
Copy link
Contributor

@raphlinus raphlinus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, and exciting to see a fix for this long-standing issue.

@@ -89,12 +89,18 @@ fn main(
let bbox_raw = bbox_intersect(clip_bbox, pb);
// TODO(naga): clunky expression a workaround for broken lhs swizzle
let bbox = vec4(bbox_raw.xy, max(bbox_raw.xy, bbox_raw.zw));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably no longer need the max here, as everything downstream should be able to interpret x1 < x0 or y1 < y0 as an empty box.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@dfrg
Copy link
Collaborator

dfrg commented Jun 29, 2023

Yes! This has been in my queue for a long time and I’ve been dreading hunting it down. I’m excited to test this on some Lottie scenes with known clipping artifacts.

When the bounding boxes of a path and its clip are disjoint (i.e. they
do not intersect) the result of their intersection is a negative
rectangle.

When calculating the intersection of the bboxes, the binning stage
ensures that the bbox is non-negative. It then normalizes the
coordinates to bin dimensions and rounds the top-left corner down
to the neareast integer and the bottom-right corner up.

However this rounding causes zero-area bounding boxes to have a non-zero
area and sends the bottom-right corner to the placed in the next bin.
This causes fully clipped out draw objects to be included in binning,
with an incorrect clip bounding box that causes them to be erroneously
drawn with partial clipping.

`binning` now takes care around this logic to make sure that a zero-area
intersected-bbox gets skipped and clipped out. `tile_alloc`, also takes
care in its logic.

Fixes linebender#286 and linebender#333
@armansito
Copy link
Collaborator Author

Yes! This has been in my queue for a long time and I’ve been dreading hunting it down. I’m excited to test this on some Lottie scenes with known clipping artifacts.

@dfrg Yes, please do! Let me know if this fixes the artifacts you've been seeing with lottie scenes.

@armansito armansito merged commit 4435398 into linebender:main Jun 29, 2023
@armansito armansito deleted the fix-clip-bug branch June 29, 2023 03:59
raphlinus added a commit that referenced this pull request Oct 6, 2023
Basically ports #335, which aggressively culls empty bounding boxes.
raphlinus added a commit that referenced this pull request Oct 7, 2023
Basically ports #335, which aggressively culls empty bounding boxes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect clipping Text clipping artifacts
3 participants