Pixel art smooth scrolling how?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
LeviathaninWaves
Prole
Posts: 9
Joined: Sun Jul 17, 2022 12:46 am

Pixel art smooth scrolling how?

Post 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?
gcmartijn
Party member
Posts: 136
Joined: Sat Dec 28, 2019 6:35 pm

Re: Pixel art smooth scrolling how?

Post 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
LeviathaninWaves
Prole
Posts: 9
Joined: Sun Jul 17, 2022 12:46 am

Re: Pixel art smooth scrolling how?

Post 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!
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Pixel art smooth scrolling how?

Post 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.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
LeviathaninWaves
Prole
Posts: 9
Joined: Sun Jul 17, 2022 12:46 am

Re: Pixel art smooth scrolling how?

Post 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.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Pixel art smooth scrolling how?

Post 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).
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
LeviathaninWaves
Prole
Posts: 9
Joined: Sun Jul 17, 2022 12:46 am

Re: Pixel art smooth scrolling how?

Post 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.
User avatar
marclurr
Party member
Posts: 105
Joined: Fri Apr 22, 2022 9:25 am

Re: Pixel art smooth scrolling how?

Post 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/
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Pixel art smooth scrolling how?

Post by zorg »

Indeed, box2d, as far as i remember, does expect fixed timestep updates.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Pixel art smooth scrolling how?

Post 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.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
Post Reply

Who is online

Users browsing this forum: Amazon [Bot], Google [Bot] and 70 guests