Advertisement

Fixed timestep with interpolation - 2D movement jitter/stutter

Started by August 13, 2023 07:52 PM
29 comments, last by skinmarquee 1 year, 3 months ago

I think its a problem with the timer or time values that are used for the alpha calculation.

Here is a graph I made in Excel showing the rx values as they change over time. You can see its not a straight line like it should be, there is a wiggle to it.

To see the wiggle better, we can look at the derivative:

So, for some reason the rate of change of the time values is not consistent, which I assume is what is producing the jitter. Maybe the timer is not as high resolution as it claims, perhaps you only get 1ms resolution and therefore the alpha values are not consistently increasing modulo 1.

Crowbone said:

I think the values look correct; here's a sample of requested points/values during a run where it was jittering:

I would not necessarily say that looks correct. Sometimes you move a position. Sometimes you don't. Sometimes you move two. If those are pixels you might need anti aliasing to make it look smooth.

Advertisement

Gnollrunner said:
I would not necessarily say that looks correct. Sometimes you move a position. Sometimes you don't. Sometimes you move two. If those are pixels you might need anti aliasing to make it look smooth.

Again, moving irregular pixel-intervals per frame doesn't produce visible jittering. A lot of pixel-perfect games have irregular move-intervals. The game I'm making, whose movement is equivalent to that of an old SNES-title, has lots of irregular movement. The player moves 1-2-1-2 px/frame when walking, and 2-3-3-2-3-3 when running. NPCs will often move 0.5px/frame (meaning visually one move every other frame). None of which is noticable as jitter, neigther in the original nor in my reimplementation. Render-interpolation in my case also makes the result even more smooth, especially on high framerate monitors, instead of worse. I'm just typing it again because I do firmly believe that unevenly moving in whole-pixel intervals and antialiasing is not something that OP should need to look into.


