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

Add optional transparency passthrough for sprite backend with bevy_picking #16388

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

Conversation

vandie
Copy link

@vandie vandie commented Nov 14, 2024

Objective

Solution

Testing

  • Ran Sprite Picking example to check it was working both with transparency enabled and disabled
  • ModPicking version is currently in use in my own isometric game where this has been an extremely noticeable issue

Showcase

Sprite Picking Text

Migration Guide

Sprite picking now ignores transparent regions (with an alpha value less than or equal to 0.1). To configure this, modify the SpriteBackendSettings resource.

Copy link
Contributor

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

Copy link
Contributor

@mgi388 mgi388 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 excited for this change. I did a quick visual code review but haven’t tested it yet.

/// Off by default for backwards compatibility. This setting is provided to give you fine-grained
/// control over if transparency on sprites is ignored.
pub passthrough_transparency: bool,
/// How Opaque does part of a sprite need to be in order count as none-transparent (defaults to 10)
Copy link
Contributor

@mgi388 mgi388 Nov 14, 2024

Choose a reason for hiding this comment

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

Can you elaborate in the docs what the units are? 10 what? What is a valid range I could use, as a user?

Copy link
Member

Choose a reason for hiding this comment

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

Can these two options be combined into a single enum? It doesn't make sense to have an alpha cutoff setting when alpha passthrough is disabled. e.g.

SpritePickingAlphaTest {
    /// Don't test alpha, only consider the rect of sprites.
    Ignore,
    /// Test the pixel alpha when running hit tests. Alpha values below this will not be considered for picking.
    Threshold(u8)
}

Copy link
Author

Choose a reason for hiding this comment

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

Yeah an enum is probably a better idea for those settings. Will rework to include.

crates/bevy_sprite/src/picking_backend.rs Outdated Show resolved Hide resolved
crates/bevy_sprite/src/picking_backend.rs Outdated Show resolved Hide resolved
@mgi388
Copy link
Contributor

mgi388 commented Nov 14, 2024

@vandie also see #14929 I think your PR fixes it.

@vandie
Copy link
Author

vandie commented Nov 14, 2024

@vandie also see #14929 I think your PR fixes it.

I think it does yeah.

@mgi388
Copy link
Contributor

mgi388 commented Nov 14, 2024

@vandie also see #14929 I think your PR fixes it.

I think it does yeah.

You can put “Fixes #{id}” in your PR description so merging this PR closes the issue as fixed. 😌

@kristoff3r kristoff3r added S-Needs-Review Needs reviewer attention (from anyone!) to move forward A-Picking Pointing at and selecting objects of all sorts D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes labels Nov 14, 2024
@alice-i-cecile alice-i-cecile added this to the 0.16 milestone Nov 14, 2024
@alice-i-cecile alice-i-cecile added the M-Needs-Release-Note Work that should be called out in the blog due to impact label Nov 14, 2024
@vandie
Copy link
Author

vandie commented Nov 17, 2024

Seems everyone agrees that this should be enabled by default so I've updated that and introduced a new SpriteBackendAlphaPassthrough enum so this can be controlled by a single setting rather than multiple.

@alice-i-cecile alice-i-cecile added the M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide label Nov 17, 2024
Copy link
Contributor

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

Could you add some context on what users should update when this change get released in a new version of Bevy?
It will be used to help writing the migration guide for the version. Putting it after a ## Migration Guide will help it get automatically picked up by our tooling.

@alice-i-cecile
Copy link
Member

Can you add a small migration guide explaining that this is now on by default? Definitely the better default, but could break existing users.

@vandie
Copy link
Author

vandie commented Nov 17, 2024

Can you add a small migration guide explaining that this is now on by default? Definitely the better default, but could break existing users.

Added. Hope that's ok and clear?

@alice-i-cecile
Copy link
Member

The migration guide was clear and effective, but the tone / target audience was a bit weird. The goal is to communicate "why is my stuff broken and how do I fix it", but your initial draft was closer to a change log :) I've quickly edited the PR description incorporating the information you've added. These get automatically scraped / compiled, so it's good to clean them up here.

@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 Nov 19, 2024
Copy link
Contributor

@andriyDev andriyDev left a comment

Choose a reason for hiding this comment

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

Sorry for the previous two comments not being part of this review, I've been noticing while trying to adapt this picking backend into my project.

