不同fps的物理更新不同

Posted

技术标签:

【中文标题】不同fps的物理更新不同【英文标题】:Physics updates different with different fps 【发布时间】:2022-01-20 08:17:48 【问题描述】:

在添加 detune 变量之前,计算机和智能手机上的物理更新明显不同。 在添加和乘以一些变量之后,结果证明可以消除差异,但不能完全一样。 在这方面,我寻求帮助,因为我自己不知道该怎么做。

public void update(float dt, Camera cam)
    float detune=dt/0.01666f;
    if(!ignoreGraviry)
        attraction.add(getGravity().cpy().scl(detune));
    float lx=1-.09f*detune;
    float ly=1-.015f*detune;
    attraction.scl(lx,ly);
    Vector v=getMotion().scl(lx,ly).cpy();
    lastPos=getPosition().cpy();
    getPosition().add(
        v.rotate(cam.getRotation()).add(
            attraction.cpy().rotate(cam.getRotation())
        ).scl(dt));

【问题讨论】:

【参考方案1】:

问题

detune 所做的是将模拟循环效果放大 60 倍。所以基本上,不必模拟 60 个循环,而只需模拟 1 个循环。但是结果会更加不准确,可能只有一点,也可能很多,这取决于外部模拟的其余部分是否稳定/收敛。同样使用lxly,这种detune 的完成方式看起来非常糟糕(对于您的问题未提供的一些外部知识可能没问题),因为您永远不应该将线性缩放效果与加法相结合。这会比你想象的更快把你扔进地狱的坑。例如,lx 将采用负数或正数,具体取决于 dtdt 通常是“增量时间”,可让您调整模拟的粒度与速度。因此,如果有人调整dt 并且突然模拟向后运行,这将成为一个真正的痛点。

解决方案

你的代码中不应该有 detune 这样的。更好地增加dt 值。确保计算周期在 PC 和智能手机上具有相同的时间距离,例如每秒 30 次(30 fps,dt=33ms),其余时间休眠。如果你不能保证,模拟结果总是会有所不同,从而带来优势或劣势。

我不知道 libgdx 是否有固定的模拟图形周期,所以每次图形更新只有一个模拟。但是在大多数引擎中(是的,尤其是游戏,这就是为什么多线程/核心通常在那里没用的原因)它们是高度耦合的,这在现代编程语言中非常糟糕,因为那样你就不得不限制你的模拟算法和图形更新PC 和手机的最低硬件,并将它们限制在最差的图形和计算最低要求。

如果您可以解耦模拟和图形,您只需要考虑最低的计算能力。关于图形,您始终可以在每个系统上运行最大帧速率(或限制为 90fps,只有极少数人有更高的敏锐度),充分利用图形硬件,获得最流畅的渲染。

【讨论】:

以上是关于不同fps的物理更新不同的主要内容,如果未能解决你的问题,请参考以下文章

即使使用 DeltaTime,C++ Raylib 在不同的 FPS 下也有不同的移动速度

unity优化

将套接字重新绑定到不同的接口

有效控制 Adob​​e Flash 中的 fps

统一不同屏幕尺寸下的不同物理行为

linux 不同进程间能否传递指针?(不能,虚拟地址进程私有,被不同进程映射到物理地址不同)