Besides, I'm not 100% sure how SDL handles the rectangle-drawning internally - the documentation for SDL_RenderFillRectF mentions it uses sub-pixel precision, so maybe it's exactly that what is causing visual jitter for you. You can try to round the values before passing them into the function, my own implementation (and it's SNES-reference) use round-down for rendering.

If that doesn't help, can you try to make a video showcasing the exact thing you see? It might be hard, but maybe with VSync and 60 FPS recording, it could come through. Because jitter can be highly subjective and/or mean different things. So seeing what is actually going on, might help a lot to pinpoint the issue further.

EDIT:

DUDE THIS GARBAGE PIECE OF SHIT FORUM SOFTWARE KEEPS DELETING THE REST OF MY POST; I SWEAR (with a bit less rage - if I type beyond the link that I posted below, it messes up the editor and when I post everythings gone -.-)

Besides, I'm not 100% sure how SDL handles the rectangle-drawning internally - https://wiki.libsdl.org/SDL2/SDL_RenderFillRectF

Juliean said:

Again, moving irregular pixel-intervals per frame doesn't produce visible jittering.

I wouldn't count it out so fast. It goes from 0 to 2 in places. Intuitively that seems wrong. Also if he's logging a constant time step there isn't much left assuming the logger is correct.

Juliean said:

Gnollrunner said:
I would not necessarily say that looks correct. Sometimes you move a position. Sometimes you don't. Sometimes you move two. If those are pixels you might need anti aliasing to make it look smooth.

Again, moving irregular pixel-intervals per frame doesn't produce visible jittering. A lot of pixel-perfect games have irregular move-intervals. The game I'm making, whose movement is equivalent to that of an old SNES-title, has lots of irregular movement. The player moves 1-2-1-2 px/frame when walking, and 2-3-3-2-3-3 when running. NPCs will often move 0.5px/frame (meaning visually one move every other frame). None of which is noticable as jitter, neigther in the original nor in my reimplementation. Render-interpolation in my case also makes the result even more smooth, especially on high framerate monitors, instead of worse. I'm just typing it again because I do firmly believe that unevenly moving in whole-pixel intervals and antialiasing is not something that OP should need to look into.


Besides, I'm not 100% sure how SDL handles the rectangle-drawning internally - the documentation for SDL_RenderFillRectF mentions it uses sub-pixel precision, so maybe it's exactly that what is causing visual jitter for you. You can try to round the values before passing them into the function, my own implementation (and it's SNES-reference) use round-down for rendering.

If that doesn't help, can you try to make a video showcasing the exact thing you see? It might be hard, but maybe with VSync and 60 FPS recording, it could come through. Because jitter can be highly subjective and/or mean different things. So seeing what is actually going on, might help a lot to pinpoint the issue further.

EDIT:

DUDE THIS GARBAGE PIECE OF SHIT FORUM SOFTWARE KEEPS DELETING THE REST OF MY POST; I SWEAR (with a bit less rage - if I type beyond the link that I posted below, it messes up the editor and when I post everythings gone -.-)

Besides, I'm not 100% sure how SDL handles the rectangle-drawning internally - https://wiki.libsdl.org/SDL2/SDL_RenderFillRectF

I've uploaded a youtube video which shows clearly the jittering:

Out of interest, for your game which rendering library do you use? I'm going to test out the same code with other libraries just to rule that out.

Aressera said:

I think its a problem with the timer or time values that are used for the alpha calculation.

Here is a graph I made in Excel showing the rx values as they change over time. You can see its not a straight line like it should be, there is a wiggle to it.

To see the wiggle better, we can look at the derivative:

So, for some reason the rate of change of the time values is not consistent, which I assume is what is producing the jitter. Maybe the timer is not as high resolution as it claims, perhaps you only get 1ms resolution and therefore the alpha values are not consistently increasing modulo 1.

It would be pretty strange if the timer wasn't high resolution (I think for Windows, the standard library implementation of std::chrono calls QueryPerformanceCounter()). I didn't think about plotting it out on a line like that! I will experiment with different functions and see if the result is any different.

I read an article before that stated that the reading of the current time should be as close to the exact time the frame is rendered but I'm unsure if this could be an issue also?

Advertisement

Crowbone said:
I've uploaded a youtube video which shows clearly the jittering

It looks pretty smooth to me aside from what looks like an inconsistent frame rate at times. Out of curiosity, does it get better if you remove all logging? Logging to console on windows is much slower than you would think because it is synchronous. It may take a significant (and variable) amount of time.

Aressera said:

Crowbone said:
I've uploaded a youtube video which shows clearly the jittering

It looks pretty smooth to me aside from what looks like an inconsistent frame rate at times. Out of curiosity, does it get better if you remove all logging? Logging to console on windows is much slower than you would think because it is synchronous. It may take a significant (and variable) amount of time.

I've checked/logged the frame-rate before; when the program starts up, it's around 39fps then it maintains at 60-61 fps (VSync on) (jittering is still present).

I don't think it makes a difference i.e it doesn't get any better when logging is removed (jittering is still there time to time)

Crowbone said:

I've checked/logged the frame-rate before; when the program starts up, it's around 39fps then it maintains at 60-61 fps (VSync on) (jittering is still present).

I don't think it makes a difference i.e it doesn't get any better when logging is removed (jittering is still there time to time)

Are you sure it's really maintaining 60-61 the whole time? It seems like it only jitters two or three times. Try to isolate those spots. I had a similar problem. In my case it turned out to be deleting meshes in the render thread due to LOD. Could it be some sort of collection that periodically kicks in? Does it happen in the same spot on every run?

I think that the red block moving in the youtube video can be considered as smooth. I have a test unit written in DirectX 9 having the similar lag when running under windowed mode, but basically perfectly smooth when running in exclusive full screen mode.

I also experienced such lag when playing AAA titles in full screen. They may be caused by different reasons according to the techniques used anyway.

None

This topic is closed to new replies.

Advertisement