-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[Merged by Bors] - Add Sprite Flipping #1407
Conversation
702549b
to
2400088
Compare
In terms of UX, I think I have a preference for |
I don't think I agree. Imo it should just be a bool field for each axis. In most cases I have a feeling we'll either have sprite.flipped = CONDITION_HERE; or having the field explicitly set during construction. If you truly don't care about the current state / just want to flip what's there, you can always do More methods == more things to document / maintain / learn |
Can it be?: pub struct Sprite {
pub size: Vec2,
pub flip_x: bool,
pub flip_y: bool,
#[render_resources(ignore)]
pub resize_mode: SpriteResizeMode,
} Or is the implementation too difficult/impossible? |
@tigregalis it's definitely possible, but due to limitations of the current |
Haha i'll file this under "another case of RenderResources constraining our designs". I do like having flip_x and flip_y as siblings of size. Sprites are "core" enough that I think its worth the extra manual effort to build the interface we want. But lets add a |
@cart Sounds good. I'll update this PR with the changes to move the fields, then. 👍 |
2400088
to
cab4891
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed an updated moving the flip parameters adjacent to the other Sprite component parameters:
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the logo to the left
flip_x: true,
..Default::default()
},
..Default::default()
});
// Flip the sprite if necessary | ||
uint x_flip_bit = 1; | ||
uint y_flip_bit = 2; | ||
if ((flip & x_flip_bit) == x_flip_bit) { | ||
uv = vec2(1.0 - uv.x , uv.y); | ||
} | ||
if ((flip & y_flip_bit) == y_flip_bit) { | ||
uv = vec2(uv.x, 1.0 - uv.y); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So here is where the rendering glitches are caused. If the UV's of the quad vertices truly are within the range of 0 to 1, then this subtraction we do to flip the UV ( 1.0 - uv.x
) should never result in a value below zero, and yet, when resizing the screen, we can see that the texture under/over-runs and samples outside of the texture image, resulting in clipping. I just don't know why.
It is worth noting that if I replace 1.0
with 0.9999
, that it looks fine, but I'm not sure if it would look fine always, or if there would be other problems down the line. It just doesn't seem right when I feel like the other one should work.
Edit: I just realized that I think this is the same issue I had with my tilemap renderer, which was built on the same concept for how it laid out the tile UVs. It would run over the edge of the UVs when resizing the screen.
cab4891
to
5a8fd72
Compare
The new Example still needs to be added to the README.md in the example folder. |
5a8fd72
to
5226cd6
Compare
Updated! |
501ac73
to
8b4fb3d
Compare
I pushed an update that fixes the UV bleeding issues that remained, but I have no idea if my solution makes any real sense. My understanding of floating point arithmetic is limited at best, but my only guess as to the issue was that somehow there is a rounding issue where It did fix any issues that are visible while resizing the screen in the |
This looks good to go once we move to RenderResources derives. |
There you go! |
It looks like you changed |
Ahhhh you changed the "bit". Thats interesting. Lemme think on that for a sec |
Oh, now that you say that I get what you meant in your above comment. I thought you were saying that's what I should do, but you were just talking about Because of padding bytes and alignment we don't take up any more bytes of data I don't think. Also, do we need the |
(not accounting for alignment/padding) the RenderResource/Byteable impl would result in a "slightly too large" buffer as Byteable has no way to ignore
Yeah for future reference |
Ah, yes. Give me one second. |
There we go. |
bors r+ |
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal: ```rust .spawn(SpriteBundle { material: materials.add(texture_handle.into()), sprite: Sprite { // Flip the sprite along the x axis flip: SpriteFlip { x: true, y: false }, ..Default::default() }, ..Default::default() }); ``` Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below. ![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png) I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong. The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed. I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
Pull request successfully merged into main. Build succeeded: |
Since 8921717, some birds in example `contributors` where not colored. Fix is to use `flip_x` of `Sprite` instead of setting `transform.scale.x` to `-1` as described in #1407. It may be an unintended side effect, as now we can't easily display a colored sprite while changing it's scale from `1` to `-1`, we would have to change it's scale from `1` to `0`, then flip it, then change scale from `0` to `1`.
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the
#[render_resources(from_self)]
annotation from the Spritesheet because theSpriteFlip
render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!