公式
首先,帧同步中,有逻辑帧间隔,我们记为LogicFrameConfig.LogicFrameInterval
那么,渲染帧的计算我先给出公式就是:
渲染帧间隔时间 = (下一次逻辑帧的累积时间 - 当前逻辑帧的累积时间)/ 逻辑帧间隔
下一次逻辑帧的累积时间 我们记为 m_NextLogicFrameTime
当前逻辑帧的累积时间 我们记为 m_AccLogicFrameTime
因而我在代码中是这样编写的:
DeltaTime = (m_NextLogicFrameTime - m_AccLogicFrameTime) / LogicFrameConfig.LogicFrameInterval;
位置更新流程
接着,我们在游戏中,由于逻辑与渲染分离的缘故,位置的更新的过程是这样的:
打印理解
可以看到渲染帧在第一次执行,插值的计算就与逻辑帧差不多是一样的了。
往后DeltaTime会越来越小,相当于在下一次逻辑帧执行前做细小的微调
深究
当然,在这过程中,我还发现如果在DeltaTime计算公式前加上 1 - ,得到的效果其实会更好
DeltaTime =1 - ( (m_NextLogicFrameTime - m_AccLogicFrameTime) /LogicFrameConfig.LogicFrameInterval);
从数值上理解,是这样的,DeltaTime是逐渐变大的
在差不多接近下一次的逻辑帧,渲染位置才与逻辑位置差不多一样。
总结
以上两种方式用哪种呢?我个人测试下来,在逻辑帧间隔为15帧的时候,后者比前者的效果用好得多。
前者明显有卡顿,后者则丝滑一些。
这个从数值上也是很好理解的。
前者的DeltaTime是从大变小的,因而渲染位置的插值计算在头几个渲染帧便与逻辑位置几乎一致。
后者的DeltaTime是从小变大的,因而渲染位置的插值计算在后几个渲染帧才与逻辑位置几乎一致。
因而相比较来说,前者是突变的,后者则是渐变的。
对比
为了对比效果更明显,我这里用的是12帧进行对比
没有1减的
有1减的
由于gif采样率可能较低,感受不明显,如果有兴趣可以找我要mp4文件,或者自己本地实现一下。