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

overall polishing needed #50

Closed
adsick opened this issue Jul 11, 2021 · 6 comments
Closed

overall polishing needed #50

adsick opened this issue Jul 11, 2021 · 6 comments

Comments

@adsick
Copy link

adsick commented Jul 11, 2021

probably 1st thing I've encountered is long compile time of examples in release:

adsick@pop-os:~/Rust/Crates/bevy_retrograde$ cargo run --features ldtk,epaint --example epaint --release
   Compiling bevy_retrograde v0.1.0 (/home/adsick/Rust/Crates/bevy_retrograde)
    Finished release [optimized] target(s) in 5m 00s
     Running `target/release/examples/epaint`

I'm not kidding, it really takes 5m taking into account that I've already built the bevy_retrograde crate in release mode.
yep my hardware is old (4c intel core i5-3330 & 8G DDR3 RAM & 1Tb HDD), but that not seems like an excuse for it (at least I think so)

2nd text.rs example is not pixel perfect (not sure if it has to be)
looks kinda odd to me
image

3rd sprite movement in hello_world is odd too, it is not smooth&looks glitchy
4rd epaint results are not looking pleasant
image
not awful but not perfect

@zicklag
Copy link
Member

zicklag commented Jul 12, 2021

Thanks for letting me know about your experience! One of the things I really want for Bevy Retro is to be very nice to use so I really appreciate you taking the time to comment on the experience.

probably 1st thing I've encountered is long compile time of examples in release:

The reason for that is that we have enabled link time optimization for release builds in the Cargo.toml:

[profile.release]
lto = true

If you take out that line, it will go much faster.

Link time optimization can greatly reduce the code size of the final build, but as you have seen, it can really push up the release build times. I had put that in there out of habit, as I usually make my release builds with that flag, but for the sake of new people cloning Bevy Retrograde and trying to build it, it really isn't necessary, because we don't build released games from the Bevy Retrograde repo.

I'll go ahead and take that out because it's not really helping.

We also have enabled some optimizations and disabled debug info for debug builds in the Cargo.toml, which should improve the performance a bit over a default debug build:

[profile.dev]
opt-level = 1
debug = 0

This should make the performance perform decently well even in debug builds, at least for the examples, but you can tweak that to your liking.

Also note that these profile settings only effect code when you build from the Bevy Retrograde repository. When you add Bevy Retro as a dependency to your own crate in your Cargo.toml, none of these settings will have any effect and Cargo will use the default build optimization, debug, and linking settings.

yep my hardware is old (4c intel core i5-3330 & 8G DDR3 RAM & 1Tb HDD), but that not seems like an excuse for it (at least I think so)

I've personally done a lot of dev on old hardware before so I definitely sympethize! We don't want to make it harder for people with old hardware if we can avoid it.


2nd text.rs example is not pixel perfect (not sure if it has to be)
looks kinda odd to me

Yes, that's a known issue that we don't exactly have a "solution" for yet.

So, the way that Bevy Retrograde currently renders the pixels is by using the camera size you provided to control the "zoom" level of the camera when rending the pixels, but when zoom level necessary to fit that camera size into the size of the window that you have isn't an exact number such as 2x zoom, 3x, 4x, etc. the pixels from the game won't fit perfectly into the pixels on your screen. This leads to certain pixels in the game ending up looking wider or taller than other pixels next to them.

There are two ways around this that I know of:

  1. Only allow resizing the game in integral increments of 2x, 3x, 4x, etc. This would result in perfect, clear pixels, but would put borders around the game camera at different screen sizes. This is an option that we should provide in Bevy Retrograde, but we haven't implemented yet.
  2. We could use a more advanced pixel filtering that uses a kind of anti-aliasing to keep pixels looking like squares even at non-integral zooms. The disadvantage of this technique is that the pixels will turn out blurrier than they are right now, because the anti-aliasing has to smooth the lines of the pixels out over multiple physical pixels on your screen. This should also be an option we provide eventually in Bevy Retrograde.

With the current strategy, pixels will always be nice and clear, with crisp edges, and you will be able to resize the window to whatever you want, but as you have found, the pixels may not be perfect squares. We felt likethis was a good middleground to start with because it probably woudn't annoy the user, it was easy to start with, and would be hard to notice in most actual game scenes. Unfortunately it is rather easy to notice for text.

I'll open an issue for creating the new pixel filtering modes, but it may be a little while before we get to implementing them. We will most-likely want to wait until we migrate to a new Bevy-based renderer ( #41 ) to avoid having to re-do work.


3rd sprite movement in hello_world is odd too, it is not smooth&looks glitchy

Bevy Retrograde, by default, restricts sprite movement to whole pixels, forcing all pixels to be lined up perfecty with all the others, but you can, on a per-sprite basis, turn off that feature to enable smooth movement that can move in your screen resolution, instead of in the game pixelated resolution.

For instance, in the hello-world example, the yellow sprite is specifically set to non-pixel-perfect mode so that it's movement shoud be perfectly smooth, while the red radish, on the other hand, uses the default setting of pixel-perfect and will make sure that it never displays un-aligned with the rest of the pixel-perfect sprites.

