interpolation.rst 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. .. _doc_interpolation:
  2. Interpolation
  3. =============
  4. 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.
  5. The basic idea is that you want to transition from A to B. A value ``t``, represents the states in-between.
  6. For example, if ``t`` is 0, then the state is A. If ``t`` is 1, then the state is B. Anything in-between is an *interpolation*.
  7. Between two real (floating-point) numbers, an interpolation can be described as:
  8. ::
  9. interpolation = A * (1 - t) + B * t
  10. And often simplified to:
  11. ::
  12. interpolation = A + (B - A) * t
  13. The name of this type of interpolation, which transforms a value into another at *constant speed* is *"linear"*. So, when you hear about *Linear Interpolation*, you know they are referring to this formula.
  14. There are other types of interpolations, which will not be covered here. A recommended read afterwards is the :ref:`Bezier <doc_beziers_and_curves>` page.
  15. Vector interpolation
  16. --------------------
  17. Vector types (:ref:`Vector2 <class_Vector2>` and :ref:`Vector3 <class_Vector3>`) can also be interpolated, they come with handy functions to do it
  18. :ref:`Vector2.lerp() <class_Vector2_method_lerp>` and :ref:`Vector3.lerp() <class_Vector3_method_lerp>`.
  19. For cubic interpolation, there are also :ref:`Vector2.cubic_interpolate() <class_Vector2_method_cubic_interpolate>` and :ref:`Vector3.cubic_interpolate() <class_Vector3_method_cubic_interpolate>`, which do a :ref:`Bezier <doc_beziers_and_curves>` style interpolation.
  20. Here is example pseudo-code for going from point A to B using interpolation:
  21. .. tabs::
  22. .. code-tab:: gdscript GDScript
  23. var t = 0.0
  24. func _physics_process(delta):
  25. t += delta * 0.4
  26. $Sprite2D.position = $A.position.lerp($B.position, t)
  27. .. code-tab:: csharp
  28. private float _t = 0.0f;
  29. public override void _PhysicsProcess(double delta)
  30. {
  31. _t += (float)delta * 0.4f;
  32. Marker2D a = GetNode<Marker2D>("A");
  33. Marker2D b = GetNode<Marker2D>("B");
  34. Sprite2D sprite = GetNode<Sprite2D>("Sprite2D");
  35. sprite.Position = a.Position.Lerp(b.Position, _t);
  36. }
  37. It will produce the following motion:
  38. .. image:: img/interpolation_vector.gif
  39. Transform interpolation
  40. -----------------------
  41. It is also possible to interpolate whole transforms (make sure they have either uniform scale or, at least, the same non-uniform scale).
  42. For this, the function :ref:`Transform3D.interpolate_with() <class_Transform3D_method_interpolate_with>` can be used.
  43. Here is an example of transforming a monkey from Position1 to Position2:
  44. .. image:: img/interpolation_positions.png
  45. Using the following pseudocode:
  46. .. tabs::
  47. .. code-tab:: gdscript GDScript
  48. var t = 0.0
  49. func _physics_process(delta):
  50. t += delta
  51. $Monkey.transform = $Position1.transform.interpolate_with($Position2.transform, t)
  52. .. code-tab:: csharp
  53. private float _t = 0.0f;
  54. public override void _PhysicsProcess(double delta)
  55. {
  56. _t += (float)delta;
  57. Marker3D p1 = GetNode<Marker3D>("Position1");
  58. Marker3D p2 = GetNode<Marker3D>("Position2");
  59. CSGMesh3D monkey = GetNode<CSGMesh3D>("Monkey");
  60. monkey.Transform = p1.Transform.InterpolateWith(p2.Transform, _t);
  61. }
  62. And again, it will produce the following motion:
  63. .. image:: img/interpolation_monkey.gif
  64. Smoothing motion
  65. ----------------
  66. Interpolation can be used to smooth movement, rotation, etc. Here is an example of a circle following the mouse using smoothed motion:
  67. .. tabs::
  68. .. code-tab:: gdscript GDScript
  69. const FOLLOW_SPEED = 4.0
  70. func _physics_process(delta):
  71. var mouse_pos = get_local_mouse_position()
  72. $Sprite2D.position = $Sprite2D.position.lerp(mouse_pos, delta * FOLLOW_SPEED)
  73. .. code-tab:: csharp
  74. private const float FollowSpeed = 4.0f;
  75. public override void _PhysicsProcess(double delta)
  76. {
  77. Vector2 mousePos = GetLocalMousePosition();
  78. Sprite2D sprite = GetNode<Sprite2D>("Sprite2D");
  79. sprite.Position = sprite.Position.Lerp(mousePos, (float)delta * FollowSpeed);
  80. }
  81. Here is how it looks:
  82. .. image:: img/interpolation_follow.gif
  83. This useful for smoothing camera movement, allies following you (ensuring they stay within a certain range), and many other common game patterns.