Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
前言
物理周期与渲染帧
One key concept to understand in Godot is the distinction between physics ticks (sometimes referred to as iterations or physics frames), and rendered frames. The physics proceeds at a fixed tick rate (set in Project Settings > Physics > Common > Physics Tick per Second), which defaults to 60 ticks per second.
However, the engine does not necessarily render at the same rate. Although many monitors refresh at 60 Hz (cycles per second), many refresh at completely different frequencies (e.g. 75 Hz, 144 Hz, 240 Hz or more). Even though a monitor may be able to show a new frame e.g. 60 times a second, there is no guarantee that the CPU and GPU will be able to supply frames at this rate. For instance, when running with V-Sync, the computer may be too slow for 60 and only reach the deadlines for 30 FPS, in which case the frames you see will change at 30 FPS (resulting in stuttering).
But there is a problem here. What happens if the physics ticks do not coincide with frames? What happens if the physics tick rate is out of phase with the frame rate? Or worse, what happens if the physics tick rate is lower than the rendered frame rate?
This problem is easier to understand if we consider an extreme scenario. If you set the physics tick rate to 10 ticks per second, in a simple game with a rendered frame rate of 60 FPS. If we plot a graph of the positions of an object against the rendered frames, you can see that the positions will appear to "jump" every 1/10th of a second, rather than giving a smooth motion. When the physics calculates a new position for a new object, it is not rendered in this position for just one frame, but for 6 frames.

This jump can be seen in other combinations of tick / frame rate as glitches, or jitter, caused by this staircasing effect due to the discrepancy between physics tick time and rendered frame time.
渲染帧和物理周期不同步怎么办?
是否要将物理周期和渲染帧锁定?
The most obvious solution is to get rid of the problem, by ensuring there is a physics tick that coincides with every frame. This used to be the approach on old consoles and fixed hardware computers. If you know that every player will be using the same hardware, you can ensure it is fast enough to calculate ticks and frames at e.g. 50 FPS, and you will be sure it will work great for everybody.
However, modern games are often no longer made for fixed hardware. You will often be planning to release on desktop computers, mobiles, and more. All of which have huge variations in performance, as well as different monitor refresh rates. We need to come up with a better way of dealing with the problem.
适应物理周期率?
Instead of designing the game at a fixed physics tick rate, we could allow the tick rate to scale according to the end user's hardware. We could for example use a fixed tick rate that works for that hardware, or even vary the duration of each physics tick to match a particular frame duration.
This works, but there is a problem. Physics (and game logic, which is often also
run in the _physics_process
) work best and most consistently when run at a
fixed, predetermined tick rate. If you attempt to run a racing game physics
that has been designed for 60 TPS (ticks per second) at e.g. 10 TPS, the physics
will behave completely differently. Controls may be less responsive, collisions /
trajectories can be completely different. You may test your game thoroughly at 60
TPS, then find it breaks on end users' machines when it runs at a different tick
rate.
This can make quality assurance difficult with hard to reproduce bugs, especially in AAA games where problems of this sort can be very costly. This can also be problematic for multiplayer games for competitive integrity, as running the game at certain tick rates may be more advantageous than others.
锁定物理周期率,但在物理周期之间使用插值让渲染帧平滑
This has become one of the most popular approaches to deal with the problem, although it is optional and disabled by default.
We have established that the most desirable physics/game logic arrangement for consistency and predictability is a physics tick rate that is fixed at design-time. The problem is the discrepancy between the physics position recorded, and where we "want" a physics object to be shown on a frame to give smooth motion.
The answer turns out to be simple, but can be a little hard to get your head around at first.
Instead of keeping track of just the current position of a physics object in the engine, we keep track of both the current position of the object, and the previous position on the previous physics tick.
Why do we need the previous position (in fact the entire transform, including rotation and scaling)? By using a little math magic, we can use interpolation to calculate what the transform of the object would be between those two points, in our ideal world of smooth continuous movement.

