最近在项目中实现了基于 websocket 数据的 threejs 车流孪生展示,其中有几个问题及其思路在这里记录一下
websocket 数据是实时推送的,且帧数不超过1秒30帧,肉眼可见的卡顿,所以必然需要补帧
- 既然需要补帧那就只有两个思路
- 一就是对数据做插帧,这种做法计算量较大,且插值后的数据可能还不能达到流畅观感,需要再次插值
- 二就是结合
tween 做平滑动画
- 第一种办法个人实践过,当时由于
websocket 数据量本身不小,再加上多次插值与 threejs 场景渲染实体更新,性能较差阻塞了 socket,导致 socket 数据堆积
后续有上网了解过可以使用 webworker 把插值计算放到另外的线程处理,但当时由于工期问题不了了之了。
- 在这里着重说下第二种办法,也是实现了并且效果较好
tween 补帧的原理是已知起点和终点,给定一个时间区间,在 onUpdate 里不断更新,实现平滑动画
- 但是由于
socket 接收到数据只有当前值,即只有终点/起点一个值,所以需要对数据做缓存
socket 数据做了缓存 保存几帧 并不够,还需要对给定的上一帧和下一帧做时间的差值计算,再做一个时间区间的数据缓存
- 这时数据准备完毕,开始执行渲染操作
- 当缓存的数据超过了设定的大小时,开始执行渲染函数,第一帧只添加实体,后续在渲染时不断地取缓存数据的第1个元素值,调用
tween 设置起点(实体当前位置)和终点(第1个缓存数据)和区间时间(缓存的时间区间第1个元素)
tween 的 onUpdate 中不断更新目标实体的 position 和其他需要控制的属性
tween 的 onComplete 中移除已使用的缓存数据,并判断缓存数据大小,递归执行下一次更新
- 以上就是所有实现步骤,亲测按这个方法的实现效果还是不错的
>.<