Fix/UI node clipping uitransform#23520
Conversation
…rotation When a UI node has a non-identity UiTransform (scale or rotation), the clipping code produced incorrect results. - With scale: screen-space clipping deltas were applied directly to UVs and the SDF `point` attribute, which are in local node space, causing inverted image scaling and incorrect border-radius rendering on clipped, scaled nodes. Fixed by converting the deltas to local space via the inverse of the transform matrix. - With rotation: axis-aligned vertex clipping moves corners in screen space, which is incorrect for a rotated quad whose corners are not aligned with the clip rect axes. Fixed by passing the clip rect to the fragment shader as a new vertex attribute and discarding fragments outside it, leaving vertices unmodified. Unit tests for the scale fix are added to `bevy_ui_render`. Fixes bevyengine#22880 Signed-off-by: Rodrigo Gomes <rodrigo.c.gomes@tecnico.ulisboa.pt>
|
Welcome, new contributor! Please make sure you've read our contributing guide, as well as our policy regarding AI usage, and we look forward to reviewing your pull request shortly ✨ |
alice-i-cecile
left a comment
There was a problem hiding this comment.
Nice! Can you add an example of this being done correctly to the ui_testbed and upload a screenshot of that before and after? :)
|
Hi, until the final of the week I will be in a conference would it be ok if I do this until Tuesday of next week as the computer I'm currently on takes too long to compile bevy? |
|
Yep, no rush at all. Thanks for the fix! |
There was a problem hiding this comment.
This approach has too many limitations I think unfortunately. The clipping region won't necessarily be a rectangle so passing a rect into the shader isn't enough, a clipping implementation needs to use a stencil buffer or something. Also the clip rect is always aligned with the viewport, so if the overflow-clip node is rotated, its children are clipped incorrectly:
Fix UI node clipping when a UiTransform with scale or rotation is applied to a UI node.
Fixes #22880
Solution
Two separate bugs were addressed:
Scale: Screen-space clipping deltas were being applied directly to UVs and the SDF point attribute, which live in local node space. This caused inverted image scaling and incorrect border-radius rendering on clipped, scaled nodes. Fixed by converting the deltas to local space using the inverse of the transform matrix.
Rotation: Axis-aligned vertex clipping moves corners in screen space, which is incorrect for a rotated quad whose corners are not aligned with the clip rect axes. Fixed by passing the clip rect to the fragment shader as a new vertex attribute and discarding fragments outside it, leaving vertices unmodified.
Changes are in [bevy_ui_render/src/lib.rs], [bevy_ui_render/src/pipeline.rs], and [bevy_ui_render/src/ui.wgsl].
Testing
Unit tests for the scale fix were added to bevy_ui_render. To manually test, spawn a UI node with a UiTransform that applies scale and/or rotation, place it inside a clipping container, and verify that the image, UV mapping, and border-radius render correctly.