Page 1 of 2

Pixel art smooth scrolling how?

Posted: Mon Jul 25, 2022 2:13 pm
by LeviathaninWaves
I'm working on a pixel art low resolution game engine.
I can't really figure this one out...

So when it came time to implement camera scrolling, I got graphical artifacts in my tilemap. This was fixed by rounding the X and Y of the camera position.
Adding a physics body and sprite to the mix is where problems come in. I set the sprite and camera position to the player physics body X and Y, rounded to an integer value. This creates visible jittering in the sprite and collider but keeps pixel perfect tilemap scrolling. If I instead use the floating point X and Y of the player physics body for sprite and camera X and Y, I get no jittering, but the tilemap scrolling instead becomes jittery.

How do I solve this one? Should I use interpolation on the X and Y coords between frames? Should I use my own physics engine? I believe old school 8 and 16 bit games used subpixel precision for physics and got perfect scrolling and no jitter by rounding the position, but how can this be achieved here?

Re: Pixel art smooth scrolling how?

Posted: Mon Jul 25, 2022 7:32 pm
by gcmartijn
I don't use a tilemap for my pixel art engine but maybe this can help you.

viewtopic.php?f=3&t=92669

Re: Pixel art smooth scrolling how?

Posted: Mon Jul 25, 2022 8:49 pm
by LeviathaninWaves
gcmartijn wrote: Mon Jul 25, 2022 7:32 pm I don't use a tilemap for my pixel art engine but maybe this can help you.

viewtopic.php?f=3&t=92669
I appreciate the help. I intend to use tilemaps only for rapid creation of level collision layouts, but the jittering is an issue I'd like to be able to solve early on.
That being said, maybe using float coords wouldn't be problematic in a non tile based graphical world. Either way, the subpixel part of the thread that you linked to might be the solution I'm looking for.

I've encountered vague mentions of adding a pixel edge to tiles, or overshooting camera and canvas dimensions by 1 and doing fractional stuff with that...but I'm going to start with testing subpixel support. Thanks again!

Re: Pixel art smooth scrolling how?

Posted: Mon Jul 25, 2022 8:57 pm
by ReFreezed
Make sure to round both the camera's position and the position of every rendered sprite. Also, it shouldn't really matter what physics engine you use - physics and rendering are separate concerns.

Re: Pixel art smooth scrolling how?

Posted: Wed Jul 27, 2022 2:26 am
by LeviathaninWaves
What an adventure. So after sacrificing the push library and giving the other ideas a try, the jitter has been significantly reduced. If you are reading this and you are having trouble with tilemap rendering and graphical artifacts at tile edges, make sure to render your sprite batch to canvas before doing any transformations on it. Also, if your camera is centered on an entity and there is significant jitter, give subpixel rendering a try with linear interpolation without whole number rounding on position.

Rounding camera and player position to integer coordinates didn't work well for me. I have yet to try it again after removing push, but there is alot to be said about trying to do integer positioning when floating point math is involved over time, especially when refresh rates and varying hardware is involved. You get rounding errors and that can compromise the fluidity of motion.

Re: Pixel art smooth scrolling how?

Posted: Wed Jul 27, 2022 3:23 am
by ReFreezed
I'm curious what exactly you mean by jitter. Is it caused by slow movement (where the camera or object moves one "big" pixel at a time every few frames), or is the jitter between objects close to each other moving at slightly different speeds or where one has a subpixel offset position relative to the other, or something else? Could you post an example program?

The only times I've had problems with jitter are when things move very slowly, or when there are parallax layers (as seen in my gif in the other linked thread), both solved by subpixel rendering (still with rounding the coordinates, but to the subpixels instead of the full "big" pixels).

Re: Pixel art smooth scrolling how?

Posted: Wed Jul 27, 2022 1:02 pm
by LeviathaninWaves
ReFreezed wrote: Wed Jul 27, 2022 3:23 am I'm curious what exactly you mean by jitter. Is it caused by slow movement (where the camera or object moves one "big" pixel at a time every few frames), or is the jitter between objects close to each other moving at slightly different speeds or where one has a subpixel offset position relative to the other, or something else? Could you post an example program?

The only times I've had problems with jitter are when things move very slowly, or when there are parallax layers (as seen in my gif in the other linked thread), both solved by subpixel rendering (still with rounding the coordinates, but to the subpixels instead of the full "big" pixels).
Upon further testing, the issue persisted especially at higher velocities. By jitter, I mean the player object would shake, even worse at higher velocities. The good news? I completely fixed it by passing love timer.getAverageDelta() to the physics world:update(). Movement is 100% smooth now.

Re: Pixel art smooth scrolling how?

Posted: Wed Jul 27, 2022 1:36 pm
by marclurr
Given you're using the built in physics, which I suspect uses a fixed timestep update internally (someone correct me if I'm wrong), I think your problem was due to fractional timestep building up in the accumulator after each frame. I had this problem myself which I solved by consuming the full delta in each frame, however this comes with its own problems especially regarding simulation consistency. That said, I'm not sure you can do this with the built in physics engine anyway. The reason using the average delta has improved it is probably because it is much closer to the desired timestep (e.g., 1/60) than the frame-to-frame delta.

This page has a much better explanation than I can give https://gafferongames.com/post/fix_your_timestep/

Re: Pixel art smooth scrolling how?

Posted: Wed Jul 27, 2022 2:38 pm
by zorg
Indeed, box2d, as far as i remember, does expect fixed timestep updates.

Re: Pixel art smooth scrolling how?

Posted: Wed Jul 27, 2022 3:37 pm
by ReFreezed
Yeah, using a fixed time step is generally a very good idea (in any game - not just pixel art games or games using Box2D). But even with a fixed time step you may encounter further, more confusing problems with timing, where the underlying causes involve the OS, hardware, and who-knows-what. If you notice the delta time sometimes being a lot longer (like, twice as long) even though the game should be running smoothly, you can fix that issue by assuming the delta time is perfect, i.e. manually set dt to 1/currentMonitorRefreshRate (if vsync is on), unless the value is way off for some time. (Using getAverageDelta() like you started doing kinda solves the issue too to some extent I guess, but may have other unwanted side effects, e.g. if the game is lagging at some point.) You can see this video where a Croteam developer talks about this specific issue.