Interpolation(補間)¶
補間は、グラフィックプログラミングの非常に基本的な操作です。グラフィックス開発者としての視野を広げるために、これに慣れることは良いことです。
基本的な考え方は、AからBに移行することです。値 t
は、中間の状態を表します。
たとえば、t
が0の場合、状態はAです。t
が1の場合、状態はBです。中間はすべて補間です。
Between two real (floating-point) numbers, a simple interpolation is usually described as:
interpolation = A * (1 - t) + B * t
多くの場合、次のように簡略化されます:
interpolation = A + (B - A) * t
一定の速度で値を別の値に変換するこのタイプの補間の名前は"線形(linear)"です。したがって、線形補間について聞いたとき、あなたは彼らがこの単純な式を参照していることを知っています。
他のタイプの補間がありますが、ここでは説明しません。後で Bezier のページを読むことをお勧めします。
ベクトル補間¶
ベクトルタイプ(Vector2 および Vector3)も補間できます。それらはそれを行う便利な関数を備えています Vector2.linear_interpolate() および Vector3.linear_interpolate() です。
For cubic interpolation, there are also Vector2.cubic_interpolate() and Vector3.cubic_interpolate(), which do a Bezier style interpolation.
補間を使用してポイントAからBに移動するための簡単な擬似コードを次に示します:
var t = 0.0
func _physics_process(delta):
t += delta * 0.4
$Sprite.position = $A.position.linear_interpolate($B.position, t)
private float _t = 0.0f;
public override void _PhysicsProcess(float delta)
{
_t += delta * 0.4f;
Position2D a = GetNode<Position2D>("A");
Position2D b = GetNode<Position2D>("B");
Sprite sprite = GetNode<Sprite>("Sprite");
sprite.Position = a.Position.LinearInterpolate(b.Position, _t);
}
次のモーションを生成します:

幾何学変換(変形)の補間¶
また、変換全体を補間することもできます(使用するばあいは、均一なスケール、または少なくとも同じ非均一なスケールを持っていることを確認してください)。このために、関数 Transform.interpolate_with() を使用できます。
以下は、猿をPosition1からPosition2に変換する例です:

次の擬似コードを使用します:
var t = 0.0
func _physics_process(delta):
t += delta
$Monkey.transform = $Position1.transform.interpolate_with($Position2.transform, t)
private float _t = 0.0f;
public override void _PhysicsProcess(float delta)
{
_t += delta;
Position3D p1 = GetNode<Position3D>("Position1");
Position3D p2 = GetNode<Position3D>("Position2");
CSGMesh monkey = GetNode<CSGMesh>("Monkey");
monkey.Transform = p1.Transform.InterpolateWith(p2.Transform, _t);
}
また、次のモーションを生成します:

スムージングモーション¶
補間は、動きや回転などを滑らかにするために使用できます。これは、滑らかな動きを使用したマウスに追従する円の例です:
const FOLLOW_SPEED = 4.0
func _physics_process(delta):
var mouse_pos = get_local_mouse_position()
$Sprite.position = $Sprite.position.linear_interpolate(mouse_pos, delta * FOLLOW_SPEED)
private const float FollowSpeed = 4.0f;
public override void _PhysicsProcess(float delta)
{
Vector2 mousePos = GetLocalMousePosition();
Sprite sprite = GetNode<Sprite>("Sprite");
sprite.Position = sprite.Position.LinearInterpolate(mousePos, delta * FollowSpeed);
}
次の様に見えます:

これは、カメラの動きを滑らかにしたり、仲間を追いかけたり(一定範囲内にとどまるようにしたり)、その他多くの一般的なゲームパターンに役立ちます。