はじめまして!
クリーク・アンド・リバー社 COYOTE 3DCG STUDIO テクニカルチーム所属の長谷川です。
これまでの「基礎編」では、Havok Clothの基本的なセットアップ方法について解説してきました。
今回から始まる応用編では、Havok Clothに加えて、Epic Games公式のRBF(Radial Basis Function)システムである「Pose Driver Connect」を併用し、モーションに応じたクロス挙動の補正や制御補間を行うことで、より安定かつ意図に沿ったクロス挙動を目指したセットアップをしていきます。
ぜひ最後までお付き合いください!
目次
※使用モデル
ワトソン・アメリアさん
※使用モーションデータ
博衣こよりさん /シアワセ√コヨリニウム © 2016 COVER Corp.
なぜRBFを使うのか
「基礎編」でも触れたとおり、Havok Cloth の Mesh to Mesh シミュレーションは、ベースとなるスキンメッシュの動きに依存して挙動を計算しています。
そのため、形状が複雑なパーツや、極端なポーズをとるようなキャラクターでは、
どれだけスキンウェイトを丁寧に調整しても、 シミュレーション時に意図しない崩れや破綻が発生するケースがあります。
こうした課題に対して、応用編では RBFを活用したHavok Clothの制御補助というアプローチを取っていきます。
まずは現状の挙動を確認し、どの部位に、どのような条件で、どのRBF制御を入れるべきかを精査するところから進めていきます。
理想的には、画像の青線のように、重力方向に素直に垂れるシルエットが望ましいのですが、
現状では、腕を前方に突き出したときや下げたときなどに、画像の赤線のようなシルエット崩れが生じやすくなっています。
これはポーズに応じてスキンメッシュが大きく変形し、それに連動してシミュレーション挙動も乱れてしまうためです。
そこで、画像で示したような箇所を中心に、「Pose Driver Connect」 を用いたRBF制御を加えていくことで、ポーズごとの挙動補正を行い、安定した見た目を保てるよう調整していきます。
今回作成するRBF
今回のセットアップでは、左右あわせておよそ10本程度の補助骨を新たに追加していきます。 各補助骨には、それぞれ異なる役割を持たせ、クロス挙動の安定とシルエット保持を両立させる構成を目指します。
「ArmTC」
目的: 腕の回転を打ち消すための補助骨。
「ArmCloth」
目的: 腕のシルエットを保つための補助骨。
「ForeArmCloth」
目的: 肘を曲げたときのシルエット補正用。
「ShoulderCloth」
目的: 腕を動かした際、肩付近がめり込むのを防ぐ補助骨です。
「SpineCloth」
目的: 腕を下げたときに胴体側がめり込むのを防ぐための補助骨。
こうして並べて見ると、まるで変形ロボットのような骨構造に見えるかもしれませんが、 今回は見た目の一貫性とクロスの安定性を優先して、贅沢に補助骨を使っていきます。
上腕の回転打ち消し
RBFの下準備
まずは、腕の回転を打ち消すためのジョイント(補助骨)を用意していきます。
RBF設定の下準備で特に大切なのは、最終的にどのような目的で使いたいかを明確にイメージしておくことです。
今回の場合では、クロスシミュレーションの起点となるベースのスキンメッシュ(Skin)が、ポーズによって不自然にねじれないようにするため、Armに対して新しくRBF用のジョイントを作成していきます。
各補助骨の位置にJointを生成する
ここでは主に 左腕(Left側)を例に説明を進めます。
まずは、「LeftArm」 を親として、同じ位置に 「RBF_LeftArmTC」 というジョイントを作成します。
Tips
ジョイントを選択した状態で、MELに joint と入力して実行(Enter)することで、選択中のジョイント位置に新しいジョイントを生成することができます。
作成したジョイントにウェイトを移す
次に、「LeftArm」 の持っているウェイトを 「RBF_LeftArmTC」 に移します。
今回は ngSkinTools2 を使用してウェイトのコピーを行いました。 執筆中にちょうど ngSkinTools2 がMayaに統合されるとの話を聞いてとても驚きました。
ngSkinTools2を起動し、Layerを作成したあとに
- ウェイトをコピーしたい元のジョイントを選択し、右クリック
- メニューから 「Copy Weights to Clipboard」 を選択
その後、貼り付けたいジョイントを選択し、新規Layerを作成して右クリック → 「Paste Weights」 を選ぶことで、貼り付けができます(置き換えや加算などの選択も可能です)。
なお、このジョイントをメッシュにバインドするのを忘れずに。
ngSkinTools2では、バインドしたいメッシュとジョイントを同時に選択した状態で、Tools → Add Influence を実行すれば、簡単に追加できます。
RBF設定時の考え方
RBF設定では、ひとつのジョイントに何でもかんでも担当させないことが安定性を保つために重要です。
ひとつの骨に複数のポーズを覚えさせようとすると、ポーズ同士が干渉して動きが不安定になるため、 今回は骨数に制限がない前提のもと、用途ごとにジョイントを細かく分けて設定しています。この設計により、処理も整理され意図した補正がしやすくなります。
RBFの設定
では実際に、RBFの設定に進んでいきます。
まず、現在の状態を確認してみましょう。
例を上げると下の用に腕を捻ったときに、RBFが設定されていない状態ではトップコートが不自然に引きずられてしまうのがわかります。
現状(RBFなし)
理想(RBFあり)
このままクロスを設定してしまうと、物理法則を無視して何かに引っ張られるような挙動になってしまうため、理想的な挙動に近づけるにはRBFによる補正が重要になります。
なお、この時点でアンダーコートが飛び出しているように見える部分については、今回の上腕の回転打ち消しではまだ気にしなくて大丈夫です。
この箇所は後ほどの「上腕周りの突き抜け回避」で改めて解説します。
Pose Driver Connect – PoseWranglerについて
RBFの設定に入る前に、「Pose Driver Connect」に付属している設定ツール「PoseWrangler」について解説していきます。
導入方法については、Epic Games公式のチュートリアルをご確認ください。
Authoring Secondary Animation in Maya and Unreal with Pose Driver Connect
正しく導入が完了していれば、以下のコマンドでPoseWranglerを起動できます。
from epic_pose_wrangler import main
pose_wrangler = main.PoseWrangler()
今回使用する主な機能は以下の通りです。
①RBF SOLVERS
RBFの作成、編集、削除などを行います。
②DRIVER TRANSFORMS
ドライバー(入力となるボーン)の追加や削除を行います。
③POSES
登録したポーズの管理、編集、削除を行います。
④DRIVENTRANSFORMS/BLENDSHAPES
ドリブン(出力となるボーンやブレンドシェイプ)の管理を行います。 ※ブレンドシェイプは今回は使用しません。
まずは、「LeftArm」(親となるボーン)に対して、回転軸それぞれに90、0、-90などの値を入れて動きを確認します。
今回は視認しやすくするため、100、0、-100といった大きめの値を使用していますが、
実際には現実的な可動域を考慮して、可動域にプラス30〜50程度の余裕をもたせると安定しやすくなります。
では、「Pose Wrangler」を使って実際の設定に入っていきましょう。
まず、「RBF SOLVERS」で「Create Solver」を実行します。
今回は、RBF対象となるジョイント名(例:RBF_LeftArmTC)をそのままSolver名として使用します。
注意点として、ドライバーを追加した時点でのポーズがPOSESの「default」として登録されるため、必ずバインドポーズ(初期姿勢)で登録してください。
また、ドライバーやドリブンはPOSESをいくつか登録すると追加できなくなることがあるため、初期登録の順序にも注意が必要です。
ドライバーは「LeftArm」、ドリブンは「RBF_LeftArmTC」とし、それぞれが初期位置にあることを確認してから追加します。
ポーズ登録
登録が完了したら、修正したいポーズをひとつずつ追加していきます。
まずはドライバーとなる「LeftArm」のジョイントを動かして、対象のポーズをとらせます。
たとえば、 Rotate X を100に設定します。
次に、ドリブンとなるRBF_LeftArmTCを操作して、回転を打ち消します。ここではRotate X を-100に設定します。
この状態で「Add Pose」を実行し、任意の名前を付けて保存します。
同様に、-100側のポーズも登録します。
それではこの状態でドライバーを動かしてみましょう
「RBF_LeftArmTC」のノードにRBFが接続されると、チャンネルボックスが黄色に変わっているのが確認できます。
ここでドライバーを動かしてみると…
動き出しが中途半端になってプルプルしてしまう現象が起こることがあります。
そこでもう一つの注意点です。
RBFをここまで設定したあとにRBFとして登録したジョイントに刺さっている
「~_UERBFSolver」の値を編集する必要があります。
「Radius」の初期値が45度の場合、補助骨はその範囲を超えてから動き始めるため、例えば100や-100のポーズを登録しても、動き始めるのは45度以降となってしまいます。
滑らかに補間させるためには、「Radius」に100を設定するか、「Automatic Radius」をオンにして自動調整させると良いです。
自動でも意図しない挙動をすることがあるため、動作確認は必ず行ってください。
効果の確認
実際にモーションを流して確認してみます。
左側には補助骨が入っており、右側には入っていない状態です。
見ての通り、RBFが入っていない側ではArmのウェイトに引っ張られてシルエットが崩れていますが、RBFを入れた側ではシルエットがきれいに保たれています。
ただし、登録したポーズの値(例:100〜-100)を超えると補助骨の動きが止まり、ポーズ同士の干渉が発生して元に戻るような動きになります。
そのため、もう少し大きな値を設定することで補完範囲を広げる必要があります。
コツとしては、想定よりも少し大きめの値を最初から学習させておくことです。
特に肩まわりや根元のように揺れが少ない部分では、シルエットを安定させることでHavok Clothの性能をより活かすことができます。
この補助骨は「打ち消し」が目的のため、めり込みや貫通などはこの段階ではそこまで気にせず、次のステップに進めていきます。
上腕周りの突き抜け回避
RBFの下準備
次に、腕をひねった際にアンダーコートが突き抜けてしまう問題への対策として、新たなRBFを作成していきます。
今回は、すでに設定済みの打ち消し骨 「RBF_LeftArmTC」 を親として、その子に 「RBF_LeftArmCloth 」を配置します。
動きを継承させるために、「RBF_LeftArmTC」 からウェイトをコピーしました。
ウェイトを移す際には、レイヤーを分けて作業すると、どこにどのような影響を与えているかが視覚的にわかりやすくなるためおすすめです。
今回、打ち消し骨(RBF_LeftArmTC)に直接ポーズを登録しない理由としては、
以前にも触れた通り、一つの骨に複数の役割を持たせるとポーズ同士が干渉し合い、意図しない動きにつながってしまうためです。
今回は骨数の制約がないため、打ち消し用の骨の子にRBFを追加することで、
元の動きを継承しつつ、新たな効果を加えることができます。
RBFの設定
まずは、実際に貫通が発生していたポーズに対応するよう、学習ポーズを2つ登録します。
1つ目のポーズでは、アンダーコートが少し斜めに突き抜けていたため、それに対して補助骨を少し斜め上方向に移動させています。
ジョイント移動前
ジョイント移動後
2つ目のポーズでは、真上方向への貫通に対し、同様に真上へジョイントを移動して補正しています。
ジョイント移動前
ジョイント移動後
左腕にはこの2つのポーズが適用されており、明らかに突き抜けが抑えられているのがわかります。
このように、まず基本的な問題箇所から順に対策を行い、必要に応じてポーズを追加していくというフローが基本となります。
今回のケースでは、最終的に合計8つのポーズを登録しました。
RBF未使用時
RBF適用後
腕を複数の方向にねじった場合でも、アンダーコートが飛び出さず、
自然なシルエットが保たれています。
また、腕を内側に向けた際に背中側の脇が突き抜けてしまう現象に対しても、
ポーズを追加して対応しています。
RBFが入っていない状態
RBFが入っている状態
以上のように、特定の問題箇所ごとに専用の補助骨とポーズを用意していくことで、シルエット崩れや貫通などの問題に対して効果的に対応できます。
肩の貫通回避
RBFの下準備
肩を上げた際に、襟元のメッシュが体に埋まってしまう問題を解消するために、RBFを追加していきます。
「Spine1」 をジョイントの親とし、RBFに登録するドライバーを 「Shoulder」 と設定します。
そのうえで、「Spine1」 の子として、左右それぞれに肩用の RBF ジョイントを追加します。
ここでは、元となる 「Spine1」 のウェイトをベースに、ngSkinTools2 を使って新しいジョイントへとウェイトを移していきます。
ただし、「Spine1」 のウェイトをそのままコピーしてしまうと胴体まで影響してしまうため、必要な箇所だけを抽出する形でウェイトの調整を行います。
まず、新規レイヤーを作成し、「Spine1」 のウェイトを新しい両肩ジョイントに半分ずつ貼り付けた状態にします。
そこからジョイントを動かしながら、ngSkinTools2 のマスク機能を使って、肩から腕にかけて大まかにマスクを塗っていきます。
マスクが一通り塗れたら、スムーズをかけて肩から腕へのウェイトのつながりを自然に整えていきます。
最終的には、以下のような自然な動きが出せれば理想的です。
RBFの設定
まず、RBFが未設定の状態では、腕を持ち上げた際に肩が外側にはみ出してしまっているのが確認できます。
この問題を解消するために、角度ごとに肩のジョイント位置を調整し、外観が破綻しないようにしたポーズを登録します。
合計で4つのポーズを登録しました。
登録後は、腕の角度に応じて肩が滑らかに動き、襟元の突き抜けが解消されているのが確認できます。
このように、肩の動きに合わせてジョイントを制御することで、衣服の自然な変形を保ちながらメッシュの貫通を抑えることが可能になります。
胴体の貫通回避
RBFの下準備
次は、腕を下げた際に胴体と衣服がめり込んでしまう現象に対応するためのRBFを設定していきます。
ここでは、「Spine1」 を親、「LeftArm」 をドライバーとして、「RBF_LeftSpineCloth」 というジョイントを追加します。
「肩の貫通回避」と同様に、ngSkinTools2 を使ってウェイトの調整を行います。
今回のケースでは、「腕を下げたときのみ反応してくれれば良い」ため、ベースとなる「Spine1」 からウェイトをコピーして調整しました。
赤が RBF_RightSpineCloth、緑が RBF_LeftSpineCloth です。
RBFの設定
まず、RBFが未設定の状態では、腕を下げたときに胴体側が大きく貫通してしまっているのが確認できます。
この問題に対しては、腕を下げた際にジョイントを横方向へ逃がすように移動させ、めり込みを防ぐ動きをRBFで登録していきます。
合計2つの学習ポーズを登録しました。
これで、補助骨の追加作業は一通り完了となります。
ここで、RBFや補助骨をセットアップしていない状態と、セットアップ済みの状態とを比較してみましょう。
まずは、ほぼバインドのみの状態。
そして、補助骨をすべて追加・RBF設定を行った状態。
比較してみると、動作全体を通してシルエットの安定性が大きく向上しているのがわかります。
今回はここまでで一区切りとし、
次回はHavok Clothブログ最終回、Havok Cloth設定編に進んでいきます!
※使用モデル
ワトソン・アメリアさん
※使用モーションデータ
博衣こよりさん /シアワセ√コヨリニウム © 2016 COVER Corp.