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 9 slice #11600

Merged
merged 16 commits into from
Feb 7, 2024
Merged

Conversation

ManevilleF
Copy link
Contributor

@ManevilleF ManevilleF commented Jan 29, 2024

Follow up to #10588
Closes #11749 (Supersedes #11756)

Enable Texture slicing for the following UI nodes:

  • ImageBundle
  • ButtonBundle
Screenshot 2024-01-29 at 13 57 43

I also added a collection of fantazy-ui-borders from Kenney's assets, with the appropriate license (CC).
If it's a problem I can use the same textures as the sprite_slice example

Work done

Added the ImageScaleMode component to the targetted bundles, most of the logic is directly reused from bevy_sprite.
The only additional internal component is the UI specific ComputedSlices, which does the same thing as its spritee equivalent but adapted to UI code.

Again the slicing is not compatible with TextureAtlas, it's something I need to tackle more deeply in the future

Fixes

  • I noticed that TextureSlicer::compute_slices could infinitely loop if the border was larger that the image half extents, now an error is triggered and the texture will fallback to being stretched
  • I noticed that when using small textures with very small tiling options we could generate hundred of thousands of slices. Now I set a minimum size of 1 pixel per slice, which is already ridiculously small, and a warning will be sent at runtime when slice count goes above 1000
  • Sprite slicing with flip_x or flip_y would give incorrect results, correct flipping is now supported to both sprites and ui image nodes thanks to @odecay observation

GPU Alternative

I create a separate branch attempting to implementing 9 slicing and tiling directly through the ui.wgsl fragment shader. It works but requires sending more data to the GPU:

  • slice border
  • tiling factors

And more importantly, the actual quad scale which is hard to put in the shader with the current code, so that would be for a later iteration

@ManevilleF
Copy link
Contributor Author

@alice-i-cecile I think this should go to 0.13 as long as the sprite slices, the UI feature is probably even more useful than the sprite counterpart

Copy link
Contributor

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.

2 similar comments
Copy link
Contributor

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.

Copy link
Contributor

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 alice-i-cecile added this to the 0.13 milestone Jan 29, 2024
@alice-i-cecile
Copy link
Member

I agree: the UI equivalent is heavily awaited and I'd like to be able to land both at once.

@@ -0,0 +1,177 @@
// This module is mostly copied and pasted from `bevy_sprite::texture_slice`
//
// A more centralized solution should be investigated in the future
Copy link
Member

Choose a reason for hiding this comment

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

Strongly agree. The API duplication between 2D and UI, and the inconsistencies and delays we get is something that's been on my mind lately.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tbh most of the code is not duplicated the main components and logic are reused, what is duplicated and adapted is the ComputedTextureSlices code, so only the cache elements with the sprite/ui specific logic

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Anyway in the future we might want to implement slicing directly in the shader

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen A-UI Graphical user interfaces, styles, layouts, and widgets labels Jan 29, 2024
@ManevilleF
Copy link
Contributor Author

@alice-i-cecile What about the new textures ? Do you think keeping them makes sense or should I only keep the one in use ?

@alice-i-cecile
Copy link
Member

I like the new textures a lot: I think they clearly demonstrate the value in a more appropriate way.

@ManevilleF
Copy link
Contributor Author

I like the new textures a lot: I think they clearly demonstrate the value in a more appropriate way.

Great, but I added the whole pack in the assets folder, so we might want to remove the unused ones from the version control

@alice-i-cecile
Copy link
Member

Yeah, let's strip it down to only the ones that we use. We can always add more later if we find a use in other examples.

@odecay
Copy link

odecay commented Feb 6, 2024

Working on giving this a review, I noticed some left over unused system set ordering which seems like it was changed here #5103 (comment) in the Texture Atlas rework.

@mockersf
Copy link
Member

mockersf commented Feb 6, 2024

could you also add the assets you're adding to https:/bevyengine/bevy/blob/main/CREDITS.md with the direct link to Kenney's pack containing them and their license?

@ManevilleF
Copy link
Contributor Author

could you also add the assets you're adding to https:/bevyengine/bevy/blob/main/CREDITS.md with the direct link to Kenney's pack containing them and their license?

Sure, currently the license file is in the asset sub folder, so in addition to the credits where should the license file be?

@mockersf
Copy link
Member

mockersf commented Feb 6, 2024

it's a CC0 license so the license file is not strictly needed, it could be removed.

Copy link

