|
@@ -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>`__.
|