チュートリアル / Bifrost for Maya Rigging Challenge~一歩先のリグ・アニメーションに挑戦~
第8回:多数のステージライトを一括操作するリグ

  • Maya
  • アニメ
  • キャラクター・リグ
  • ゲーム
  • コラム
  • シミュレーション
  • チュートリアル
  • 上級者
  • 中級者
  • 映画・TV

みなさん、こんにちは。

本コラムでは Maya のプラグイン"Bifrost"を使って、リグ、アニメーション、物理シミュレーションなどの観点から作例を紹介していきます。
今回は「多数の小物をパラメータ制御で一括コントロールする仕組み」を作ってみたいと思います。

成果物は以下の通りです。

今回の成果物

【環境】
・Windows 11
・Maya 2026.1
・Bifrost 2.14.0.0

状況の確認

まずはこちらをご確認ください。簡易的なライブステージにムービングライトを30個ほど配置しておきました。30個ならひとつひとつ手付けで動かせなくもない量ですが、仮にライト数が増えた時にも耐えられて、且つ複数の演出作成を効率的に作成できるような仕組みを考えてみたいと思います。

簡易的なライブステージにムービングライトを30個ほど配置しておきました。

ムービングライトはPanとTiltの2箇所の回転操作ができ、照射方向をアニメーションさせられるライトです。明るさや色は基本として、照射範囲の調整、ゴボの適用など、実物では他にもいろいろな機能を持つ機材があるようですが、ここでは動作に関係するPan・Tiltだけを扱うことにします。本来であればステージ上にはムービングライト以外にも固定のライトが多数置かれることと思いますが、最低限で進めます。

ムービングライトはPanとTiltの2箇所の回転操作ができ、照射方向をアニメーションさせられるライトです。

今回は難易度の高いアルゴリズムは特に出てきません。ひとつひとつは簡単なロジックばかりです。ただし、一括操作やプロシージャルな動作エフェクトなど、複数のパラメータや状態を組み合わせたり切り替えたりするため、全体の設計がキモになってきます。

それでははじめていきます!

コントローラの基本設計

まずはPanとTiltをそれぞれ計2つのスライダーで制御することを考えます。複数のライトをひとまとめにして一括制御したいところですが、全てのライトが同じ動きでは少し困るのでバラ付きを持たせたいです。しかしライトはたくさんあります。ひとつひとつのライトに対してオフセット値を手打ちするのは大変ですので、ライト数分のオフセット値を出力する仕組みを間に挟むことにします。

コントローラーの基本設計

上図の黒い矢印は単一の値、赤い矢印はライト数分の値の配列を想定しています。編集すべきパラメータがライト数に比例せず最小限にとどまるよう、Inputからは黒い矢印だけが伸びるように構成を考えていきます。これならたとえライトが100個になったとしても操作すべきパラメータ数は増えません。

グラフは以下のようになりました。スライダーの値は原則 [-1〜1] や [0〜1] の範囲で動かせるようにしてあります。Panは±270度、Tiltは±120度を可動範囲としてmultiply(*1)で可動範囲にスケールしています。

*1) 仮に単純な乗算で変えられる状況ではない場合は、change_rangeが候補に挙がります。

bifrostGraphShape
bifrostGraphShape
bifrostGraphShape > spread
bifrostGraphShape > spread
NodeEditor
NodeEditor

10個のライトを一括制御出来ました!

10個のライトを一括制御出来ました!

エイム操作

スポットライトは賑やかし用途で使いたい時もあれば、どこかをしっかりと狙って照らしたい時もあるかと思います。ターゲット位置を元にPanとTiltが決まるエイムコンパウンドも別途作成しておきます。

エイム操作

ターゲット位置からPanとTiltの角度を計算するにはアークタンジェントが使えます。

Panは、XZ平面でターゲットTに向かう角度を考えます。TiltについてはまずTまでの水平距離dを求め、d-Y平面(上図のオレンジ色の平面)上で角度を計算します。hはTilt軸までの高さです。

Panは、XZ平面でターゲットTに向かう角度を考えます。TiltについてはまずTまでの水平距離dを求め、d-Y平面(上図のオレンジ色の平面)上で角度を計算します。hはTilt軸までの高さです。

計算式

グラフは以下のようになりました。

bifrostGraphShape
bifrostGraphShape
bifrostGraphShape > aim
bifrostGraphShape > aim
NodeEditor
NodeEditor

エイム操作ができました!各ライトのWorldMatrixを基準に角度を割り出しているので、ライトの移動や回転も問題なく可能です。