@odecay odecay left a comment

Choose a reason for hiding this comment

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

I see there is a note to support flipping, but it seems like there is an issue with the default orientation.

crates/bevy_ui/src/texture_slice.rs Outdated Show resolved Hide resolved
@ManevilleF
Copy link
Contributor Author

I see there is a note to support flipping, but it seems like there is an issue with the default orientation.

It was tricky but I fixed the flipped issue and added flipping support for sliced textures

@ManevilleF
Copy link
Contributor Author

ManevilleF commented Feb 7, 2024

@alice-i-cecile Do you know why the CI fails on check-bans ? What can I do to fix this ?

@mockersf
Copy link
Member

mockersf commented Feb 7, 2024

@alice-i-cecile Do you know why the CI fails on check-bans ? What can I do to fix this ?

you can't, and it's not blocking for merging (it doesn't have the "required" tag)

Copy link
Member

@mockersf mockersf left a comment

Choose a reason for hiding this comment

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

I'm unhappy about the need for a compute_slices_on_asset_event system, and even worse that it was already added for sprites.

I think 9-slice enabled ui elements and sprites should not be part of the existing bundles but in new bundles, or a "add this component ImageScaleMode to any entity with an image and it will be sliced/scaled/tiled, otherwise it will be just scaled and nothing fancy will happen"

This has already been added for sprites, so approving here for feature parity

Copy link

@odecay odecay left a comment

Choose a reason for hiding this comment

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

Nice, the flipping works as expected now and the default orientation is correct.
The ordering cleanup also looks 👍
LGTM

@ManevilleF
Copy link
Contributor Author

I'm unhappy about the need for a compute_slices_on_asset_event system, and even worse that it was already added for sprites.

This is an optimization to avoid re computing the slices every frames, in a prepare or extract stage. It's not ideal but untile we are able to do slicing on the GPU I don't have a better solution

I think 9-slice enabled ui elements and sprites should not be part of the existing bundles but in new bundles, or a "add this component ImageScaleMode to any entity with an image and it will be sliced/scaled/tiled, otherwise it will be just scaled and nothing fancy will happen"

Since the sprite slicing was not released yet we can remove the scale mode from the sprite and UI bundles, note that in UI it was only added to bundles with a UI image

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Feb 7, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Feb 7, 2024
@mockersf
Copy link
Member

mockersf commented Feb 7, 2024

I'm unhappy about the need for a compute_slices_on_asset_event system, and even worse that it was already added for sprites.

This is an optimization to avoid re computing the slices every frames, in a prepare or extract stage. It's not ideal but untile we are able to do slicing on the GPU I don't have a better solution

Yup, what I'm unhappy about is that any change to an image asset will go through all image (2d or UI) entities, even when you're not using 9 slice at all

I think 9-slice enabled ui elements and sprites should not be part of the existing bundles but in new bundles, or a "add this component ImageScaleMode to any entity with an image and it will be sliced/scaled/tiled, otherwise it will be just scaled and nothing fancy will happen"

Since the sprite slicing was not released yet we can remove the scale mode from the sprite and UI bundles, note that in UI it was only added to bundles with a UI image

I would like that. Do you think we should duplicate all bundles with an added ImageScaleMode component? Or have it as a free standing component, and show in the examples and doc "add this component and stuff happens"? @alice-i-cecile, do you have an opinion?

Merged via the queue into bevyengine:main with commit ab16f5e Feb 7, 2024
27 of 28 checks passed
@ManevilleF
Copy link
Contributor Author

Yup, what I'm unhappy about is that any change to an image asset will go through all image (2d or UI) entities, even when you're not using 9 slice at all

Honestly we can just remove those systems, the slices won't refresh if you change the image asset directly but users can be responsible to trigger change detection

I think 9-slice enabled ui elements and sprites should not be part of the existing bundles but in new bundles, or a "add this component ImageScaleMode to any entity with an image and it will be sliced/scaled/tiled, otherwise it will be just scaled and nothing fancy will happen"

Since the sprite slicing was not released yet we can remove the scale mode from the sprite and UI bundles, note that in UI it was only added to bundles with a UI image

I would like that. Do you think we should duplicate all bundles with an added ImageScaleMode component? Or have it as a free standing component, and show in the examples and doc "add this component and stuff happens"? @alice-i-cecile, do you have an opinion?

I feel we might be adding too many bundles that are basically the same as others with one extra component.
For example the sprite sheet bundle is strictly identical to the sprite bundle with one extra component. So maybe we could have some "basic" bundles and explain the possible additional behaviour through extra components? This would be fixed by optional components in bundles too I think

github-merge-queue bot pushed a commit that referenced this pull request Feb 9, 2024
> Follow up to #11600 and #10588 

@mockersf expressed some [valid
concerns](#11600 (comment))
about the current system this PR attempts to fix:

The `ComputedTextureSlices` reacts to asset change in both `bevy_sprite`
and `bevy_ui`, meaning that if the `ImageScaleMode` is inserted by
default in the bundles, we will iterate through most 2d items every time
an asset is updated.

# Solution

- `ImageScaleMode` only has two variants: `Sliced` and `Tiled`. I
removed the `Stretched` default
- `ImageScaleMode` is no longer part of any bundle, but the relevant
bundles explain that this additional component can be inserted

This way, the *absence* of `ImageScaleMode` means the image will be
stretched, and its *presence* will include the entity to the various
slicing systems

Optional components in bundles would make this more straigthfoward

# Additional work

Should I add new bundles with the `ImageScaleMode` component ?
github-merge-queue bot pushed a commit that referenced this pull request Feb 23, 2024
# Objective

Fixes #11944

## Solution

#11600 made an incorrect assumption on what `UiImageSize` does, removing
its usage in slicing fixes the problem
msvbg pushed a commit to msvbg/bevy that referenced this pull request Feb 26, 2024
# Objective

Fixes bevyengine#11944

## Solution

bevyengine#11600 made an incorrect assumption on what `UiImageSize` does, removing
its usage in slicing fixes the problem
msvbg pushed a commit to msvbg/bevy that referenced this pull request Feb 26, 2024
# Objective

Fixes bevyengine#11944

## Solution

bevyengine#11600 made an incorrect assumption on what `UiImageSize` does, removing
its usage in slicing fixes the problem
mockersf pushed a commit that referenced this pull request Feb 27, 2024
# Objective

Fixes #11944

## Solution

#11600 made an incorrect assumption on what `UiImageSize` does, removing
its usage in slicing fixes the problem
github-merge-queue bot pushed a commit that referenced this pull request Mar 5, 2024
# Objective

Follow up to #11600 and #10588 
#11944 made clear that some
people want to use slicing with texture atlases

## Changelog

* Added support for `TextureAtlas` slicing and tiling.
`SpriteSheetBundle` and `AtlasImageBundle` can now use `ImageScaleMode`
* Added new `ui_texture_atlas_slice` example using a texture sheet

<img width="798" alt="Screenshot 2024-02-23 at 11 58 35"
src="https:/bevyengine/bevy/assets/26703856/47a8b764-127c-4a06-893f-181703777501">

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Pablo Reinhardt <[email protected]>
spectria-limina pushed a commit to spectria-limina/bevy that referenced this pull request Mar 9, 2024
# Objective

Follow up to bevyengine#11600 and bevyengine#10588 
bevyengine#11944 made clear that some
people want to use slicing with texture atlases

## Changelog

* Added support for `TextureAtlas` slicing and tiling.
`SpriteSheetBundle` and `AtlasImageBundle` can now use `ImageScaleMode`
* Added new `ui_texture_atlas_slice` example using a texture sheet

<img width="798" alt="Screenshot 2024-02-23 at 11 58 35"
src="https:/bevyengine/bevy/assets/26703856/47a8b764-127c-4a06-893f-181703777501">

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Pablo Reinhardt <[email protected]>
msvbg pushed a commit to msvbg/bevy that referenced this pull request Jun 11, 2024
Follow up to bevyengine#11600 and bevyengine#10588
bevyengine#11944 made clear that some
people want to use slicing with texture atlases

* Added support for `TextureAtlas` slicing and tiling.
`SpriteSheetBundle` and `AtlasImageBundle` can now use `ImageScaleMode`
* Added new `ui_texture_atlas_slice` example using a texture sheet

<img width="798" alt="Screenshot 2024-02-23 at 11 58 35"
src="https:/bevyengine/bevy/assets/26703856/47a8b764-127c-4a06-893f-181703777501">

---------

Co-authored-by: Alice Cecile <[email protected]>
Co-authored-by: Pablo Reinhardt <[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-Feature A new feature, making something new possible 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.

Ordering constraints referencing RenderUiSystem::ExtractAtlasNode aren't doing anything
5 participants