Inconsistent interpolation velocity, and interp + lag compensation?

Recommended Posts

My interpolation is having some jitters, and I think I've boiled it down to an inconsistent velocity based on the distance of point A to B.  Is there a standard way of ensuring my interpolations are consistent?  I'm not performing any sort of extrapolation, but I feel that might be the key, I'm just struggling a bit with the actual implementation of it.  Here's my code, called every frame for every entity:

var nextFrameIdx = GetFrameInPast(interp.Frames, 0.1f);

// no available frame
if (nextFrameIdx == -1)
{
continue;
}

var frame = interp.Frames[nextFrameIdx];
var ent = (NetEntity)hm;

if (nextFrameIdx != interp.nextFrame)
{
//Debug.Log("------------------------------");
interp.fromPosition = pair.Key.Model.Position; // current rendered position
interp.fromAngles = pair.Key.Model.Angles; // current rendered angles
interp.toPosition = frame.Position; // state received by server
interp.toAngles = frame.Angles; // state received by server
interp.velocity = frame.Velocity; // state received by server
interp.nextFrame = nextFrameIdx;
//interp.accumulator = 0;
interp.startTime = Time.time;
interp.finishTime = Time.time + updateRate;
}

Debug.DrawLine(interp.fromPosition, interp.fromPosition + Vector3.up * 2, Color.green);
Debug.DrawLine(interp.toPosition, interp.toPosition + Vector3.up * 2, Color.yellow);

//interp.accumulator += Time.deltaTime;
//var t = interp.accumulator / (interp.finishTime - interp.startTime);
var t = (Time.time - interp.startTime) / (interp.finishTime - interp.startTime);
//Debug.Log(t);
var newPos = Vector3.LerpUnclamped(interp.fromPosition, interp.toPosition, t);
var newRot = Quaternion.Lerp(Quaternion.Euler(interp.fromAngles), Quaternion.Euler(interp.toAngles), t);
hm.Model.Set(newPos, newRot.eulerAngles);

And here's how it looks, with an update rate of 2 per second:

You can see movement velocity varies depending on how far the entity must move.  With a smaller update interval, this becomes less obvious, but there are micro-jitters which I'm looking to get rid of.

My other question is about lag compensation.  In my code, each entity has its own accumulator or subframe for interpolation.  Do I have to interpolate all entities simultaneously between global snapshots in order to send the client's subframe to servers to achieve an accurate rewind?

edit: Here's a video showing the jitter at various update rates.  Maybe its unrelated to my initial problem?  More update rates gives pretty consistent spacings between point a & b

Edited by Crayz92

Share on other sites

http://www.kinematicsoup.com/news/2016/8/9/rrypp5tkubynjwxhxjzd42s3o034o8 here you might find possible fix to your problem, when you're using frame / timestamp -dependent movement.

/MODERATOR COMMENT: The link goes to an article about smoothing motion and how to work with timestamps in Unity.  Without any other words nor useful text in the URL, I wasn't sure if I was clicking through to spam or a browser hijacking, or if it was actually related to the discussion.

Edited by wobes

Share on other sites
8 hours ago, wobes said:

Useful article, but not related to networking.

I fixed up my interp logic a bit.  Had some issues with how I was finding the next frame to transition to, and processing the same position twice (t=1, then t=0 after finding a new frame), however still curious about lag compensation.

Edited by Crayz92

Share on other sites

This has been covered a lot of times on this forum so do a search and you might find some hints that help you out.

Generally speaking there isn't so much one standard way of handling this, but a bunch of broad principles you get to trade-off, depending on what is most important to you - lowest latency, most accurate position, most accurate velocity, etc.

If your system is buffering up updates ('frames'?) and you attempt to keep a buffer of 100 milliseconds (the GetFrameInPast / 0.1f bit?) then the broad logic looks correct, and you shouldn't need extrapolation. However, your system directly lerps towards the next frame's position as soon as the frame changes - this means that velocity will also change instantly at that point as these frame switches will not be at exact and identical millisecond boundaries, and those velocity discontinuities are often visible.

The easiest improvement here is, as you know, to increase the update rate - more updates per second means that these discontinuities will be smaller and less visible. But you can also be careful at the time you switch frames and be careful to handle the timing error. For example, you'll normally switch frames some number of milliseconds early, so you can add that to the next frame duration to balance it out. There are also ways to interpolate velocity rather than position to smooth over these discontinuities - probably easy if your calculus is good, which mine is not.

Create an account

Register a new account

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 14
• 12
• 29
• 11
• 47
• Forum Statistics

• Total Topics
634863
• Total Posts
3019690
×