Skip to content

Fix/UI node clipping uitransform#23520

Closed
Poico wants to merge 2 commits intobevyengine:mainfrom
Poico:fix/ui-node-clipping-uitransform
Closed

Fix/UI node clipping uitransform#23520
Poico wants to merge 2 commits intobevyengine:mainfrom
Poico:fix/ui-node-clipping-uitransform

Conversation

@Poico
Copy link
Copy Markdown

@Poico Poico commented Mar 25, 2026

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.

Poico and others added 2 commits March 21, 2026 21:54
…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>
@github-actions
Copy link
Copy Markdown
Contributor

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 alice-i-cecile added C-Bug An unexpected or incorrect behavior A-UI Graphical user interfaces, styles, layouts, and widgets S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Mar 25, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in UI Mar 25, 2026
Copy link
Copy Markdown
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

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

Nice! Can you add an example of this being done correctly to the ui_testbed and upload a screenshot of that before and after? :)

@alice-i-cecile alice-i-cecile added A-Rendering Drawing game state to the screen D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes labels Mar 25, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Rendering Mar 25, 2026
@Poico
Copy link
Copy Markdown
Author

Poico commented Mar 25, 2026

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?

@alice-i-cecile
Copy link
Copy Markdown
Member

Yep, no rush at all. Thanks for the fix!

Copy link
Copy Markdown
Contributor

@ickshonpe ickshonpe left a comment

Choose a reason for hiding this comment

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

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:

Image

@ickshonpe ickshonpe added D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged S-Nominated-To-Close A triage team member thinks this PR or issue should be closed out. and removed D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 4, 2026
@github-project-automation github-project-automation Bot moved this from Needs SME Triage to Done in UI May 4, 2026
@github-project-automation github-project-automation Bot moved this from Needs SME Triage to Done in Rendering May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen A-UI Graphical user interfaces, styles, layouts, and widgets C-Bug An unexpected or incorrect behavior D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Nominated-To-Close A triage team member thinks this PR or issue should be closed out. S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged

Projects

Status: Done
Status: Done

Development

Successfully merging this pull request may close these issues.

UiTransform.scale breaks text rendering, image scaling and border radius

3 participants