エイム操作ができました!各ライトのWorldMatrixを基準に角度を割り出しているので、ライトの移動や回転も問題なく可能です。

周期関数で自動アニメーション

マニュアル操作やエイムでPanとTiltを制御することはできましたので、次は周期関数を使って自動的に動き続けるアニメーションエフェクトを作ってみます。sin(t) と cos(t) を組み合わせるだけで円運動が作れますので、これをPanとTiltに適用することを考えます。

周期f、位相Φ、振幅a、オフセットo などを自由に変更することを考えると、sin関数(およびcos関数)は以下のような形を基本形として使用することになります。また、BPM(*2)をもとに周期fを決定する計算式も用意しておきます。

*2) BPM (Beats Per Minute):1分間あたりの拍数を示す単位です。

計算式

o:オフセット
a:振幅
t:時間
f:周波数
Φ:位相

これまでと同様、周期関数にもオフセット値を利用して効率よく多数の値を制御します。この場合はオフセット値の配列を位相Φに入力し、出力されるアニメーションを少しずつずらせるように組むことにします。

周期関数で自動アニメーション

グラフは以下のようになりました。

bifrostGraphShape
bifrostGraphShape
bifrostGraphShape > wave_pan_tilt
bifrostGraphShape > wave_pan_tilt
bifrostGraphShape > bpm_to_freq
bifrostGraphShape > bpm_to_freq
NodeEditor
NodeEditor

周期や位相を変えることでいろいろな動きが作れそうです!

周期や位相を変えることでいろいろな動きが作れそうです!

モード切り替え

ここまでで「マニュアル操作」「エイム操作」「周期アニメーション」の3系統が完成しました。いずれもライト数分のPan・Tilt値を配列として出力しています。これらを任意に切り替えたり、複数のモードを混ぜ合わせて使えるようにするための仕組みを追加してみます。

モード切り替え

グラフは以下のようになりました。二次元配列(上図の赤矢印をさらに配列にまとめたもの)の重み付き和を計算し、一次元配列を出力します。一次元配列であればmultiplyで自動ループを発生させるだけで重み付けの計算ができるのですが、二次元ですのでfor_eachなどを使用して自作しています。

bifrostGraphShape
bifrostGraphShape
bifrostGraphShape > blend_float_arrays
bifrostGraphShape > blend_float_arrays
bifrostGraphShape > blend_float_arrays > for_each
bifrostGraphShape > blend_float_arrays > for_each
bifrostGraphShape > blend_float_arrays > iterate
bifrostGraphShape > blend_float_arrays > iterate

複数の値をまとめて配列を作成するにはbuild_arrayコンパウンドが使用できますが、array<float>をそのまま複数繋ぐと"連結"になってしまい一次元配列のarray<float>が出力されるので注意が必要です。二次元配列を作成するには、空の二次元配列(array<array<float>>)を接続して明示的に型を指定する必要があります。

build_arrayの挙動
build_arrayの挙動

スライダー操作によってモードチェンジができるようになりました!

Wave → Manual → Aim 切り替え
Wave → Manual → Aim 切り替え

動的なグループ分け

この10個のライトグループをさらに動的にサブグループに分けられるよう拡張してみます。たとえば「エイム」モードの時、端から交互に2つのサブグループに分け、それぞれ異なるターゲットのほうを向かせるような構成にしてみます。

動的なグループ分け

グループ分けには、[0,0,1,1,0,0,1,1…] のようなインデックス配列を作成するgroup_by_sizeというコンパウンドと、そのIDによって複数の配列から要素を選択するselect_by_idというコンパウンドを作成し、これらを組み合わせる形にしてみました。選択対象となる配列は前項と同様にbuild_arrayを通した二次元配列になっています。

bifrostGraphShape(AimとBlendの間に挟んでいる黄色の部分がグループ分けノード)
bifrostGraphShape(AimとBlendの間に挟んでいる黄色の部分がグループ分けノード)
bifrostGraphShape > group_by_size
bifrostGraphShape > group_by_size
bifrostGraphShape > group_by_size > iterate
bifrostGraphShape > group_by_size > iterate
bifrostGraphShape > select_by_id
bifrostGraphShape > select_by_id
bifrostGraphShape > select_by_id > iterate
bifrostGraphShape > select_by_id > iterate

サブグループ数は最大2つまでで固定してしまっていますが、各ライトの所属先をパラメータで選択できるようになりました。

サブグループ数は最大2つまでで固定してしまっていますが、各ライトの所属先をパラメータで選択できるようになりました。