crates/bevy_sprite/src/picking_backend.rs Outdated Show resolved Hide resolved
crates/bevy_sprite/src/picking_backend.rs Outdated Show resolved Hide resolved
crates/bevy_sprite/src/picking_backend.rs Show resolved Hide resolved
@MonforteAdrian
Copy link

MonforteAdrian commented Nov 22, 2024

Testing the changes got this error after a crash:

2024-11-22T07:39:32.137594Z  INFO bevy_winit::system: Creating new window "App" (0v1#4294967296)
2024-11-22T07:39:32.137772Z  INFO winit::platform_impl::platform::x11::window: Guessed window scale factor: 1
2024-11-22T07:39:32.326951Z  WARN bevy_render::view::window: Couldn't get swap chain texture after configuring. Cause: 'The underlying surface has changed, and therefore the swap chain must be updated'
thread 'Compute Task Pool (4)' panicked at /home/adrian/bevy_testing/bevy/crates/bevy_image/src/image.rs:974:36:
range end index 8 out of range for slice of length 4
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_sprite::picking_backend::sprite_picking`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!

I'm using 0.15 release branch with the changes applied on top. Running the sprite_picking example
The sprite on the right works fine, but the squares and bevy logos works quite bad and make the app crash.
The test run on linux with x11 as you can see in the errors

@andriyDev
Copy link
Contributor

andriyDev commented Nov 22, 2024

Testing the changes got this error after a crash:

I verified this on Windows and on main as well. Looks like there's something wrong with Image::get_color_at. Dang! I'll file another issue.

@vandie
Copy link
Author

vandie commented Nov 22, 2024

Testing the changes got this error after a crash:

I verified this on Windows and on main as well. Looks like there's something wrong with Image::get_color_at. Dang! I'll file another issue.

edit: Oh wait, irritating, this looks like a different panic...

Copy link
Contributor

@andriyDev andriyDev left a comment

Choose a reason for hiding this comment

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

@vandie #16475 has been merged so that should fix one set of panics.

crates/bevy_sprite/src/picking_backend.rs Outdated Show resolved Hide resolved
crates/bevy_sprite/src/picking_backend.rs Outdated Show resolved Hide resolved
@andriyDev
Copy link
Contributor

andriyDev commented Nov 23, 2024

I tested the sprite_picking example, looks like the black squares are offset by half its width and height. Color sprites are actually a 1x1 image, so it looks like we're offset by half a pixel somewhere.

Edit: nevermind I completely misunderstood what was happening, looks like the color sprites are off by half width/height which in this case is 64x64

Edit 2: DOUBLE NEVERMIND I WAS CONFUSED, we pass a custom size to the color sprite, which makes it 64x64, but the image size is 1x1.

Copy link
Contributor

@andriyDev andriyDev left a comment

Choose a reason for hiding this comment

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

We're not considering the custom_size of sprites, or the rect of sprites inside the pixel checking code.

I also think we should consider moving all the pixel picking logic into the Sprite struct as a method. It seems reasonable to want to reuse "given this relative position, where am I in the texture for this sprite?" (but like with the float part remaining).

Edit: It looks like we're also not considering Sprite::flip_x, Sprite::flip_y, and Sprite::image_mode. I'm tinkering to see if I can get an implementation that works.

})
.or(Some(URect::new(0, 0, texture.width(), texture.height())))?;
// get mouse position on texture
let texture_position = (texture_rect.center().as_vec2()
Copy link
Contributor

Choose a reason for hiding this comment

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

We're getting the center and then casting to a float. Odd image sizes will mean the center won't be at 0.5, 0.5 like we'd expect. I'm pretty sure we need to cast the rect to f32 and then get the center, so texture_rect.as_rect().center().

Copy link
Author

Choose a reason for hiding this comment

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

Hmm, let me check my commits because I think I had some correction for this. Wonder if I accidentally removed it with all the reworking we've done.

@andriyDev
Copy link
Contributor

andriyDev commented Nov 23, 2024

@vandie When you have time, could you take a look at vandie#2 ? I tested it and it looks like it solves a lot of issues! (just wanna make sure it doesn't get lost)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Picking Pointing at and selecting objects of all sorts D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes 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-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.

Add support for alpha-testing in sprite picking backend
8 participants