発展資料 ボーン階層とスキニング変換
この資料で扱う内容
- 親子階層でローカル変換が連結される仕組みを理解する
- バインドポーズと現在のボーン姿勢の役割を整理する
- 複数ボーンの変換をウェイトで混ぜる考え方を理解する
- スキニングとシェーダーによる頂点変形を比較する
- 変形後の座標空間と法線を意識してShader Graphを組む
- 頂点がどの基準からどの基準へ移されるかを追う
Transform階層
座標変換の確認
前回は、頂点が Object Space から World Space、View Space、Clip Space へ変換される流れを扱いました
今回扱うボーンにも、それぞれ位置、回転、スケールがあります
ボーンを親子関係でつなぐと、子の変換には親の変換が順番に適用されます
親から子へ変換を連鎖する
次のような左腕の階層を考えます
CharacterRoot
Hips
Spine
Shoulder_L
UpperArm_L
LowerArm_L
Hand_LHand_L のローカル座標が変わらなくても、Shoulder_L を回転させれば手は移動します
これは手のワールド変換に、肩、上腕、前腕、手のローカル変換がすべて含まれるためです
列ベクトルを使う表記では、子ボーンのワールド行列を次のように表せます
階層全体では、親から子までの行列を順に掛け合わせます
行列の表記規則は環境によって異なることがあります
重要なのは、親の変換を受けた空間へ子のローカル変換を重ねるという関係です
部位ごとに基準を持つ
- 手は前腕を基準に配置できる
- 前腕は上腕を基準に回転できる
- 上腕は肩を基準に動かせる
- 肩より上位の胸や腰を動かすと、腕全体が追従する
- アニメーターは各部位を、その親に対するローカルな姿勢として編集できる
すべてのボーンを直接 World Space で制御すると、親を動かすたびに全ての子の位置を再計算する必要があります
階層を使えば、部位のつながりを変換の連鎖として表せます
スキニング変換
頂点とボーンの基準となるバインドポーズ
Bind Pose は、メッシュをボーンへ関連づけたときの基準姿勢です
一般的な人型モデルでは T ポーズや A ポーズが使われますが、ポーズの形そのものより、メッシュと各ボーンの対応が保存されていることが重要です
スキニングでは、頂点を現在のボーン姿勢へそのまま変換するだけでは正しい位置になりません
まずバインド時のボーン変換を打ち消し、その後に現在のボーン変換を適用します
1本のボーンだけから影響を受ける頂点は、概念的に次の式で変換できます
はバインド姿勢の頂点位置です はバインド時の変換を打ち消す逆行列です は現在姿勢のボーン変換です は変形後の頂点位置です
適用した変換を戻す逆行列
逆行列は、ある変換を打ち消す行列です
I は何も変換しない単位行列です
例えば、位置を右へ2移動する変換の逆は、左へ2移動する変換です
回転やスケールも、逆行列を使って元の基準へ戻せます
バインドポーズの逆行列によって、頂点をバインド時のボーン空間へ戻してから、現在のボーン姿勢へ移します
複数ボーンの結果を混ぜるボーンウェイト
関節付近の頂点を1本のボーンだけで変形すると、曲げた部分が固く折れて見えます
そこで、1つの頂点に複数のボーンとウェイトを割り当てます
2本のボーンから影響を受ける場合は、各ボーンで変換した頂点位置をウェイトで混ぜます
通常、ウェイトの合計は1になるように扱います
| 頂点の場所 | 上腕ウェイト | 前腕ウェイト | 変形の傾向 |
|---|---|---|---|
| 上腕中央 | 1.0 | 0.0 | 上腕に追従する |
| 肘の上腕側 | 0.75 | 0.25 | 主に上腕へ追従する |
| 肘中央 | 0.5 | 0.5 | 両方の変換が混ざる |
| 肘の前腕側 | 0.25 | 0.75 | 主に前腕へ追従する |
| 前腕中央 | 0.0 | 1.0 | 前腕に追従する |
変換結果を加算するLinear Blend Skinning
複数ボーンによる変換結果を線形補間する方法を Linear Blend Skinning と呼びます
- 計算が比較的単純で高速です
- 多くのリアルタイムキャラクターで基本となる方法です
- ウェイトを滑らかに塗ることで、関節の曲がりを滑らかに見せられます
- 強くねじると体積が減ったように見えるなど、線形補間に由来する限界があります
- 補助ボーン、ウェイト調整、ブレンドシェイプなどで問題を補うことがあります
頂点シェーダーと組み合わせる
スキニングと頂点シェーダーの違い
| 観点 | スキニング | Shader Graph の頂点変形 |
|---|---|---|
| 主な入力 | ボーン姿勢、バインドポーズ、ウェイト | 位置、法線、時間、テクスチャー、プロパティ |
| 主な目的 | 骨格アニメーションに沿った変形 | 揺れ、膨張、波、ディゾルブ連動など |
| 変形の基準 | ボーンごとの座標変換 | 選択した座標空間と計算式 |
| 得意な表現 | 関節を持つキャラクター | 規則的、連続的、手続き的な変形 |
| 制御方法 | アニメーションとウェイト | シェーダーの数値とノード |
キャラクターへ頂点変形シェーダーを適用すると、ボーンによる変形に加えて、シェーダー側の変位も加わります
例えば、アニメーションするキャラクターの表面を法線方向へ少し膨らませ、呼吸やエネルギーの脈動を表現できます
空間によって変わる変形順序
次の2つは同じ結果になりません
A: Object Space で上方向へ変位 -> ボーンとオブジェクトの変換
B: ボーンとオブジェクトの変換 -> World Space で上方向へ変位- Object Space の上方向は、モデルの回転に追従します
- World Space の上方向は、シーン全体の上方向に固定されます
- 法線方向の変位は、表面から外側へ膨らむ表現に向いています
- 風で揺らす場合は、ワールド方向と頂点のマスクを組み合わせることがあります
どの段階で変形しているか分からなくなった場合は、入力位置、変位ベクトル、出力位置の座標空間をそれぞれ確認します
法線も変換する
- 法線は表面の向きを表す方向ベクトルです
- 頂点を大きく変形すると、元の法線が変形後の表面と一致しなくなることがあります
- 法線が不正確だと、ライトの当たり方やフレネルが不自然になります
- 一様でないスケールを含む変換では、位置と同じ行列をそのまま法線へ使えません
- Shader Graph で小さな変位を加えるだけなら元の法線でも目立たない場合がありますが、大きく変形する場合は法線の再計算方法も検討します
実習:スキニング変換を確認する
実習1:Transform階層の変換連鎖を確認する
- 空の GameObject を3つ作り、
Root > Arm > Handの親子関係にする ArmとHandのローカル位置を X 方向へずらすRoot、Arm、Handを順に回転し、子がどの基準で動くか確認する- Inspector のローカル位置と、Scene ビューでのワールド位置を比較する
- 親を回転しても子のローカル位置が変わらないことを確認する
実習2:ボーンウェイトによる補間を観察する
- ボーンを表示できるスキンメッシュをシーンへ配置する
- 肘や膝を曲げるアニメーションを再生する
- 関節中央と、その両側にある頂点の動きを比較する
- ウェイトを確認できる場合は、2本のボーンの影響が切り替わる範囲を見る
- 1本のボーンだけに追従した場合の形を想像し、現在の変形と比較する
実習3:スキンメッシュへShader Graphの頂点変形を追加する
- 第10回で使用したスキンメッシュ対応の Shader Graph を複製する
- Vertex の
Positionへ小さな変位を加える Normal Vectorと時間変化する値を使い、表面を弱く脈動させる- 変位量をプロパティにし、
0に戻せるようにする - アニメーションを再生し、ボーン変形と頂点変形が両方反映されることを確認する
- 変位を強くして破綻する条件を確認した後、形が読み取れる値へ戻す
実習4:Object SpaceとWorld Spaceの変位を比較する
- Object Space の一定方向へ頂点を変位させる
- 同じ大きさの変位を World Space の一定方向で作る
- キャラクターの GameObject を回転する
- 変位方向がキャラクターに追従するか、ワールドに固定されるかを比較する
- どちらが目的の表現に適しているか説明する
授業内課題:ボーン変形とシェーダー頂点変形を比較する
アニメーションするスキンメッシュに、調整可能な頂点変形を1つ追加します
完成条件
SkinnedMeshRendererを持つモデルへ Shader Graph のマテリアルを適用している- ボーンアニメーションが再生された状態で表示できる
- 法線方向、Object Space の一定方向、World Space の一定方向のいずれかへ頂点を変位させている
- 変位量を Shader Graph のプロパティで調整できる
- 変位量
0の状態と、変位を加えた状態を比較できる - 使用した変位ベクトルの座標空間を説明できる
- スクリーンショットまたは短い動画で提出する
提出時の説明
- 使用したモデルとアニメーション
- どの方向へ頂点を変位させたか
- 変位の計算に使用した座標空間
- ボーン変形とシェーダー変形が、それぞれ見た目のどの部分を作っているか
- 変位量を強くしたときに起きた問題と、最終的な調整値
よくある問題
| 問題 | 確認する場所 |
|---|---|
| モデルが動かない | Animator、Animation Clip、Avatar、再生状態 |
| マテリアルを替えると形が崩れる | Shader Graph の対象、Vertex Position の接続、座標空間 |
| 変位方向が回転に追従しない | Object Space と World Space の選択 |
| 関節だけ不自然に伸びる | ボーンウェイト、変位量、使用する頂点マスク |
| 表面の明るさが不自然 | 法線の Space、変形量、非一様スケール |
| 画面外へ出ると止まる、消える | Skinned Mesh Renderer とエフェクトの Bounds |
この資料の到達目標
- 親子階層でローカル変換が連結される仕組みを説明できる
- バインドポーズの逆変換と現在のボーン変換の役割を説明できる
- 複数ボーンの変形結果をウェイトで混ぜる考え方を説明できる
- スキニングと手続き的な頂点変形の違いを説明できる
- 頂点変形に使う方向の座標空間を選び、結果を比較できる
まとめ
- 子ボーンのワールド変換は、親から子までのローカル変換を連結して求めます
- バインドポーズの逆行列で基準姿勢を打ち消し、現在のボーン変換を適用します
- 関節付近では、複数ボーンの変形結果をウェイト付きで加算します
- Shader Graph の頂点変形は、スキニングに追加する手続き的な変形として利用できます
- 変位の方向と計算対象は、同じ座標空間へそろえる必要があります
- 見た目が崩れたときは、頂点がどの空間からどの空間へ変換されているかを順に追うことが重要です