ここまでの結果を元にリグを完成させる

必要なものはだいたい揃った気がします。ここまでで作成した機構は以下の通りです。

・マニュアル操作
・エイム操作
・周期アニメーション
・モードチェンジ
・動的グループ分け

ステージ上の全ムービングライトを各区画ごとに分類しこれらの仕組みを展開していきます。

ステージ上の全ムービングライトを各区画ごとに分類しこれらの仕組みを展開していきます。

まずは、ここまでのグラフを丸ごとひとつのコンパウンドにまとめ、このコンパウンドを適宜カスタマイズしながら各区画に展開していくことにします。エイムモードをなくしたり動的なサブグループをなくしたり、それぞれに必要なものを取捨選択をしつつ組み合わせていきます。

前項までのグラフを1つにまとめたコンパウンド
前項までのグラフを1つにまとめたコンパウンド

グラフはすべて載せるとかなりの量になってしまうので省略しますが、基本はここまでの成果物をコピペして組み合わせているだけです。

グラフはすべて載せるとかなりの量になってしまうので省略しますが、基本はここまでの成果物をコピペして組み合わせているだけです。
サンプルデータ:01_pan_tilt_controls.ma (記事の最後のダウンロードリンクからダウンロードできます。)
サンプルデータ:01_pan_tilt_controls.ma (記事の最後のダウンロードリンクからダウンロードできます。)

明るさや色にも同じ仕組みを追加

動きの制御のみにとどめる予定でしたが、少し寂しいので同じような構成のグラフをライトの色や明るさにも適用してみます。

ここで新規に追加したコンパウンドは以下の3種です。

・1つのsin波を出力する「wave_sin」
・FCurveで波形をカスタムできる「wave_custom」
・色の重み付き和を計算するための「blend_float3_arrays」

bifrostGraphShape(Pan・Tiltをコントロールするコンパウンドを改変し、明るさと色をコントロールするコンパウンドを作成)
bifrostGraphShape(Pan・Tiltをコントロールするコンパウンドを改変し、明るさと色をコントロールするコンパウンドを作成)
bifrostGraphShape > light_color_control
bifrostGraphShape > light_color_control
bifrostGraphShape > light_color_control > wave_sin
bifrostGraphShape > light_color_control > wave_sin
bifrostGraphShape > light_color_control > wave_custom
bifrostGraphShape > light_color_control > wave_custom
bifrostGraphShape > light_color_control > blend_float3_arrays
bifrostGraphShape > light_color_control > blend_float3_arrays

グラフ全体は以下のようになりました。例によって巨大なグラフですので、詳細はサンプルデータをご確認いただければと思います。

グラフ全体
グラフ全体
動かした様子
動かした様子
動かした様子
サンプルデータ:02_intensity_color_control.ma (記事の最後のダウンロードリンクからダウンロードできます。)
サンプルデータ:02_intensity_color_control.ma (記事の最後のダウンロードリンクからダウンロードできます。)

以上で完成です!

最後は色や明るさも変えて実際のライブ演出を想定したシーンを簡単に設定してみましたが、実際のところあまり使わなそうなパラメータや逆に不足しているパラメータがありました。まだ改良の余地はありそうです。

コントローラはカーブで作成してMaya側から操作可能な構成にしてみましたが、演出ごとにBifrost内のグラフをガラッと組み換えて最低限のパラメータだけ都度Mayaに公開する使い方もアリかもしれません。

ちなみに、今回のデータはあくまでビューポートでの確認用にしか組んでいませんので、実際にはライトオブジェクトに接続したり、パラメータだけ出力してAfterEffectsに持ち込むなど、その後のワークフローによってベストな組み方が変わってくるかと思います。いろいろなやり方があるかと思いますが、何かの参考になれば幸いです。

最後に、今回作成したコンパウンドを用途ごとにまとめて終わりにしたいと思います。

サンプルデータ:compounds.ma(記事の最後のダウンロードリンクからダウンロードできます。)
サンプルデータ:compounds.ma(記事の最後のダウンロードリンクからダウンロードできます。)

また次回をお楽しみに!

まとめ

・操作すべきパラメータがライト数に比例しないような設計を
・build_arrayで二次元配列を作成するときはつなぎ方に注意
・マニュアル操作、エイム、周期アニメーションを重み付き和で切替え&合成
・同様の仕組みを明るさや色変化にも転用可能


製品購入に関するお問い合わせ
オートデスク メディア&エンターテインメント 製品のご購入に関してご連絡を希望される場合は、こちらからお問い合わせください。