Jittering with Lerping camera

Hi,

I’m using Vector2.Lerp to achieve a smooth camera, but it jitters with the players acceleration. I assume this is because the player moves one pixel, then the camera will catch up to that pixel a frame or so later. How do I avoid this?

Code:
Vector2 entityPosition = new Vector2((int)(entity.position.X - Assets.gameWidth / 2 + entity.width / 2), (int)(entity.position.Y - Assets.gameHeight / 2 + entity.height / 2));
position = Vector2.Lerp(unRoundedPosition, entityPosition, 0.125f);
unRoundedPosition = position;
position = new Vector2((int)position.X, (int)position.Y);

Footage:
Animation

Are you using a point for your players position. Use a vector instead

There is a spritebatch overload that takes a vector for position

Thanks for the reply, I am already using a vector for the player position, and the same for the camera position.

You’re using a vector 2 to store the data, but you’re casting to an int. When you do this every frame you lose data for subsequent frames. Try only casting position in your draw where you actually use the camera to render your frame, in a new Vector2 object?

I had the same problem.

The only three ways I know on how to fix this:

  1. Scale the textures to a bigger size (32x32 tiles to 128x128 or even bigger)
  2. not using a smooth camera when using the spritebatch when you dont scale the sprites
  3. not using the spritebatch but using 3d quads with textures on them instead.

The 3rd solution is what I am doing currently with all my projects.

although i cast to an int, i use the unrounded vector ‘unRoundedPosition’ in the calculation to avoid losing data, so this shouldn’t be an issue.

hmm, thanks for the response. Seems rather frustrating that nothing more can be done, it seems like a simple problem. I won’t mark this as the solution quite yet, in case someone has a ‘true’ fix, but thanks anyway

I found some code of a game I was working on, I hope it helps

Take a look at:

Objects/Camera.cs
Managers/SceneManager.cs Line. 272

It was just a bit harder to follow without the complete code but I follow now.

What’s not shown here is how you’re scaling your scene. If you’re rendering the scene to a render target using the camera you configured, this issue makes sense because the render target can only render to pixel scale.

Maybe you could try rendering to a render target that is one pixel on all sides larger than your target resolution. Then calculating the sub-pixel camera offset and shifting your final render position (for the render target) by that offset.

It’s a bit of tom-foolery, but hopefully that makes sense. I suspect the problem is that when you’re calculating your camera position, you don’t actually have that sub-pixel data available to you. So you’ll need to do some work to preserve it and adjust your final render position accordingly.

EDIT: You might have to render this render target with the one pixel border to another render target that’s the correct size so you can clip the scene properly. Or mask it off in some other way.

Hey, Managed to solve it!

code:
Vector2 targetPosition = new Vector2(entity.position.X + entity.width / 2 - Globals.Graphics.gameWidth / 2, entity.position.Y + entity.height / 2 - Globals.Graphics.gameHeight / 2);

calcPosition = Vector2.Lerp(calcPosition, targetPosition, 0.1f);

calcPosition = new Vector2((Math.Abs(entity.dPosition.X) < 0.5f) ? calcPosition.X : (float)Math.Round(calcPosition.X), (Math.Abs(entity.dPosition.Y) < 0.5f) ? calcPosition.Y : (float)Math.Round(calcPosition.Y));

position = new Vector2((float)Math.Round(calcPosition.X), (float)Math.Round(calcPosition.Y));

Result:
Animation3

4 Likes

You may find this article helpful. Something I wrote on lerping a while back. I use this technique a lot in Jetboard Joust, and for many things other than camera tracking.

Hi BluishRed,

what is entity.dPosition? in display position?

Thanks!

entity.dPosition is the vector that represents the change in x and y coordinates for that frame for that entity.

1 Like

Great :slight_smile: