Procházet zdrojové kódy

Improve interpolation smoothing example

Improves explanation of interpolation ("lerp") smoothing.
Adds a note about framerate-independent version, with off-site links to
full explanations.

Co-Authored-By: aXu-AP <[email protected]>
tetrapod00 před 9 měsíci
rodič
revize
012f0b8a19
1 změnil soubory, kde provedl 48 přidání a 3 odebrání
  1. 48 3
      tutorials/math/interpolation.rst

+ 48 - 3
tutorials/math/interpolation.rst

@@ -3,7 +3,10 @@
 Interpolation
 =============
 
-Interpolation is a very basic operation in graphics programming. It's good to become familiar with it in order to expand your horizons as a graphics developer.
+Interpolation is a common operation in graphics programming, which is used to
+blend or transition between two values. Interpolation can also be used to smooth
+movement, rotation, etc. It's good to become familiar with it in order to expand
+your horizons as a game developer.
 
 The basic idea is that you want to transition from A to B. A value ``t``, represents the states in-between.
 
@@ -109,7 +112,11 @@ And again, it will produce the following motion:
 Smoothing motion
 ----------------
 
-Interpolation can be used to smooth movement, rotation, etc. Here is an example of a circle following the mouse using smoothed motion:
+Interpolation can be used to smoothly follow a moving target value, such as a
+position or a rotation. Each frame, ``lerp()`` moves the current value towards
+the target value by a fixed percentage of the remaining difference between the values.
+The current value will smoothly move towards the target, slowing down as it gets
+closer. Here is an example of a circle following the mouse using interpolation smoothing:
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -138,4 +145,42 @@ Here is how it looks:
 
 .. image:: img/interpolation_follow.gif
 
-This is useful for smoothing camera movement, allies following you (ensuring they stay within a certain range), and many other common game patterns.
+This is useful for smoothing camera movement, for allies following the player
+(ensuring they stay within a certain range), and for many other common game patterns.
+
+.. note::
+    Despite using ``delta``, the formula used above is framerate-dependent, because
+    the ``weight`` parameter of ``lerp()`` represents a *percentage* of the remaining
+    difference in values, not an *absolute amount to change*. In ``_physics_process()``,
+    this is usually fine because physics is expected to maintain a constant framerate,
+    and therefore ``delta`` is expected to remain constant.
+
+    For a framerate-independent version of interpolation smoothing that can also
+    be used in ``process()``, use the following formula instead:
+
+    .. tabs::
+        .. code-tab:: gdscript GDScript
+
+            const FOLLOW_SPEED = 4.0
+
+            func _process(delta):
+                var mouse_pos = get_local_mouse_position()
+                var weight = 1 - exp(-FOLLOW_SPEED * delta)
+                $Sprite2D.position = $Sprite2D.position.lerp(mouse_pos, weight)
+
+        .. code-tab:: csharp
+
+            private const float FollowSpeed = 4.0f;
+
+            public override void _Process(double delta)
+            {
+                Vector2 mousePos = GetLocalMousePosition();
+
+                Sprite2D sprite = GetNode<Sprite2D>("Sprite2D");
+                float weight = 1f - Mathf.Exp(-FollowSpeed * (float)delta);
+                sprite.Position = sprite.Position.Lerp(mousePos, weight);
+            }
+    
+    Deriving this formula is beyond the scope of this page. For an explanation, 
+    see `Improved Lerp Smoothing <https://www.gamedeveloper.com/programming/improved-lerp-smoothing->`__
+    or watch `Lerp smoothing is broken <https://www.youtube.com/watch?v=LSNQuFEDOyQ>`__.