Inconsistent interpolation velocity, and interp + lag compensation?

Started by
3 comments, last by Kylotan 6 years ago

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:

 

2018-04-14_14-24-02.gif

 

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

https://streamable.com/72s2d

 

Advertisement

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.

Check my dev blog: http://wobesdev.wordpress.com/

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.

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. :)

This topic is closed to new replies.

Advertisement