修复您的时间步长:为什么不直接插入剩余的 dt?

问题描述 投票:0回答:1

Gaffer建议在先前状态和当前状态之间进行线性插值以进行渲染。当前状态与前一个状态相距 1 个完整的固定时间步长。但为什么不直接将剩余的 dt 插入到普通模拟器中,渲染场景,然后丢弃新状态,直到完成一个完整的步骤?

使用 Windows QueryPerformanceCounter 的真实示例:

QueryPerformanceCounter(&after);
float dt = (double)(after.QuadPart-before.QuadPart)/(double)freq.QuadPart;
before = after;
float step = 1.0f/60.0f;
while (dt > step){
    Simulate(step);
    dt -= step;
}
Render(dt);

我认为这只是一个性能问题,以避免每帧运行模拟,而是对新状态进行更便宜的线性插值,您只需计算一次。

c game-physics game-engine timestep
1个回答
1
投票

这不仅仅是“性能问题”。在更新循环结束时再次运行集成步骤将违反 正是本文所提倡的:

问题是物理模拟的行为取决于您传入的增量时间。

通过在更新循环结束时传入小于固定时间步长的

dt
,您会引发物理模拟不一致的问题。使用线性插值根据先前的固定时间步长计算来估计当前状态,可以通过确保始终使用相同的固定时间步长执行积分步骤并消耗插值步骤中的剩余帧时间来避免此问题。

但是为什么不直接将剩余的 dt 插入到普通模拟器中,渲染场景,然后丢弃新状态,直到完成一个完整的步骤?

这句话我不太明白。如果“剩余 dt”指的是 OP 指的是消耗固定时间步长后剩余的分数 dt,那么将该分数 dt 插入积分步骤就是上面描述的问题。

另一方面,也许OP意味着通过固定的时间步长接近总帧时间,然后丢弃剩余的分数dt而不进行模拟。如果这是意图,结果可能会卡顿,因为物理和渲染不同步:

这意味着我们在与渲染时间略有不同的时间显示物理模拟的状态,导致屏幕上的物理模拟出现微妙但视觉上令人不愉快的卡顿。

© www.soinside.com 2019 - 2024. All rights reserved.