Sfoglia il codice sorgente

Port physics interpolation docs from 3.6

skyace65 8 mesi fa
parent
commit
6b4a2c9801

+ 1 - 0
tutorials/physics/index.rst

@@ -19,3 +19,4 @@ Physics
    collision_shapes_3d
    large_world_coordinates
    troubleshooting_physics_issues
+   interpolation/index

+ 69 - 0
tutorials/physics/interpolation/2d_and_3d_physics_interpolation.rst

@@ -0,0 +1,69 @@
+.. _doc_2d_and_3d_physics_interpolation:
+
+2D and 3D physics interpolation
+===============================
+
+Generally 2D and 3D physics interpolation work in very similar ways. However, there
+are a few differences, which will be described here.
+
+Global versus local interpolation
+---------------------------------
+
+- In 3D, physics interpolation is performed *independently* on the **global
+  transform** of each 3D instance.
+- In 2D by contrast, physics interpolation is performed on the **local transform**
+  of each 2D instance.
+
+This has some implications:
+
+- In 3D, it is easy to turn interpolation on and off at the level of each ``Node``,
+  via the ``physics_interpolation_mode`` property in the Inspector, which can be
+  set to ``On``, ``Off``, or ``Inherited``.
+
+.. figure:: img/physics_interpolation_mode.webp
+    :align: center
+
+- However this means that in 3D, pivots that occur in the ``SceneTree`` (due to
+  parent child relationships) can only be interpolated **approximately** over the
+  physics tick. In most cases this will not matter, but in some situations the
+  interpolation can look slightly wrong.
+- In 2D, interpolated local transforms are passed down to children during
+  rendering. This means that if a parent is set to ``physics_interpolation_mode``
+  ``On``, but the child is set to ``Off``, the child will still be interpolated if
+  the parent is moving. *Only the child's local transform is uninterpolated.*
+  Controlling the on / off behavior of 2D nodes therefore requires a little more
+  thought and planning.
+- On the positive side, pivot behavior in the scene tree is perfectly preserved
+  during interpolation in 2D, which gives super smooth behaviour.
+
+Resetting physics interpolation
+-------------------------------
+
+Whenever objects are moved to a completely new position, and interpolation is not
+desired (so as to prevent a "streaking" artefact), it is the responsibility of the
+user to call ``reset_physics_interpolation()``.
+
+The good news is that in 2D, this is automatically done for you when nodes first
+enter the tree. This reduces boiler plate, and reduces the effort required to get
+an existing project working.
+
+.. note:: If you move objects *after* adding to the scene tree, you will still need
+          to call ``reset_physics_interpolation()`` as with 3D.
+
+2D Particles
+------------
+
+Currently only ``CPUParticles2D`` are supported for physics interpolation in 2D. It
+is recommended to use a physics tick rate of at least 20-30 ticks per second to
+keep particles looking fluid.
+
+``Particles2D`` (GPU particles) are not yet interpolated, so for now it is
+recommended to convert to ``CPUParticles2D`` (but keep a backup of your
+``Particles2D`` in case we get these working).
+
+Other
+-----
+
+- ``get_global_transform_interpolated()`` - this is currently only available for 3D.
+- ``MultiMeshes`` - these should be supported in both 2D and 3D.
+

+ 174 - 0
tutorials/physics/interpolation/advanced_physics_interpolation.rst

