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 <1621768+aXu-AP@users.noreply.github.com>
This commit is contained in:
tetrapod00
2024-11-02 22:22:29 -07:00
parent 717d603073
commit 012f0b8a19

View File

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