This explanation is currently available in Japanese.
ひとことで
四元数(クォータニオン)で表した 2 つの回転の間を、最短の経路に沿って一定の角速度で補間する方法です。Spherical Linear intERPolation の略。キャラクターの向き、カメラの回転、アニメーションの姿勢ブレンドなど、「回転の途中」を求めるあらゆる場面で使われます。
ゲームでの使いどころ
- 向きの切り替え:キャラクターや砲塔、宇宙船が目標の方向へ振り向く動き。
- アニメーションのブレンド:歩きと走りのように 2 つのアニメーションを混ぜるとき、各ボーンの回転を slerp(または nlerp)します。
- カメラの補間:カットシーンのキーフレーム間でカメラの向きを補間する。
- 物理・ネットワーク:受信した姿勢の間を補間して、回転を滑らかに再生する。
しくみ
オイラー角(x, y, z 軸まわりの角度)をそれぞれ線形補間すると、3 つの回転が別々に進むため、先端が遠回りの経路を描き、途中で不自然なねじれが起きます(デモの赤い経路)。ジンバルロックの問題もあります。
単位四元数 は 4 次元の単位球面上の点として回転を表します。slerp はこの球面上の大円に沿って補間します。
- 最短経路: と は同じ回転を表します。内積 が負なら の符号を反転してから補間しないと、遠回り(360° − 角度)の回転になります。
- 一定の角速度: を一定に進めると、回転角も一定に進みます。
nlerp(正規化線形補間)は、4 成分を線形補間してから正規化するだけの安価な近似です。経路は slerp と同じ大円ですが、角速度が一定ではなく、中央が速く端が遅くなります。2 つの回転の差が小さい場合(アニメーションのブレンドなど)はほぼ区別がつかず、計算も速く、複数の回転を平均するのにも向くため、実務ではよく使われます。
実装のポイント
- 符号の反転:three.js の
slerpは内部で内積の符号をチェックして最短経路を選びます。自作する場合は忘れずに。 - 角度がほぼ 0 のとき: で割り算が不安定になるため、差が小さいときは nlerp に切り替えます。
- 一定速度で振り向く:目標までの角度に関係なく「毎秒 180°」で回したいときは、
rotateTowards(target, maxStep)のような最大角度制限つきの回転を使います。
つまずきやすい点
- オイラー角のまま補間する:エディタの数値がオイラー角でも、補間は四元数に変換してから行います。
- 180° 付近の回転:2 つの回転がちょうど反対向きに近いと、最短経路が一意に決まらず、わずかな差で回る方向が反転します。演出上どちら回りかを決めたい場合は中間のキーを追加します。
- スケールや位置は別扱い:slerp は回転専用です。位置は Lerp、スケールは Lerp(または対数空間での補間)で別に補間します。
デモで試すこと
- 宇宙船の補間方法を切り替え、先端の経路を比べてください。赤(オイラー角)は大きく遠回りし、黄(nlerp)と水色(slerp)は同じ最短経路を通ります。
- 球面上の点は を 1/12 ずつ進めた位置です。水色の点だけが等間隔に並び、黄色は中央でまばら、端で密になっています。
- 「新しい目標の向き」を何度か押し、角度が大きいほど 3 つの違いが大きくなることを確認してください。