@@ -0,0 +1,174 @@
+.. _doc_advanced_physics_interpolation:
+
+Advanced physics interpolation
+==============================
+
+Although the previous instructions will give satisfactory results in a lot of games,
+in some cases you will want to go a stage further to get the best possible results
+and the smoothest possible experience.
+
+Exceptions to automatic physics interpolation
+---------------------------------------------
+
+Even with physics interpolation active, there may be some local situations where
+you would benefit from disabling automatic interpolation for a
+:ref:`Node<class_Node>` (or branch of the :ref:`SceneTree<class_SceneTree>`), and
+have the finer control of performing interpolation manually.
+
+This is possible using the :ref:`Node.physics_interpolation_mode<class_Node_property_physics_interpolation_mode>`
+property which is present in all Nodes. If you for example, turn off interpolation
+for a Node, the children will recursively also be affected (as they default to
+inheriting the parent setting). This means you can easily disable interpolation for
+an entire subscene.
+
+The most common situation where you may want to perform your own interpolation is
+Cameras.
+
+Cameras
+~~~~~~~
+
+In many cases, a :ref:`Camera3D<class_Camera3D>` can use automatic interpolation
+just like any other node. However, for best results, especially at low physics tick
+rates, it is recommended that you take a manual approach to camera interpolation.
+
+This is because viewers are very sensitive to camera movement. For instance, a
+Camera3D that realigns slightly every 1/10th of a second (at 10tps tick rate) will
+often be noticeable. You can get a much smoother result by moving the camera each
+frame in ``_process``, and following an interpolated target manually.
+
+Manual camera interpolation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Ensure the camera is using global coordinate space
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The very first step when performing manual camera interpolation is to make sure the
+Camera3D transform is specified in *global space* rather than inheriting the
+transform of a moving parent. This is because feedback can occur between the
+movement of a parent node of a Camera3D and the movement of the camera Node itself,
+which can mess up the interpolation.
+
+There are two ways of doing this:
+
+1) Move the Camera3D so it is independent on its own branch, rather than being a child of a moving object.
+
+.. image:: img/fti_camera_worldspace.webp
+
+2) Call :ref:`Node3D.top_level<class_Node3D_property_top_level>` and set this to ``true``, which will make the Camera ignore the transform of its parent.
+
+Typical example
+^^^^^^^^^^^^^^^
+
+A typical example of a custom approach is to use the ``look_at`` function in the
+Camera3D every frame in ``_process()`` to look at a target node (such as the player).
+
+But there is a problem. If we use the traditional ``get_global_transform()`` on a
+Camera3D "target" node, this transform will only focus the Camera3D on the target *at
+the current physics tick*. This is *not* what we want, as the camera will jump
+about on each physics tick as the target moves. Even though the camera may be
+updated each frame, this does not help give smooth motion if the *target* is only
+changing each physics tick.
+
+get_global_transform_interpolated()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+What we really want to focus the camera on, is not the position of the target on
+the physics tick, but the *interpolated* position, i.e. the position at which the
+target will be rendered.
+
+We can do this using the :ref:`Spatial.get_global_transform_interpolated<class_Node3D_method_get_global_transform_interpolated>`
+function. This acts exactly like getting :ref:`Spatial.global_transform<class_Node3D_property_global_transform>`
+but it gives you the *interpolated* transform (during a ``_process()`` call).
+
+.. important:: ``get_global_transform_interpolated()`` should only be used once or
+               twice for special cases such as cameras. It should **not** be used
+               all over the place in your code (both for performance reasons, and
+               to give correct gameplay).
+
+.. note:: Aside from exceptions like the camera, in most cases, your game logic
+          should be in ``_physics_process()``. In game logic you should be calling
+          ``get_global_transform()`` or ``get_transform()``, which will give the
+          current physics transform (in global or local space respectively), which
+          is usually what you will want for gameplay code.
+
+Example manual camera script
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Here is an example of a simple fixed camera which follows an interpolated target:
+
+.. code-block:: gdscript
+
+    extends Camera3D
+        
+    # Node that the camera will follow
+    var _target
+        
+    # We will smoothly lerp to follow the target
+    # rather than follow exactly
+    var _target_pos : Vector3 = Vector3()
+        
+    func _ready() -> void:
+        # Find the target node
+        _target = get_node("../Player")
+        
+        # Turn off automatic physics interpolation for the Camera3D,
+        # we will be doing this manually
+        set_physics_interpolation_mode(Node.PHYSICS_INTERPOLATION_MODE_OFF)
+        
+    func _process(delta: float) -> void:
+        # Find the current interpolated transform of the target
+        var tr : Transform = _target.get_global_transform_interpolated()
+        
+        # Provide some delayed smoothed lerping towards the target position 
+        _target_pos = lerp(_target_pos, tr.origin, min(delta, 1.0))
+        
+        # Fixed camera position, but it will follow the target
+        look_at(_target_pos, Vector3(0, 1, 0))
+
+Mouse look
+^^^^^^^^^^
+
+Mouse look is a very common way of controlling cameras. But there is a problem.
+Unlike keyboard input which can be sampled periodically on the physics tick, mouse
+move events can come in continuously. The camera will be expected to react and
+follow these mouse movements on the next frame, rather than waiting until the next
+physics tick.
+
+In this situation, it can be better to disable physics interpolation for the camera
+node (using :ref:`Node.physics_interpolation_mode<class_Node_property_physics_interpolation_mode>`)
+and directly apply the mouse input to the camera rotation, rather than apply it in
+``_physics_process``.
+
+Sometimes, especially with cameras, you will want to use a combination of
+interpolation and non-interpolation:
+
+* A first person camera may position the camera at a player location (perhaps using :ref:`Spatial.get_global_transform_interpolated<class_Node3D_method_get_global_transform_interpolated>`), but control the Camera rotation from mouse look *without* interpolation.
+* A third person camera may similarly determine the look at (target location) of the camera using :ref:`Spatial.get_global_transform_interpolated<class_Node3D_method_get_global_transform_interpolated>`, but position the camera using mouse look *without* interpolation.
+
+There are many permutations and variations of camera types, but it should be clear
+that in many cases, disabling automatic physics interpolation and handling this
+yourself can give a better result.
+
+Disabling interpolation on other nodes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Although cameras are the most common example, there are a number of cases when you
+may wish other nodes to control their own interpolation, or be non-interpolated.
+Consider for example, a player in a top view game whose rotation is controlled by
+mouse look. Disabling physics rotation allows the player rotation to match the
+mouse in real-time.
+
+
+MultiMeshes
+~~~~~~~~~~~
+
+Although most visual Nodes follow the single Node single visual instance paradigm,
+MultiMeshes can control several instances from the same Node. Therefore, they have
+some extra functions for controlling interpolation functionality on a
+*per-instance* basis. You should explore these functions if you are using
+interpolated MultiMeshes.
+
+- :ref:`MultiMesh.reset_instance_physics_interpolation<class_MultiMesh_method_reset_instance_physics_interpolation>`
+- :ref:`MultiMesh.set_buffer_interpolated<class_MultiMesh_method_set_buffer_interpolated>`
+
+Full details are in the :ref:`MultiMesh<class_MultiMesh>` documentation.

