チュートリアル / Bifrost for Maya Rigging Challenge~一歩先のリグ・アニメーションに挑戦~
第9回:Bifrost Rigging でカスタムモジュールを作る
- Maya
- アニメ
- キャラクター・リグ
- ゲーム
- コラム
- シミュレーション
- チュートリアル
- 上級者
- 中級者
- 映画・TV
みなさん、こんにちは。
本コラムではMayaのプラグイン"Bifrost"を使って、リグ、アニメーション、物理シミュレーションなどの観点から作例を紹介していきます。今回は「Bifrost Rigging」で自作のモジュールを作ってみたいと思います。
成果物は以下の通りです。
【環境】
・Windows 11
・Maya 2026.2
・Bifrost 2.15.0.0
※Maya 2026.2 にバンドルされているBifrostのバージョンは2.14.1.0になります。2.15.0.0を使うには下記リンクよりBifrost単体のインストーラーを取得して更新する必要があります。
https://manage.autodesk.com/products/updates
Bifrostリギングモジュールフレームワークとは
Bifrostリギングモジュールフレームワークとは、バージョン2.14より新たに追加されたBifrost駆動のモジュラーリギングシステムです。プロシージャルかつモジュールが特徴で拡張性、再利用性の高いシステムとなっているとのことです。Maya Learning Channelにて非常に分かりやすい動画が全7本公開されていますので、まずはこちらに目を通しておいていただけるとよりスムーズに進められるかと思います。特にPart3はカスタムモジュールを作成する手順が1本にまとまっており非常に重要です。本記事はこの動画シリーズと公式ヘルプをベースにしている部分が多々あります。
・Featured - Bifrost Rigging - YouTube
・Maya ヘルプ | Bifrost リギング モジュール フレームワーク
リギングモジュールフレームワークの概要
まずはBifrostのリギングモジュールが従来のMaya標準ノードのみを使ったリグとどのように置き換わるのか各工程で比較してみます。以下の図は『骨を配置してメッシュをバインドし、コントローラを作成したら何らかのギミックを介して骨を制御』という工程を簡単に示したものです。
赤線で囲ったバインド以外の部分がBifrostグラフのモジュールでプロシージャル(非破壊的)に構築されることになります。スキンバインドはBifrostの外側にあるため破壊的ですが、skinClusterのbindPreMatrixというアトリビュートを利用することで初期ポーズが変更可能な状態にできます。これについては後半で詳しく触れていきます。
第1回『両端を固定し長さが保てるベルトのリグ』おさらい
今回はリギングモジュールのお試しということで、第1回で作成した「両端を固定し長さが保てるリグ」をモジュールに転用してみたいと思います。
まずは第1回の要素をおさらいします。
・複数の点(第1回の時は7点)に距離の制約をかける
・両端の2点は固定、中間の点はフリーに
・複数の制約を満たすよう反復計算を行う
・各点の位置を元に回転値を計算
最終的なグラフは以下のようになっています。これは第1回の配布データ「distance_constraint_rig.ma」のグラフです。
グラフの入力は、各コントローラのworldMatrix、各ジョイントの初期位置、反復回数。出力は、各ジョイントの位置と回転になっています。点の数は7点固定です。まずはリギングモジュールに入る前に、このグラフ全体を、"ジョイント数が可変"かつ"入出力がMatrix配列(array<Math::double4x4>)"となるよう改変していきます。double型にする理由はリギングモジュールの設計に適合しやすく都合が良いからです。
まず元のグラフのiterate内部を見てみます。7つの位置とその間の距離を受け取り、距離制約6つの計算を終えた後、両端を除く5点について平均位置を計算しています。同じ計算を複数並べていて少々無駄なので、配列で可変長にできるよう組みなおします。
ここから先は組み直したグラフです。姿勢を収束させるための全体の反復計算(calc_position_iterate)の中にさらに位置配列を端から順に処理するiterateを作ります。各点は2つの距離制約により一度2つの位置データに分かれるので、保管用の変数(position_buffer_1, position_buffer_2)に格納しておき、その後まとめてaverage_positionコンパウンドを通して平均位置をとることにします。
位置の計算が終わった後、点の位置とコントローラを入力としてエイムによって回転値を求める部分についても同様に、配列で対応できるように組み直します。
最後に、全体を「strap」という名前のコンパウンドでまとめます。入出力が配列になり、スッキリまとまりました!
動作結果も問題なく第1回と同じになっていそうです!
ここまではまだグラフを整理しただけで、リギングモジュールは一切関係のない状態です。次項よりカスタムモジュール化していこうと思います。
カスタムモジュールを組んでみる
前項と同じシーン(distance_constraint_rig_v2.ma)のまま作業を続行します。まずは新しいBifrostGraphにて「template_module」を作成し、右クリック > Make Editable で編集可能な状態にします。複数用意されているモジュールのうち template_module はグラフを改変してカスタムモジュールを自作するための雛形になっています。
template_module の入出力ポートをどこかへ接続する前に、デフォルトのPin(*1)を設定しておきます。制御点の数は可変にする予定ですが、ひとまず初期値として7点(point0~6)のPinと、反復回数などを操作するオプションコントローラ(ui)用のPinを用意しておきます。Parameter EditorよりInputs > Setup > Pins の [+] ボタンを押して、Name や Pivot Matrix を入力していきます。
*1) Pin:コントローラやジョイントの初期姿勢を定義するためのガイドトランスフォームです。Pinを始点にリグの生成からアニメーションまでがプロシージャルに構築されることになります。
Pinは下記のようにvnnコマンドを使って効率よく設定することもできます。
# bifrostGraphShape2 の template_module へ pinを追加するサンプル
from maya import cmds
pin_mtx = []
# ui
pin_mtx.append(f'ui, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1')
# point x 7
for i in range(7):
t = [0, (i+1)*5, 0]
pin_mtx.append(f'point{i}, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, {t[0]}, {t[1]}, {t[2]}, 1')
inputs_value = '{{' + ', '.join(pin_mtx) + '}, , {}, {}, {}, {}, {}, {}, , 0, 0}'
cmds.vnnNode(
'bifrostGraphShape2',
'/template_module',
setPortDefaultValues=["inputs", inputs_value]
)
Pinsの初期値入力ができたら、root_moduleを追加作成して下記のように繋ぎます。これでinputsとoutputsがMaya側に公開され、BifrostRigをビルドする準備が整いました。
一度Mayaビューポートに戻り、RiggingメニューバーのBifrost Rigging > Create Rig From Modulesオプションを開いたら、以下のように Synced Container にチェックを入れ、Setup Methodは native でリグを作成してみます。
うまくいけばbifrostRigというノードが作られ、その子階層にpinsやcontrolsなどの構成要素が生成されると思います。ただし、コントローラやジョイントはrootモジュールのぶんしか作られていません。今はまだtemplate_moduleの中身が空っぽだからです。これから、template_moduleのグラフ内にコントローラなどの定義を追加していきます。
template_moduleの内部を見るとすでに多くのグラフが組まれていますが、編集すべきところは下記の2箇所の赤い部分だけです。左側のUser Setupはコントローラやジョイントの階層を作成し初期状態を定義する領域、右側のUser Animationはリグのギミックを作成しトランスフォームを更新する領域になります。これ以外のコンパウンドは特に見る必要はありません。
コントローラとジョイントの定義
ではまずは左側の user_setup コンパウンドの内部で、コントローラとジョイントを定義していきます。いったん最小構成として、グラフは以下のようになりました。ここでやっていることは、『PinのMatrixと親のコントローラやジョイントを取得し、それらの情報を使ってこのモジュールに必要なコントローラとジョイントを複数作成する』ところまでです。uiコントローラには “iteration” アトリビュートも追加してあります。
ここまで組めたところで一度ビューポートへ戻ってみると、グラフ内で定義したコントローラとジョイント階層がすでにMayaのノードとして作られていることがわかります。これは先ほどリグを作成する際に Synced Container オプションによりルートノードがbifrostRiggingContainerになるよう設定していたためです。このコンテナのAuto Update(*2) が有効になっているとモジュール内の変更が自動的に反映され、リグが再構築されるようになります。
*2) Auto Update:グラフ内でモジュールを改変する時にのみ有効にすべきオプションです。コントローラを操作する際には無効にする必要があります。
一度 Auto Update をオフにし、pins階層下のロケーターを動かすと、各コントローラやジョイントの初期位置を変更できます。コントローラも操作可能な状態になっていますが、現状はuser_setupにてコントローラとジョイントをそれぞれ作成しただけですので、操作したところでジョイントはまだ動きません。
リグのギミックを定義
ではここから、右側の赤色領域にある user_animation コンパウンドの内部でリグのギミック本体を定義していきます。グラフは以下のようになりました。こちらでやっていることは、『コントローラやジョイントのtransformやアトリビュートを取得し、strapコンパウンドによりジョイントの姿勢を更新する』ところまでです。前項で第1回のグラフを改造して作った“strapコンパウンド”がここで登場しています。
再度Mayaのビューポートへ戻ってみます。bifrostRigのAuto Updateを有効にしてリグの再構築を促し、その後すぐ無効にしてコントローラを動かしてみます。今度はジョイントが動くはずです。
この時点で動作的な問題はないのですが、strapコンパウンド内のエイムによってジョイントの初期回転値を変えてしまっているので、これが後々問題になります。user_animation内で以下のように2箇所にtransform_scopeを接続してみると、ジョイントの初期位置であるpivot_matrixと、strapコンパウンドを出た直後のトランスフォームがズレていることがわかります。
この対策として、一度user_setupに戻りコントローラやジョイントを定義するMatrix配列に手を加えます。PinのMatrix配列をそのまま使うのではなく、strap内部のエイム処理と同じものを一度適用して回転を補正した後のMatrix配列を使うよう変更します。
これでジョイントの初期姿勢(pivot_matrix)がブレなくなりました!
さて、ここまででモジュールの機能としては概ね完成となります。次は生成されたBifrostRigでメッシュをスキンバインドしてみます。
スキンバインド
第1回のベルトのリグをBifrostRigに置き換えてみます。元のリグデータでは下記のように、メッシュ階層、ジョイント階層、リグ階層、そしてbifrostGraph1という構成でした。これらのうちメッシュ階層以外の部分を丸ごとBifrostRigに置き換えていきます。
ジョイント階層を削除するとskinClusterが消えてウェイト情報を失ってしまいますので、事前にエクスポートをしておきます。既存のバインドジョイントの名前をBifrostRigのジョイント名 template_0_jnt ~ template_6_jnt に合わせてリネームした後、茶色いベルト部分に入っているスキンウェイトを Deform > Export Weights で出力します。両端の金具についてはインフルエンスが1つしかないのでウェイト出力は不要です。
次に、Auto Update がオフになっていることを確認し(*3)、templateモジュールの各pinを元リグのジョイントへひとつずつ Match Transform で位置合わせしていきます。
*3) モジュール内部を編集する際はオンにしておくと便利ですが、モジュールを“使う”フェーズでは必ずオフにしておく必要があります。自動的に再構築が走ると、位置がリセットされてしまったり、せっかく入れたskinClusterが消えたりするためです。
ここまで終えたらもう元のリグは必要ありません。ジョイント階層、リグ階層、bifrostGraph1を全て消してしまいます。改めて、BifrostRigのジョイントで3つのメッシュをバインドし、茶色のベルトについては先ほどエクスポートしておいたウェイトを復元します。スキンを復元した結果以下のようになりました!BifrostRigで元のリグと同じものが再現できています!
いったんこれで動きはしますが、アニメーションが追加された後であっても何も壊さずにジョイントの初期ポーズを変更出来るよう、さらに手を加えたいと思います。
具体的には、BifrostRigにより生成されたジョイントのpivotInverseMatrix (*4) を各skinCluster のbindPreMatrixに接続します。pivotMatrix はコントローラで姿勢を更新する前のジョイントの初期トランスフォームが記録されています。pivotInverseMatrix はその逆行列です。skinCluster の bindPreMatrix は初期姿勢の逆行列を接続することでバインドポーズを可変にできます。ここでskinClusterにPivot Inverse Matrix を接続するために、前項で軸ズレを修正しておきました。
*4)Bifrost ヘルプ | トランスフォーム モデル | Autodesk:BifrostのTransformモデルについて詳しくはこちらをご確認ください。
接続は手作業で行っても良いですが、以下のスクリプトを使用するとskinClusterに繋がっているすべてのインフルエンスをbindPreMatrixに追加接続することができます。
from maya import cmds
def get_skin_cluster(shape: str, *args):
his = cmds.listHistory(shape, pdo=True) or []
skin_clusters = cmds.ls(his, type='skinCluster') or []
if not skin_clusters:
return
return skin_clusters[0]
def connect_bind_pre_matrix(sc: str, mtx_attr: str='pivotInverseMatrix', *args):
matrix_attr_list = cmds.listAttr(f'{sc}.matrix', m=True)
for matrix_attr in matrix_attr_list:
bind_pre_attr = matrix_attr.replace('matrix', 'bindPreMatrix')
inf = cmds.listConnections(f'{sc}.{matrix_attr}')[0]
cmds.connectAttr(f'{inf}.{mtx_attr}', f'{sc}.{bind_pre_attr}', f=True)
print(f'Connect bindPreMatrix ({sc}) : {inf}.{mtx_attr} -> {sc}.{bind_pre_attr}')
# 選択したすべてのメッシュのskinClusterにおいて、bindPreMatrixの接続を行います。
if __name__ == '__main__':
for o in cmds.ls(sl=True):
shapes = cmds.listRelatives(o, s=True, f=True) or []
sc = get_skin_cluster(shapes[0])
connect_bind_pre_matrix(sc)
接続を終えたら、Pinを動かしてもメッシュが変形しなくなりました!コントローラにアニメーションを追加した後にPinを動かしても破損がないことが確認できます。
パブリッシュして他のモジュールと組み合わせてみる
では最後に、このカスタムモジュールをパブリッシュして再利用可能にしてみます。まずはモジュールを使う時に調整できるようにしておきたいポートを、モジュールの最上位に取り出します。どのポートを取り出すかは、既存のモジュール(arm、variable_fkなど)を参考にしつつ最低限に抑えてみます。グラフは以下のようになりました。黄色い枠線内が更新部分です。コントローラシェイプ、エイム軸、親の検索情報などを接続しています。
パブリッシュ直前のデータはサンプルデータ『create_strap_module_02.ma』になります。記事の最後のダウンロードリンクからダウンロードできます。
ここまで出来たらtemplateモジュールのコンパウンドを右クリック > Publish "template_module" …より、外部ファイルに出力します。名前は「strap_module」にしておきます。
これで、Node Library やTabキーからstrapモジュールが再利用できるようになりました!
最後に、strap_moduleを別のモジュールと組み合わせる例を簡単に紹介して終わりにしようと思います。2.15のBifrost Browserに「Biped Modules」という二足歩行型リグのサンプルグラフが公開されていますので、まずはこちらを新規シーンにインポートします。インポートされるのはグラフだけですので、BifrostRigをビルドします。
このリグの腰あたりにチェーンが繋がっているイメージで、strapモジュールを追加してみます。グラフは以下のようになりました。
サンプルデータadd_strap_to_biped.maを正常に開くには、同じくサンプルデータのCompounds\strap_module.jsonを C:\Users\<ユーザー名>\Autodesk\Bifrost\Compounds に配置しておく必要があります。
以上です!
今回はBifrostのあらたなフレームワーク「リギングモジュール」に触れてみました。Maya標準では今までモジュラーリグシステムは付属していなかったので、このシステムは大きな進歩に繋がる気がしています。まだリリース直後でモジュールの数は少ないですが、今後のバージョンアップで拡充されていけば様々なタイプのリグに対応できるようになるかと思います。仮にカスタムモジュールを共有するコミュニティが活発になれば、さらに加速的に広がるかもしれません。この辺は今後どうなるか分かりませんが期待したいところです。
モジュールをカスタムするにはまずモジュールの構造を把握する必要がありますが、すべてのグラフを隅々まで理解する必要は無いことが分かりました。また、リグのロジックそのものは今まで通りの組み方をほぼそのまま活かせることも分かりました。本記事は入門にしては少々重めの内容になってしまったかもしれませんが、既存モジュールのグラフをただただ眺めるより一度カスタムモジュールを作ってみたほうが理解が早く進むと思います!是非試してみてください。
また次回をお楽しみに!
まとめ
・Bifrost Riggingはプロシージャルなモジュラーリンギングシステム!
・モジュールの内部すべてを理解する必要は無し!赤いところだけ拡張すればOK
・リグのロジックそのものは今までの組み方を流用できる
















































