1
\$\begingroup\$

I've made a custom engine that uses 2:1 isometric sprite graphics with a 3D world simulation. Each render tick, I convert each entity's world position into a screen position, and render their sprite appropriately:

still entity

While moving diagonally across the screen, the naive rendering approach (using the raw world -> screen pixel coordinates) caused some jitter. I resolved this by making sure that during diagonal movement, the sprite always gets rendered on the same pixel in the 2:1 pattern. For example, below is a diagonal line with a repeated 2:1 pattern. The first pixel in each step of the pattern is colored blue. If the sprite happened to start its diagonal movement on the first pixel in the pattern, I would continue to round its origin each frame to the closest blue pixel.

highlighted first pixel

This gives me a sprite that looks like its traveling in a straight line, with no up/down jitter. It introduces a new issue though: if the entity's runspeed doesn't happen to perfectly line up with the pattern, it will sometimes move by 1 step, and sometimes move by 2:

irregular movement pattern

This gives a slight jitter to the graphic, as it moves irregularly across the screen. This jitter isn't present if I choose a runspeed that moves the graphic a consistent number of steps each frame.

My question is: is there any fix for this? I've thought of smoothing out the irregular steps by moving the sprite less frequently, but it doesn't seem possible to get the runspeed, render rate, and update rate to all line up perfectly for any arbitrary runspeed. Maybe it is, though? Or maybe there's another solution?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I'm working on a isometric pixel art game targeting 60fps in monogame and had to overcome this problem myself.

Is there a fix? Yeah kinda lol, but it's never going to be as convenient as regular top down orthogonal/diagonal movement.

From what I've worked out you have four options:

  1. Do nothing and force sprites moving isometrically to use a fixed set of speeds that give smooth movement (like you mentioned in your post.)

  2. Run the game at a higher resolution/zoomed in. The lamest option and not always viable (you can design for 1440p but many people still only have 1080p screens,) but it does increases the set of possible speeds that will appear perfectly smooth.

  3. Use render targeting and render frames one resolution level above what you want using pixel perfect scaling, then scale frames back down using a certain kinds of sampler, such as anisotropic or linear (you can mess around with samplers to get the clarity you want, you just can't use a sampler that tries to scale things pixel perfect.)

You still have to use a fixed set of speeds but there are now more usable speeds and can now achieve smooth movement at a lower speed threshold. This is the solution I use but I specifically use it because my game is low res pixel art and this method preserves the pixel art.

  1. Instead of step 3 where you render a frame with a higher resolution scale and then scale the whole frame down with a sampler, you just scale sprites up with a sampler when you render them to the frame. You'll need to choose the right sampler or create one yourself with the parameters you want, but certain samplers can you let you achieve smooth movement at waaay more different speed values.

This solution does not work for low res pixel art and honestly I don't know how well it will work for higher res non-pixel art but this might be the best option for you. When I tested this method on my game the movement was buttery smooth at almost any speed but due to being low res pixel art the sprites either had artifacts or were blurred until they were no longer pixel art lol. Maybe if you're not using pixel art this is the perfect solution but it does require sprites to be drawn smaller than your final resolution and then blurred at least a little bit when they are scaled up.

I hope there's a better solution out there but I've searched a bunch and haven't found anything. I also looked at a bunch of 2D isometric games to try and find out more but noticed that they all tend to use one or a couple fixed speeds.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.