BIN
tutorials/physics/interpolation/img/fti_camera_worldspace.webp


BIN
tutorials/physics/interpolation/img/fti_graph_fixed_ticks.webp


BIN
tutorials/physics/interpolation/img/fti_graph_interpolated.webp


BIN
tutorials/physics/interpolation/img/physics_interpolation_mode.webp


+ 14 - 0
tutorials/physics/interpolation/index.rst

@@ -0,0 +1,14 @@
+.. _doc_physics_interpolation:
+
+Physics Interpolation
+=====================
+
+.. toctree::
+   :maxdepth: 1
+   :name: toc-physics-interpolation
+
+   physics_interpolation_quick_start_guide
+   physics_interpolation_introduction
+   using_physics_interpolation
+   advanced_physics_interpolation
+   2d_and_3d_physics_interpolation

+ 232 - 0
tutorials/physics/interpolation/physics_interpolation_introduction.rst

@@ -0,0 +1,232 @@
+.. _doc_physics_interpolation_introduction:
+
+Introduction
+============
+
+Physics ticks and rendered frames
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+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 :ref:`Project Settings > Physics > Common > Physics Tick per Second<class_ProjectSettings_property_physics/common/physics_ticks_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.
+
+.. image:: img/fti_graph_fixed_ticks.webp
+
+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.
+
+What can we do about frames and ticks being out of sync?
+--------------------------------------------------------
+
+Lock the tick / frame rate together?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+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.
+
+Adapt the tick rate?
+^^^^^^^^^^^^^^^^^^^^
+
+Instead of designing the game at a fixed physics tick rate, we could allow the tick
+rate to scale according to the end users 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.
+
+Lock the tick rate, but use interpolation to smooth frames in between physics ticks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+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.
+
+.. image:: img/fti_graph_interpolated.webp
+
+Linear interpolation
+^^^^^^^^^^^^^^^^^^^^
+
+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.
+
+.. note:: 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.
+
+The physics interpolation fraction
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If our physics ticks are happening 10 times per second (for this example), what
+happens if our rendered frame takes place at time 0.12 seconds? We can do some math
+to figure out where the object would be to obtain a smooth motion between the two
+ticks.
+
+First of all, we have to calculate how far through the physics tick we want the
+object to be. If the last physics tick took place at 0.1 seconds, we are 0.02
+seconds *(0.12 - 0.1)* through a tick that we know will take 0.1 seconds (10 ticks
+per second). The fraction through the tick is thus:
+
+.. code-block:: gdscript
+
+	fraction = 0.02 / 0.10
+	fraction = 0.2
+
+This is called the **physics interpolation fraction**, and is handily calculated
+for you by Godot. It can be retrieved on any frame by calling :ref:`Engine.get_physics_interpolation_fraction<class_Engine_method_get_physics_interpolation_fraction>`.
+
+Calculating the interpolated position
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Once we have the interpolation fraction, we can insert it into a standard linear
+interpolation equation. The X coordinate would thus be:
+
+.. code-block:: gdscript
+
+	x_interpolated = x_prev + ((x_curr - x_prev) * 0.2)
+
+So substituting our ``x_prev`` as 10, and ``x_curr`` as 30:
+
+.. code-block:: gdscript
+
+	x_interpolated = 10 + ((30 - 10) * 0.2)
+	x_interpolated = 10 + 4
+	x_interpolated = 14
+
+Let's break that down:
+
+- We know the X starts from the coordinate on the previous tick (``x_prev``) which
+  is 10 units.
+- We know that after the full tick, the difference between the current tick and the
+  previous tick will have been added (``x_curr - x_prev``) (which is 20 units).
+- 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.
+
+.. note:: 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.
+
+Smoothed transformations between physics ticks?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+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.
+
+But wait, you may have noticed something. If we are interpolating between the
+current and previous ticks, we are not estimating the position of the object *now*,
+we are estimating the position of the object in the past. To be exact, we are
+estimating the position of the object *between 1 and 2 ticks* into the past.
+
+In the past
+^^^^^^^^^^^
+
+What does this mean? This scheme does work, but it does mean we are effectively
+introducing a delay between what we see on the screen, and where the objects
+*should* be.
+
+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.
+
+Why look into the past? Why not predict the future?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+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.
+
+Fixed timestep interpolation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+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.
+
+.. tip:: 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.

+ 14 - 0
tutorials/physics/interpolation/physics_interpolation_quick_start_guide.rst

@@ -0,0 +1,14 @@
+.. _doc_physics_interpolation_quick_start_guide:
+
+Quick start guide
+=================
+
+- Turn on physics interpolation: :ref:`Project Settings > Physics > Common > Physics Interpolation<class_ProjectSettings_property_physics/common/physics_interpolation>`
+- Make sure you move objects and run your game logic in ``_physics_process()``
+  rather than ``_process()``. This includes moving objects directly *and
+  indirectly* (by e.g. moving a parent, or using another mechanism to automatically
+  move nodes).
+- Be sure to call :ref:`Node.reset_physics_interpolation<class_Node_method_reset_physics_interpolation>`
+  on nodes *after* you first position or teleport them, to prevent "streaking".
+- Temporarily try setting :ref:`Project Settings > Physics > Common > Physics Tick per Second<class_ProjectSettings_property_physics/common/physics_ticks_per_second>`
+  to 10 to see the difference with and without interpolation.

+ 154 - 0
tutorials/physics/interpolation/using_physics_interpolation.rst

@@ -0,0 +1,154 @@
+.. _doc_using_physics_interpolation:
+
+Using physics interpolation
+===========================
+
+How do we incorporate physics interpolation into a Godot game? Are there any
+caveats?
+
+We have tried to make the system as easy to use as possible, and many existing
+games will work with few changes. That said there are some situations which require
+special treatment, and these will be described.
+
+Turn on the physics interpolation setting
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The first step is to turn on physics interpolation in :ref:`ProjectSettings.physics/common/physics_interpolation<class_ProjectSettings_property_physics/common/physics_interpolation>`.
+You can now run your game.
+
+It is likely that nothing looks hugely different, particularly if you are running
+physics at 60 TPS or a multiple of it. However, quite a bit more is happening
+behind the scenes.
+
+.. tip::
+
+    To convert an existing game to use interpolation, it is highly recommended that
+    you temporarily set :ref:`ProjectSettings.physics/common/physics_ticks_per_second<class_ProjectSettings_property_physics/common/physics_ticks_per_second>`
+    to a low value such as 10, which will make interpolation problems more obvious.
+
+Move (almost) all game logic from _process to _physics_process
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The most fundamental requirement for physics interpolation (which you may be doing
+already) is that you should be moving and performing game logic on your objects
+within ``_physics_process`` (which runs at a physics tick) rather than ``_process``
+(which runs on a rendered frame). This means your scripts should typically be doing
+the bulk of their processing within ``_physics_process``, including responding to
+input and AI.
+
+Setting the transform of objects only within physics ticks allows the automatic
+interpolation to deal with transforms *between* physics ticks, and ensures the game
+will run the same whatever machine it is run on. As a bonus, this also reduces CPU
+usage if the game is rendering at high FPS, since AI logic (for example) will no
+longer run on every rendered frame.
+
+.. note:: If you attempt to set the transform of interpolated objects *outside* the
+          physics tick, the calculations for the interpolated position will be
+          incorrect, and you will get jitter. This jitter may not be visible on
+          your machine, but it *will* occur for some players. For this reason,
+          setting the transform of interpolated objects should be avoided outside
+          of the physics tick. Godot will attempt to produce warnings in the editor
+          if this case is detected.
+
+.. tip:: This is only a *soft rule*. There are some occasions where you might want
+         to teleport objects outside of the physics tick (for instance when
+         starting a level, or respawning objects). Still, in general, you should be
+         applying transforms from the physics tick.
+
+
+Ensure that all indirect movement happens during physics ticks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Consider that in Godot, Nodes can be moved not just directly in your own scripts,
+but also by automatic methods such as tweening, animation, and navigation. All
+these methods should also have their timing set to operate on the physics tick
+rather than each frame ("idle"), **if** you are using them to move objects (*these
+methods can also be used to control properties that are not interpolated*).
+
+.. note:: Also consider that nodes can be moved not just by moving themselves, but
+          also by moving parent nodes in the :ref:`SceneTree<class_SceneTree>`. The
+          movement of parents should therefore also only occur during physics ticks.
+
+Choose a physics tick rate
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When using physics interpolation, the rendering is decoupled from physics, and you
+can choose any value that makes sense for your game. You are no longer limited to
+values that are multiples of the user's monitor refresh rate (for stutter-free
+gameplay if the target FPS is reached).
+
+As a rough guide:
+
+.. csv-table::
+    :header: "Low tick rates (10-30)", "Medium tick rates (30-60)", "High tick rates (60+)"
+    :widths: 20, 20, 20
+    
+    "Better CPU performance","Good physics behavior in complex scenes","Good with fast physics"
+    "Add some delay to input","Good for first person games","Good for racing games"
+    "Simple physics behaviour"
+
+.. note:: You can always change the tick rate as you develop, it is as simple as
+          changing the project setting.
+
+Call ``reset_physics_interpolation()`` when teleporting objects
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Most of the time, interpolation is what you want between two physics ticks.
+However, there is one situation in which it may *not* be what you want. That is
+when you are initially placing objects, or moving them to a new location. Here, you
+don't want a smooth motion between where the object was (e.g. the origin) and the
+initial position - you want an instantaneous move.
+
+The solution to this is to call the :ref:`Node.reset_physics_interpolation<class_Node_method_reset_physics_interpolation>`
+function. What this function does under the hood is set the internally stored
+*previous transform* of the object to be equal to the *current transform*. This
+ensures that when interpolating between these two equal transforms, there will be
+no movement.
+
+Even if you forget to call this, it will usually not be a problem in most
+situations (especially at high tick rates). This is something you can easily leave
+to the polishing phase of your game. The worst that will happen is seeing a
+streaking motion for a frame or so when you move them - you will know when you need
+it!
+
+There are actually two ways to use ``reset_physics_interpolation()``:
+
+*Standing start (e.g. player)*
+
+1) Set the initial transform
+2) Call ``reset_physics_interpolation()``
+
+The previous and current transforms will be identical, resulting in no initial
+movement.
+
+*Moving start (e.g. bullet)*
+
+1) Set the initial transform
+2) Call ``reset_physics_interpolation()``
+3) Immediately set the transform expected after the first tick of motion
+
+The previous transform will be the starting position, and the current transform
+will act as though a tick of simulation has already taken place. This will
+immediately start moving the object, instead of having a tick delay standing still.
+
+.. important:: Make sure you set the transform and call
+               ``reset_physics_interpolation()`` in the correct order as shown
+               above, otherwise you will see unwanted "streaking".
+
+Testing and debugging tips
+--------------------------
+
+Even if you intend to run physics at 60 TPS, in order to thoroughly test your
+interpolation and get the smoothest gameplay, it is highly recommended to
+temporarily set the physics tick rate to a low value such as 10 TPS.
+
+The gameplay may not work perfectly, but it should enable you to more easily see
+cases where you should be calling :ref:`Node.reset_physics_interpolation<class_Node_method_reset_physics_interpolation>`,
+or where you should be using your own custom interpolation on e.g. a
+:ref:`Camera3D<class_Camera3D>`. Once you have these cases fixed, you can set the
+physics tick rate back to the desired setting.
+
+The other great advantage to testing at a low tick rate is you can often notice
+other game systems that are synchronized to the physics tick and creating glitches
+which you may want to work around. Typical examples include setting animation blend
+values, which you may decide to set in ``_process()`` and interpolate manually.