Skip to content

Add ZIndex, YSort, and SortBias 2d components #19463

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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

tychedelia
Copy link
Member

Objective

Using Z transform for sprites and 2d meshes is gross! Users expect familiar sorting strategies.

Solution

Adds 3 new sorting components for 2d:

  • ZIndex: sorts entities into layers and always takes priority.
  • YSort: sorts entities in each ZIndex layer by their Y transform.
  • SortBias: an arbitrary bias that is either added to Y transform or used as a secondary sort value.

TODO:

  • What should we do with the name conflict with the existing ui ZIndex.
  • How should 2d mesh opaque behave? Right now, using any of these components opts you into transparent sorting on the CPU, but ideally we'd be able to do GPU based fragment sorting as well. This is an advantage that using the transform Z has that we should take into consideration.

Testing

Tested a bunch of examples, might be more broken.

@tychedelia tychedelia added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jun 2, 2025
@tychedelia tychedelia added M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide M-Needs-Release-Note Work that should be called out in the blog due to impact X-Contentious There are nontrivial implications that should be thought through labels Jun 2, 2025
Copy link
Contributor

github-actions bot commented Jun 2, 2025

It looks like your PR is a breaking change, but you didn't provide a migration guide.

Please review the instructions for writing migration guides, then expand or revise the content in the migration guides directory to reflect your changes.

Copy link
Contributor

github-actions bot commented Jun 2, 2025

It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note.

Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes.

Copy link
Contributor

github-actions bot commented Jun 2, 2025

Your PR caused a change in the graphical output of an example or rendering test. This might be intentional, but it could also mean that something broke!
You can review it at https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D?filter=PR-19463

If it's expected, please add the M-Deliberate-Rendering-Change label.

If this change seems unrelated to your PR, you can consider updating your PR to target the latest main branch, either by rebasing or merging main into it.

@alice-i-cecile alice-i-cecile added this to the 0.17 milestone Jun 2, 2025
Comment on lines 146 to 153
/// A marker component that enables Y-sorting (depth sorting) for sprites and meshes.
///
/// When attached to an entity, this component indicates that the entity should be rendered
/// in draw order based on its Y position. Entities with lower Y values (higher on screen)
/// are drawn first, creating a depth illusion where objects lower on the screen appear
/// in front of objects higher on the screen.
#[derive(Component, Default, Debug, Clone)]
pub struct YSort;
Copy link
Contributor

Choose a reason for hiding this comment

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

Setting YSort per-sprite seems like it might be confusing to me. Will we be able to resolve situations where you have multiple overlapping sprites, some with YSort, some without, in a consistant way?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right now, for entities on the same z index layer, an entity with y sort enabled will always sort before one without it. Not sure if this is intuitive but it is consistent.

Comment on lines +241 to +243
z_index: 0,
y_sort: false,
sort_bias: None,
Copy link
Contributor

Choose a reason for hiding this comment

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

Text2d needs to support z index too.

Copy link
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.

As long as they both just wrap an i32 and higher values are on top, I think it would be okay to use the same ZIndex component for both UI and 2d. bevy_ui already depends on bevy_sprite for the texture slicing API. We'd just need to be careful to make sure all the documentation points out clearly how it behaves in each context.

Copy link
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.

What about propagation? It feels like this needs some sort of local ordering support so children are drawn above their ancestors and inherit their parent's z-ordering.

@tychedelia
Copy link
Member Author

What about propagation? It feels like this needs some sort of local ordering support so children are drawn above their ancestors and inherit their parent's z-ordering.

We just merged #17575 which could help. I'm the wrong person to ask about 2d design patterns, but it's not clear to me that children should always be drawn above their ancestors, although I realize this is a pattern that using z position plus transform propagation makes trivial and we are breaking. Would appreciate input here from others.

@NthTensor
Copy link
Contributor

it's not clear to me that children should always be drawn above their ancestors

I don't think we can assume this. We need to make it possible for children to be drawn in front of behind their ancestors, depending on artist intent.

@alice-i-cecile
Copy link
Member

I don't think we can assume it, but I do think it's a good default :)

@tychedelia
Copy link
Member Author

I don't think we can assume it, but I do think it's a good default :)

I guess the question is, what does this look like? Do we have a GlobalZIndex component? Or do we just have some kind of mechanism that silently updates ZIndex += 1 behind the scenes? What if you don't want this behavior?

@hymm
Copy link
Contributor

hymm commented Jun 3, 2025

It feels to me like y-sorting is more a property of an individual layer rather than individual sprites. Wouldn't you want all sprites in the same layer to be y sorted?

Does the y sort take into account the anchor point at all?

@tychedelia
Copy link
Member Author

Wouldn't you want all sprites in the same layer to be y sorted?

Probably? But again I think this is more a function of questions around patterns for inheritance/propagation. At the end of the day, they will be sorted one by one and so I think it still makes sense for the components to apply to individual entities if you want. I wouldn't want to take away this fine grained control just add other tools for making common use cases easier.

@tomara-x
Copy link
Contributor

tomara-x commented Jun 3, 2025

mechanism that silently updates ZIndex += 1 behind the scenes? What if you don't want this behavior?

bevy_lunex does this. by default every child is one z step above its parent. and there's an override component (with set and add variants). i like that those can also be propagated now :)

i wonder if different variants like that can be useful here

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 C-Feature A new feature, making something new possible M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide M-Needs-Release-Note Work that should be called out in the blog due to impact S-Needs-Review Needs reviewer attention (from anyone!) to move forward X-Contentious There are nontrivial implications that should be thought through
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

6 participants