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

UI texture slice texture flipping reimplementation #15034

Merged
merged 15 commits into from
Sep 4, 2024

Conversation

ickshonpe
Copy link
Contributor

@ickshonpe ickshonpe commented Sep 3, 2024

Objective

Fixes #15032

Solution

Reimplement support for the flip_x and flip_y fields.
This doesn't flip the border geometry, I'm not really sure whether that is desirable or not.
Also fixes a bug that was causing the side and center slices to tile incorrectly.

Testing

cargo run --example ui_texture_slice_flip_and_tile

Showcase

nearest With tiling need to use nearest filtering to avoid bleeding between the slices.

@ickshonpe ickshonpe changed the title UI texture slice texture flipping UI texture slice texture flipping reimplementation Sep 3, 2024
@alice-i-cecile alice-i-cecile added this to the 0.14.2 milestone Sep 3, 2024
@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen A-UI Graphical user interfaces, styles, layouts, and widgets labels Sep 3, 2024
@ickshonpe
Copy link
Contributor Author

Seems to work, just going to get something to eat then I'll make a few more test examples to be sure.

@alice-i-cecile alice-i-cecile added the S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged label Sep 3, 2024
@ickshonpe
Copy link
Contributor Author

It seems to be alright but I'd be happiest if @ManevilleF could have a look before it's merged.

@alice-i-cecile alice-i-cecile added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Sep 3, 2024
Copy link
Contributor

github-actions bot commented Sep 3, 2024

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@alice-i-cecile
Copy link
Member

FYI @janhohenheim, this is the other blocker on 0.14.2 :)

Copy link
Member

@janhohenheim janhohenheim left a comment

Choose a reason for hiding this comment

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

Looks good except for one potential mistake that I'd like sorted out. The rest are just minor style nits.
Thanks for adding an example with the implementation, I really appreciate it :)

Copy link
Member

Choose a reason for hiding this comment

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

FYI, you can shave off half of the size of this png with oxipng, but at this low filesize I'm fine with merging as-is. Something to keep in mind for bigger pngs :)

let tsx = target_size.x * (1. - border[0] - border[2]);
let tsy = target_size.y * (1. - border[1] - border[3]);
let isx = image_size.x * (slices[2] - slices[0]);
let isy = image_size.y * (slices[2] - slices[1]);
Copy link
Member

@janhohenheim janhohenheim Sep 4, 2024

Choose a reason for hiding this comment

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

Don't know much about the nine-patch implementation, but the code before used 3 instead of 2 on this line.
I assume that's what you meant with your quote

Also fixes a bug that was causing the side and center slices to tile incorrectly.

?

Can't comment on the mathematical correctness of this change in general. It looks like it's doing something else than before mathematically? Could you comment on that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the old texture slicing implementation (which used a separate sprite for each slice) insets were used to define the slices, but I found it more natural to use normalized coordinates, offset from the the top-left corner.

So previously nine slicing a 100x100 image with 25x25 border corner pieces you had

border = [
    0.25 // left inset,
    0.25 // top inset,
    0.25 // right inset,
    0.25 // bottom inset,
]

and then to calculate the normalized width of the horizontal side and center sections it would do:
1 - border[0] - border[2] = 1 - 0.25 - 0.25 = 0.5

whereas now it's

border = [
    0.25 // top-left x,
    0.25 // top-left y,
    0.75 // bottom-right x,
    0.75 // bottom-right y,
]

and to get the normalized width it's
border[2] - border[0] = 0.75 - 0.25 = 0.5

Copy link
Contributor

Choose a reason for hiding this comment

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

Does that affect how users define the slices? Will it break current usage ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No the user API should behave the same as before, the coordinates change is just for the internal calculations.

examples/ui/ui_texture_slice_flip_and_tile.rs Outdated Show resolved Hide resolved
examples/ui/ui_texture_slice_flip_and_tile.rs Outdated Show resolved Hide resolved
let image = asset_server.load_with_settings(
"textures/fantasy_ui_borders/numbered_slices.png",
|settings: &mut ImageLoaderSettings| {
// Need to use nearest filtering to avoid bleeding between the slices with tiling
Copy link
Member

Choose a reason for hiding this comment

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

That's only because they're pixely, right? Would a more high-res png also require this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It depends on the texture and the result the user wants. If, as in the ui_texture_slice example, the source texture is seamless and the sides are just mono-coloured horizontal and vertical lines then it can be stretched or tiled without any artifacts even with blending.

With the numbered texture from the example here, there is bleeding between each slice if you use ImageSampler::linear(). The same was true of the previous implementation using multiple sprites, it's not a regression at least.

examples/ui/ui_texture_slice_flip_and_tile.rs Outdated Show resolved Hide resolved
examples/ui/ui_texture_slice_flip_and_tile.rs Outdated Show resolved Hide resolved
@@ -0,0 +1,75 @@
//! This example illustrates how to how to flip and tile images with 9 Slicing in the UI
Copy link
Member

@janhohenheim janhohenheim Sep 4, 2024

Choose a reason for hiding this comment

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

Some links or a basic explanation as to what 9-slicing even is would nice for beginners.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I'd rather make an issue and leave that for a separate PR. The new example is just adapated from the ui_texture_slice.rs example which didn't have much in the way of explanation either.

Copy link
Member

@janhohenheim janhohenheim left a comment

Choose a reason for hiding this comment

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

Lovely changes, thanks! Left two very minor suggestions to apply, feel free to ignore :)

examples/ui/ui_texture_slice_flip_and_tile.rs Outdated Show resolved Hide resolved
examples/ui/ui_texture_slice_flip_and_tile.rs Outdated Show resolved Hide resolved
Co-authored-by: Jan Hohenheim <[email protected]>
@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Sep 4, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Sep 4, 2024
Merged via the queue into bevyengine:main with commit 8ac745a Sep 4, 2024
31 checks passed
mockersf pushed a commit that referenced this pull request Sep 5, 2024
# Objective

Fixes #15032

## Solution

Reimplement support for the `flip_x` and `flip_y` fields.
This doesn't flip the border geometry, I'm not really sure whether that
is desirable or not.
Also fixes a bug that was causing the side and center slices to tile
incorrectly.

### Testing

```
cargo run --example ui_texture_slice_flip_and_tile
```

## Showcase
<img width="787" alt="nearest"
src="https://github.com/user-attachments/assets/bc044bae-1748-42ba-92b5-0500c87264f6">
With tiling need to use nearest filtering to avoid bleeding between the
slices.

---------

Co-authored-by: Jan Hohenheim <[email protected]>
Co-authored-by: Alice Cecile <[email protected]>
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 S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nine-patch shaders should support image flipping
4 participants