线性插值
The simplest way to achieve this is linear interpolation, or lerping, which you may have used before.
Let us consider only the position, and a situation where we know that the previous physics tick X coordinate was 10 units, and the current physics tick X coordinate is 30 units.
备注
Although the maths is explained here, you do not have to worry about the details, as this step will be performed for you. Under the hood, Godot may use more complex forms of interpolation, but linear interpolation is the easiest in terms of explanation.
物理插值比例
假设(在这个例子中)物理周期是每秒 10 次,那么渲染帧位于 0.12 秒的话会发生什么呢?要实现两个周期之间的平滑运动,物体所处的位置,我们来解一个数学题就知道了。
首先,我们要计算物体在物理周期中经过了多久。如果上一个物理周期在 0.1 秒,那么我们就在物理周期中经过了 (0.12 - 0.1) 即 0.02 秒,因为一个周期总共 0.1 秒(每秒 10 个周期)。所以周期中的比例就是:
fraction = 0.02 / 0.10
fraction = 0.2
这个值叫做物理插值比例,Godot 会帮你计算好,可以在任何帧中调用 Engine.get_physics_interpolation_fraction 来获取。
计算插值位置
得到插值比例后,我们就可以把它代入标准线性插值公式。所以 X 坐标就是:
x_interpolated = x_prev + ((x_curr - x_prev) * 0.2)
将 x_prev
替换为 10,将 x_curr
替换为 30:
x_interpolated = 10 + ((30 - 10) * 0.2)
x_interpolated = 10 + 4
x_interpolated = 14
让我们来拆解一下:
我们知道 X 从上一周期的坐标(
x_prev
)开始,该坐标为 10 个单位。我们知道在完整的一个周期之后,会加上当前周期与上一周期之间的差值(
x_curr - x_prev
)(即 20 个单位)。The only thing we need to vary is the proportion of this difference we add, according to how far we are through the physics tick.
备注
Although this example interpolates the position, the same thing can be done with the rotation and scale of objects. It is not necessary to know the details as Godot will do all this for you.
物理周期之间的平滑变换?
Putting all this together shows that it should be possible to have a nice smooth estimation of the transform of objects between the current and previous physics tick.
但是等等,你可能已经注意到了。如果我们是在当前周期和上一个周期之间进行插值,那我们并不是在估计物体现在的位置,而是在估计物体过去的位置。准确地说,我们是在估计物体在过去的 1 到 2 个周期之间的位置。
过去
这是什么意思?这种方案确实可行,但也意味着我们本质上是在屏幕上看到的内容和物体应该在的位置之间引入了一个延迟。
In practice, most people won't notice this delay, or rather, it is typically not objectionable. There are already significant delays involved in games, we just don't typically notice them. The most significant effect is there can be a slight delay to input, which can be a factor in fast twitch games. In some of these fast input situations, you may wish to turn off physics interpolation and use a different scheme, or use a high tick rate, which mitigates these delays.
为什么回顾过去?为什么不预测未来?
There is an alternative to this scheme, which is: instead of interpolating between the previous and current tick, we use maths to extrapolate into the future. We try to predict where the object will be, rather than show it where it was. This can be done and may be offered as an option in future, but there are some significant downsides:
The prediction may not be correct, especially when an object collides with another object during the physics tick.
Where a prediction was incorrect, the object may extrapolate into an "impossible" position, like inside a wall.
Providing the movement speed is slow, these incorrect predictions may not be too much of a problem.
When a prediction was incorrect, the object may have to jump or snap back onto the corrected path. This can be visually jarring.
固定时间步长插值
In Godot this whole system is referred to as physics interpolation, but you may also hear it referred to as "fixed timestep interpolation", as it is interpolating between objects moved with a fixed timestep (physics ticks per second). In some ways the second term is more accurate, because it can also be used to interpolate objects that are not driven by physics.
小技巧
Although physics interpolation is usually a good choice, there are exceptions where you may choose not to use Godot's built-in physics interpolation (or use it in a limited fashion). An example category is internet multiplayer games. Multiplayer games often receive tick or timing based information from other players or a server and these may not coincide with local physics ticks, so a custom interpolation technique can often be a better fit.