Inverse Kinematicsを用いたキャラクターの姿勢操作
概要
本記事ではキャラクターアニメーションにおいて重要なInverse Kinematics(IK)について紹介します。自分の学習用に執筆したため、一部間違い等が存在する可能性がございます。何かございましたらご一報いただけると幸いです。
Deep Learningでキャラクターアニメーションを扱う際に、前処理・後処理用のPythonスクリプトを書いているので、foot skatingの修正用などに簡単なInverse Kinematicsアルゴリズムを書きました。この記事の3D Plotはこちらで実装しています。今後Jacobianを用いたFullbody IKなども実装予定です。
Inverse Kinematics(IK)とは
人間などのキャラクターにおける姿勢は、初期姿勢とそれを基準とした回転情報から記述されることが多いです。キャラクターの関節位置を直接制御すると、骨の長さが伸びてしまうなど問題が発生してしまうためです。
キャラクターモーションの記述子(bvhファイルなど)では以下図のように、ROOT(腰骨など)を基準として末端に向かって骨の親子関係が存在します。親の回転は子の回転にも影響します。
このルールに従い、初期姿勢の関節を回転させて各関節位置を求めることを Forward Kinematics(FK) と呼びます。FKは全ての関節回転を用いることで一意に結果が定まります。
このような関係から、キャラクターに任意の姿勢をとらせるためには、各関節の適切な回転情報を入力する必要があります。しかし直線的に手を動かすアニメーション等を作成する場合、直接位置を指定できたほうが扱いやすいです。この問題に対処するために、目標位置からそこへ到達するまでの関節回転を求めることを Inverse Kinematics(IK) と呼びます。これらの用語はロボット分野で生まれました。
上の図では2次元上での例を示していますが、3次元でも同様の考えを用います。IKは一般に無数の解を持つことが多く、解析的に解くことができない場合が存在します。そのため、今日まで複数の解法が提案されてきました。ここでは簡単なIKの例を紹介します。
IKの解法
[5]によるとIKは大きく分けて、解析的(analytical)解法、数値的(numerical)解法、データ駆動型(data-driven)解法、hybrid(これらを組み合わせた総合的解法)に分けることが可能です(もしかしたらサーベイ論文に載っていないグループもあるかもしれません)。これらの詳細はまた機会があれば紹介します。ここでは簡単な例のみを紹介するため、解析的な解法としてtwo bone IKを、数値的解法としてCCD IK、FABRIKを取り扱います。
Two bone IK
キャラクターの脚の滑り修正などに使用されるIKです。脚に使用する場合、股関節を固定して、膝と踵の関節によって構成される2本の骨を用いる場合が多いです。次章の実装では膝の前方向ベクトルと踵の位置を入力として、解析的に股関節の回転と膝の回転を求める方法を紹介します。Fullbody IKなどで修正する場合には他の解法が必要になりますが、簡易的な操作であればこちらで十分です。詳細な説明は[7]をご参照ください。
CCD IK
CCD IKはCyclic Coordinate Descent Inverse Kinematicsの略で、ベースとなる関節位置を固定して反復的に関節回転を更新する手法です。
上図のように末端側の関節から順に、effectorがtargetに近づくよう回転させていきます。この手法は着実にtargetへと近づけることができ、effector-target間の距離が閾値以下になる、もしくは指定したイテレーションに達するまで上図の処理を繰り返し行います。
FABRIK
FABRIKはForward And Backward Reaching Inverse Kinematicsの略で、backword reaching、forward reachingという2つのステップを繰り返す手法です。
上図はもととなった論文[4]のものを用いています。Backward reachingでは末端のJointから位置を合わせて、それぞれの関節位置を更新していきます。この際、関節間距離が保たれるように処理を行いますが、根本の位置も変更されます。続いて根本からbackward reachingと同様の処理を行うことで根本の位置が合うようにしながら調整していきます。これをforward reachingと呼び、CCDと同様の条件に達するまで繰り返し処理を行います。
実装
今回は基本として、枝分かれのない骨格構造を用いたCCD IK、FABRIK、two bone IKを実装しました。ページ上部に載せたリポジトリのanim/animation.py
に記したAnimationクラスを用いて処理を行っています。このクラスでは下のように各関節を定義し、これらのリストで関節構造をまとめ、動的な部分(回転と移動)のみAnimationクラスで処理しています。
Two bone IK
ここではfoot IKを想定して簡単な脚モデルを使用しました。青い方が初期姿勢、橙の方が処理後の姿勢となっています。このIKでは股関節、膝、踵で結ばれる三角形において、踵の位置と膝の向きを指定します。上の実装では、targetによって踵の位置を指定し、fwdによって膝の方向(ノルム1のベクトル)を指定することでIKを行います。解析的に解が求まるため、非常に軽量コストで計算することができます。
CCD IK
青で書かれたorigを初期値として、末端がtargetに到達するようにCCD IKを行った結果が上図のようになります。イテレーション回数は10回で試してみましたが、少しずれが生じているように見えます。
FABRIK
CCD IKと同じ条件でFABRIKを計算した結果が上図になります。回転を用いたFABRIKの実装方法がよく分からなかったため、各処理において位置を導出した後、その方向へ向けるための回転をかけることによって、回転を求めました。このあたりについて詳しい方がいらっしゃれば、教えていただけると幸いです。
上の結果ではCCD IKよりも、末端がtargetに近づいていることがわかります。
参考資料
本記事作成にあたり、以下の資料を参考にさせていただきました。
CCD IK and Particle IK - Tomohiko Mukai, 2014
1.こちらから参照できます。
都立大の向井先生が執筆されたCCD IK等の記事です。その他のIK記事に関してもSimple Two Joint IK - Daniel Holden, 2017
2.深層学習をキャラクターアニメーションに応用させた先駆者として有名な、Daniel Holden氏が執筆されたtwo bone IKの記事です。本実装のtwo bone IK部分はこちらを参考にしています。
Motion-Matching - Daniel Holden, 2021
3.Learned Motion Matchingという深層学習を用いたmotion matchingの実装も行われています。本実装における回転の計算はこちらのリポジトリを参考にしております。Pythonの3次元回転計算ではscipy.spatial.transform.Rotation
やPyTorch3D
も存在しますが、処理が複雑だったので使用しませんでした。また、quaternionsでの回転計算は4×4の行列や回転行列よりも次元が少なく、効率が良いです。
FABRIK: A fast, iterative solver for the Inverse Kinematics problem - Andreas Aristidou et al., 2011
4.FABRIKのもととなった論文です。
Inverse Kinematics Techniques in Computer Graphics: A Survey - Andreas Aristidou et al., 2017
5.[4]の著者らによるIKサーベイ論文です。
Inverse Kinematicsについて - SEGA TECH Blog, 2022
6.Two bone IKなど簡単な解析解について、数式を用いた分かりやすい説明がされています。
Discussion
FABRIKの論文の画像を無断転載しているようですが、大丈夫ですか?
2011 Elsevier Inc. All rights reserved.とあるので無断転載不可だと思います。
しかるべきところに通報しました。