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