.spawn_bundle(SpriteBundle {
image: yellow_radish_image,
transform: Transform::from_xyz(-20., 0., 0.),
sprite: Sprite {
// Make him upside down 🙃
flip_y: true,
// Slow moving objects can look very "jerky" when they are forced into perfectly
// aligned pixels. Disabling pixel perfect on moving sprites can make things look
// much nicer at the cost of a little bit of retro authenticity, but, hey, that's
// what Shovel Knight did. 🙂
pixel_perfect: false,
..Default::default()
},
..Default::default()
})


4rd epaint results are not looking pleasant

Yes, I'll admit that the epaint integration is rather half-baked at the moment. I actually added the feature less than a week ago because I needed it to write some debug visualizations for a character pathfinder and I got it working just enough to be usable. It's not super high-priority to make it look nicer yet, but we can open an issue for it so that it doesn't get forgotten.

@zicklag
Copy link
Member

zicklag commented Jul 12, 2021

I created issues for the pixel filtering which should address your text rendering concerns: #51. In summary, we will eventually have all of these modes, but we currently only have the "Crisp Scalable" mode:

Mode Implemented Crisp Edges Perfect Squares Any Zoom Level Doesn't Require Camera Borders
Crisp Scalable ✔️ ✔️ ✔️ ✔️
Smooth Scalable ✔️ ✔️ ✔️
Crisp Fixed Scale ✔️ ✔️

I also created an issue for improving the epaint integration. Once we move to Bevy's renderer, we might get that for free because there is already the bevy_egui crate which renders the epaint shapes: #52 .

zicklag added a commit that referenced this issue Jul 12, 2021
The amount of time it took to do a release buid was detrimental for a
new user ( #50 ) and we don't really need it for this repository because
no real games are built from this repo.
bors bot pushed a commit that referenced this issue Jul 12, 2021
The amount of time it took to do a release buid was detrimental for a
new user ( #50 ) and we don't really need it for this repository because
no real games are built from this repo.
@adsick
Copy link
Author

adsick commented Jul 12, 2021

impressive level of feedback, @zicklag thx a lot.

I'll go ahead and take that out because it's not really helping.

looks like a good decision. when working with Bevy I've a strong habit to always use release mode, because it matters for perf. a lot => others may have this habit as well.

The disadvantage of this technique is that the pixels will turn out blurrier than they are right now, because the anti-aliasing has to smooth the lines of the pixels out over multiple physical pixels on your screen.

I think it is kinda ok taking into account that today's screens are 1920x1080 or more, therefore that blurriness would be either not so noticeable.

the game 'Enter the Gungeon' has settings to enable pixel perfectness and also support adding black frames.
anyway, I see this will eventually get better over time.

it's movement shoud be perfectly smooth

I know it should be, but unfortunately it isn't. I've encountered the same before with Bevy when tried to scroll some text2d on the screen - it was not perfectly smooth. I've tried some framerate independence stuff there (it was almost rock 60 though), but text sometimes "jumped" on screen, had some very noticeable non-smoothness to it.
linear filtering was used, nearest neighbor looks bad...

@zicklag
Copy link
Member

zicklag commented Jul 12, 2021

I know it should be, but unfortunately it isn't.

Ah, actually, I might know what you mean. I noticed from your screenshot that you're runing on what looks like Linux with Gnome ( Pop!_OS actually, which I use too! 🙂 ), and there is a known issue with Linux and Gnome that can effect pretty much all games or graphics applications ( even glxgears will skip occasionally ): bevyengine/bevy#962 (comment).

A way to test it for sure is to run in borderless fullscreen mode, which shouldn't exhibit the same issue. You can test this by modifying the hello_world example by changing the following code:

        .insert_resource(WindowDescriptor {
            title: "Bevy Retrograde Hello World".into(),
            // Add this line here
            mode: bevy::window::WindowMode::BorderlessFullscreen,
            ..Default::default()
        })

It looks like the issue is essentially that gnome did some optimizations to reduce how often the screen was refreshed when it didn't need to be, but they overdid it a little and now the screen isn't refreshed sometimes when it needs to be for non-fullscreen applications.

For now I think the only workaround is to run in fullscreen. I usually add this system to my Bevy games to make the F11 button switch to and from fullscreen mode:

fn switch_fullscreen(mut windows: ResMut<Windows>, keyboard_input: Res<Input<KeyCode>>) {
    if keyboard_input.just_pressed(KeyCode::F11) {
        if let Some(window) = windows.get_primary_mut() {
            window.set_mode(match window.mode() {
                WindowMode::BorderlessFullscreen => WindowMode::Windowed,
                _ => WindowMode::BorderlessFullscreen,
            });
        }
    }
}

We're using nearest neighbor filtering so you may still see some pixel "crawling" effect, that can probably be improved somehow and we'll likely revisit that once we get to working on #51.

@adsick
Copy link
Author

adsick commented Jul 12, 2021

Pop!_OS actually

true.
now it feels a bit better, but you are right on this one:

you may still see some pixel "crawling" effect

I do, it is not too bad though.
thanks for your attention <3

@zicklag
Copy link
Member

zicklag commented Jul 15, 2021

@adsick I'm going to close this for now, if you don't mind, since I've added issues for the remaining work to be done, but feel free to re-open or create new issues if you have more thoughts or questions!

@zicklag zicklag closed this as completed Jul 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants