# Techniques to mitigate microstuttering when the FPS is above 60fps and vsync is off

The problem with first person shooters is that your input is important, and coupling it with VSync ruins it.

The following frames per second data when rendering with OpenGL shows:

60-100 fps: annoying jitter

140 fps: minor jitter, but certainly noticeable

200 fps: very minor small jitter sometimes

260 fps: either generally fine or very very small

300+ fps: perfectly fine

The problem is other games I play that use similar rendering algorithms only stutter in the range of 60-100fps, whereas my range is 60-250fps (albeit it gets better when you get into the 200 range but you can still notice it if paying attention).

At first I thought my game loop may have been wrong, but after going through it in great detail it is working just fine (and vsync works perfectly smooth with it too, if it was broken this would be an issue the update rate and the vsync monitor refresh rate are not divisible by each other).

60 - 100 fps is 62.5 - 10ms

100 - 250 fps is 10 - 4ms

Not being able to go above 4ms would be pretty constraining!

Because I'm using C# (note: I have zero GC, it doesn't run), I don't know if this means I'm somehow running into higher variability with the VM than I would when I did stuff in C++. I don't know if being in the 4-10ms range means that sometimes it will spike.

Now I did profile this, and this is what I've seen:

Ignoring the green line, the blue line is the uncapped version and orange is vsync. Since the vsync line has massive variability but seems to render fine, whereas the blue one has spikes but are all generally below the vsync line (and definitely not greater than the spikes from vsync), I don't understand whether I'm actually seeing those blue spikes and it's because of some kind of intermediate frame tear or not. It doesn't look like a frame tear to me, it just looks like a frame is lost and I lurch forward a bit more than normal like I was lagging online.

So the question is... what can I do to diagnose this issue? Or is this normal?

I was thinking of rendering to a framebuffer and just drawing that every 1/60 seconds in an attempt to smooth things out and emulate vsync but this comes with it's own drawbacks. Problem is... my back is against the wall and I'm worried I'll be doing potentially stupid and wasteful stuff.

EDIT 1: Ticker code that does what I do

(int, double) timerFunc()
{
long currentTime = GetCurrentTime();

accumulation += currentTime - lastTimeSeen;
lastTimeSeen = currentTime;

// If it returns 1.27, then we have to run 1 tick, and interpolate at t = 0.27
double tickFraction = accumulation / timePerGametick;

int ticksToRun = floor(tickFraction);
double fraction = tickFraction - ticksToRun;

if (ticksToRun > 0)
accumulation -= (ticksToRun * timePerGametick);

return (ticksToRun, fraction);
}


EDIT 2: Game loop and basic logic (uses timerFunc data from above)

void update(int ticksToRun) {
for i in ticksToRun {
foreach plane in planes that should move {
plane.Tick();
}

foreach entity in entities {
entity.Tick();
}
}
}

// interpolation will be in [0.0, 1.0)
void render(double interpolation) {
foreach plane in planes {
planeDelta = (plane.current - plane.prev);
planeInterpolated = plane.prev + (planeDelta * interpolation);
render(planeInterpolated);
}

foreach entity in entities {
entityDelta = (entity.current - entity.prev);
entityInterpolated = entity.prev + (entityDelta * interpolation);
render(entityInterpolated);
}

swapBuffers();
}

void gameLoop() {
while (true) {
(int ticksToRun, double fraction) = timerFunc();

pollInput();

if (ticksToRun > 0)
update(ticksToRun);

render(fraction);
}
}

• Take a look at triple-buffering, maybe it's what you need – Kromster says support Monica Aug 17 at 17:15
• @Kromster Is triple buffering supposed to help with stutter? I was reading online that it makes it worse. Is this wrong? – Water Aug 17 at 17:38
• @Kromster Unfortunately triple buffering didn't help after I enabled it :( – Water Aug 17 at 17:47