これはHoudiniApprenticeAdventCalenderの2024/12/18の記事です。
実行環境と注意事項
Windows11 Houdini 20.5.389 Educational License
APEXはまだベータですのでヴァージョン情報にはご注意ください。
また、ライセンス形態によっても挙動が微妙に異なることがあるようです。
この記事の内容はKineFX/APEXの正式リリース以降は間違った情報となる可能性があります。
自己紹介と対象読者
こんにちは。私は元グラフィックス・エンジニアで、現在は大学教員をしています。Houdiniは触れるけどキャラクター・アニメーションはやったことがない、SideFXがKineFX/APEXでキャラクター・アニメーションに注力しているのは知っている、公式ドキュメントはまだ整備されていないけどベータ版のうちに触っておくかなあ、と私とおなじようなテンションでKineFX/APEXを見ている方を対象に記事を書きます。もちろん、詳しい方にも読んでいただき、ツッコミ、アドバイス、勉強会へのお誘いなどいただけると大変ありがたいです。
動機
Houdini20.0でグラフを使ってAPEXリグを生成・編集するAPEXGraphが導入されました。私はSOPより粒度が細かいグラフ編集は苦手でコードを書く方が好きなので、20.0まではAPEXリグを敬遠してました。ですが、Houdini20.5からグラフではなくコードでAPEXリグを生成・編集するAPEXScriptが導入されたことで、APEXリグに本格的に取り組むことにしました。
まだベータということもあり、あまり情報がなく、進捗は芳しくありません。そんなおり、APEXGraphを直接編集してリグを作成するMaxさんの動画に対して、その動画と同じことをAPEXScriptでコードを書いてリグを作成するCameronさんの動画がアップされました。同じロジックをグラフとコードの両面から分析することで、飛躍的にAPEXリグの理解が深まるという事がわかり、大変感銘を受けました。
正直なところ、私はある一定以上複雑なグラフを見ると思考停止してしまうので、努力不足を情報不足と言い換えていたかもしれません。Cameronさんのやり方を知ってからはAPEXリグ解析に弾みがつき、現在はMixamoからダウンロードしたキャラクターにリグをつけたい学生用にElectraのリグを適用するHDAを作るくらいはできるようになりました。
しかし、この程度のことを理解するのにも時間がかかるくらいKineFX/APEXをめぐる状況は混乱しています。この混乱を自分なりに整理した経験を、ベータのうちにAPEXリグを始めようという人に向けて記事にすれば有意義かもしれないと思い、この記事を書くことにしました。
KineFXリグはどうなった?
最初の混乱はこれですよね。公式にもこのあたりの歴史的経緯に関して記述がありますが、SiggraphAsia2024のHiveでもこの記事にあるようなKineFXリグのさらに前身であるOBJリグまで遡ったとてもわかりやすいレクチャーが管理人様からありました。ユーザーの混乱が解消すると思いますので、SideFX様には是非アーカイブ配信していただきたいです。
私の理解ではKineFXというのはファー、クロース、リジッドボディといったHoudiniが得意なシミュレーションと手付けのキーフレーム・アニメーションをシームレスに連携できる新しいアニメーション・ワークフローの名前です。
このワークフローの中のKineFXリグがAPEXリグに置き換わっていく流れなのだと思います。ぱっと見ではKineFXリグはSOPグラフでプロシージャルにリグを構築していくことができる良いシステムだと思ったのですが、何が問題だったのでしょう?
KineFXリグでは、SOPグラフのあちこちに散在するRigPoseSOPを順番に評価してアニメーションします。先述の通り、KineFXリグはSOPグラフでリグの構造を表現するので、RigPoseSOPを評価するということはリグの評価・計算とリグの構築が同時に行われることになります。リグの性質上これらを並列計算するわけにはいきません。結果、複雑なリグを何体も同時にアニメーション編集するような状況では重くて動かないそうです。
よく参考にさせていただいている動画でもRigPoseSOPがKineFXリグのボトルネックだと結論付けています。
APEXリグでどう変わった?
新しく導入されたAPEXリグでは、リグ構築フェーズとリグ評価・計算フェーズを分離することに主眼が置かれています。APEX系のSOPはリグ構築用とリグ評価・計算用で完全に分かれています。ですのでリグ構築用のSOPがいくつか続いた後にリグ評価計算用のSOPが来るというパターンが崩れることのない、直線的で作業フェーズがわかりやすいSOPグラフに自然となります。
この記事では、まず、簡単なAPEXリグの実例をコメント付きでざっと見ていただき、各フェーズにまつわる混乱を整理していきたいと思います。サンプルとしてチューブに骨を入れて、ウェイトをつけて、あらかじめ用意されているリグ部品を3つ使ってAPEXリグを構築して、最後にアニメーションを編集する、ミニマルなSOPグラフを作りました。
注目していただきたいのは複数のAPEXAutoRigComponentSOPでプロシージャルに少しづつリグを構築しているリグ構築フェーズと、一つのAPEXSceneAnimateSOPでアニメーション編集の全てを担うリグ評価・計算フェーズです。とてもシンプルで直線的な流れですよね。リグというとMayaのDGスパゲッティをイメージする私は「このSOPグラフのどこでリグの構造が表現されているのだ?」とシンプルすぎてかえって混乱しました。
実はSOPグラフにリグの構造が現れるKineFXリグとは異なり、APEXリグではSOPよりひとつ下のレイヤーにあるAPEXGraphでリグの構造を表現しています。APEXGraphは、APEX系のSOPによって生成・編集されてはワイヤーを流れて行くジオメトリのようなものです。(実際、パックされたジオメトリです)サンプルのSOPグラフが生成・編集したApexGraphを視覚化するとこのようになります。たった3つのSOPですが、MayaのDGに勝るとも劣らない立派なスパゲッティができていて、初めて見たときは妙に安心しました。これならリグの構造を表現できそうです。
このように操作する側とされる側でネットワークのレイヤーを分けたことで、SOPグラフは単にリグ構築手順書になりました。APEXGraphがどんなに複雑になってもSOPグラフは直線的でシンプルなままです。例えば、これは先述のMAXさんの動画を参考に作った本格的なBipedリグです。いろいろな機能が追加されていますが、SOPグラフが直線的に長くなっているだけです。
なお、ここまで見てきた事例のようにTAGなどのメタデータと純正リグ部品を活用したモジュラー・リギングをするだけならAPEXGraphについて理解する必要はほとんどありません。サンプルのようにSOPをいくつかつなげるだけでリギングを完結できます。このあたりはリグを量産したり、アニメーションのリターゲティングといったシチュエーションを最初から想定しているのだと思います。
私はなんとなく、KineFXリグはインタープリター言語、APEXリグはコンパイル言語といったイメージで捉えています。お気楽なインタープリター言語に比べると、コンパイル言語にはあらかじめ理解しておかなければいけない概念が多いですが、APEXリグにもそれがあてはまります。ある程度、予備知識をつけてからでないと触ることができません。「とりあえずいじりながら理解する」はうまくいきませんでした。
APEXリグを理解するための予備知識
APEXについて
今のところリグが主な適用事例になってますが、APEXはリグ専用ということではなくVEXと同じように各種コンテキストのオペレーターやヴューワー・ステートから呼び出せる汎用グラフ評価フレームワークという位置づけのようです。その実体はPythonのapexモジュールです。
リグの場合、APEXは例えば先ほどのSOPグラフの最後にあったAPEXSceneAnimateSOPのヴューワー・ステートに実装されています。ViewerStateBrowserでそのPythonソース・コードを確認することができます。
勉強不足でapexモジュールを解析できていませんが、仮にその実体がC言語のPythonラッパーとかではなく普通のPythonコードならAPEXはコンテキスト・フリーに実装できそうです。実際、SiggraphAsia2024のHiveでもリグ以外の様々なコンテキストでバイオームやヴォリュームのためにAPEXを使っているという報告がありました。「All Purpose Execution」は伊達じゃなさそうです。
このあたりのAPEXの汎用性や将来性に興味があるという方はぜひ、amaterasu様の記事をご一読ください。APEXリグはもちろん、APEXそのものについて深堀されていてとてもわかりやすいです。
APEXGraphについて
APEXは「汎用グラフ評価フレームワーク」と言いましたが、この評価対象である「汎用グラフ」がAPEXGraphです。APEXにAPEXGraphを入力すると何かしらの出力が得られるというわけです。ひとまずAPEXをプログラム実行環境、APEXGraphをプログラムと考えて問題ないと思います。(ちょっと語弊があります。あとで修正します)APEXGraphは、例えば、APEXEditGraphSOPでAPEXNetworkViewを表示して作成・編集できます。
APEXGraphの実体はパックされたジオメトリーです。APEXGraphのノードとエッジを、ジオメトリのポイントとラインプリミティブでそれぞれ表現します。ポイント・アトリビュートの形でさまざまなデータを保持しておき、ラインプリミティブのトポロジーでそのデータ・フローを表現するという感じです。
前述の通り、私は上図中段のAPEXNetworkViewのように一つのノードからたくさんエッジが出ているグラフが苦手です...
APEXScriptについて
同じように感じる人が多かったのかわかりませんが、VEXにVOPGraphとVEXCodeがあるように、Houdini20.5以降のAPEXにもAPEXGraphとAPEXScriptが用意されたのでグラフ編集が得意な人は前者を、コード編集が得意な人は後者を選べるようになりました。具体的にはAPEXScriptSOPにAPEXScriptを記述するとそれがAPEXGraphに変換されていきます。
おそらくは先にどちらがあったかの違いでVEXの場合はVOPGraphがVEXCodeに変換されるのに対して、APEXの場合はAPEXScriptがAPEXGraphに変換されますが、グラフとコードで同じことができるのはVEXと同様です。
さて、混乱の一つめです。APEXScriptは型情報つきのPythonのように見えますがPythonではありません。APEXが(おそらく)Pythonで書かれているのでAPEXScriptもPythonのように思ってしまうのですが、APEXScriptはあくまでもAPEXGraphを生成・編集するための独自言語です。
さらに混乱するのですが、その独自言語をパース&実行するのはAPEXScriptSOPの実体であるHDA内にあるPythonSOPです。もう笑うしかない。中身を見てみると入力されたAPEXScriptをPythonSOPでパースしていることがわかります。
なぜこんなことをするのでしょう?それはおそらく変換先であるAPEXGraphがPythonよりも表現力が低いため、APEXScriptには素のPythonにはない以下のような制限があるためです。
- 辞書型のキーには文字列型以外は使えません
- 配列型には1種類の型しか格納できません
まだまだありますが、ApexScriptSOPは入力されたコードがこれらの制限を守っているかチェックして、問題がなければAPEXGraphに変換、問題があればエラーで停止するということをしなければならないのです。
実用上APEXGraphの表現力に問題があるとは感じませんが、Pythonの表現力になれてしまっているので上記の制限を忘れてしまいがちです。特に、APEXScriptSOPと並行してPythonSOPも編集しているときなどは何度も引っかかって「なんで動かないんだ?」と気が狂いそうでした。似ているだけにやっかいです。
APEXScriptGraph?どっちやねん?
実はAPEXScriptを使わなくても、APEXGraph自身でAPEXGraphを生成・編集できます。エンジニアの方はAPEXにとってのAPEXGraphは、LISPにとってのリストのようなものと考えると良いかもしれません。プログラムとデータが同じ形をしているので、データを操作するのと同じやり方でプログラムも操作できます。
そして混乱が始まります。やっかいなことに公式リファレンスや動画では、APEXEditGraphのパラメーターを見てみるとわかるように、このようなプログラムとしてのAPEXGraphをScriptと呼称します。もちろん、これはAPEXScriptを指しているのではありません。
さらに混乱は続きます。まず、新しすぎてまだアイコンすらない哀れなAPEXScriptSOPの第2出力ポートにカーソルを合わせてみます。するとコンテキストヘルプが現れてAPEXScriptGraphが出力されると書かれています。思わずどっちやねん?とツッコミたくもなります。
このあたり本当に混乱しました。20.0と20.5ではAPEX関係で出てくるScriptという言葉の意味が変わってくるからです。用語が統一されるまではScriptという言葉が何を意味するのか、文脈から判断するしかありません。
以下の事を頭に入れておくと役に立つと思います
- APEXGraphはプログラムであり、データである
- どちらとして扱うかはSOPによって決まっている
- プログラムとして扱うAPEXGraphはScriptGraph,GraphScript,単にScriptと呼ばれる
- これらとAPEXScriptは別物。ただ、稀にAPEXScriptをこのように呼称する方もいる
- Scriptに入力するデータとしてのAPEXGraphはRigGraphなどと呼ばれる
APEXリグについて
ようやく本題です。それぞれのフェーズでの混乱を整理していきます。
ジオメトリー作成フェーズ
最初の混乱はshapeでしょう。リグ構造の中にスキンが含まれるというのは、他のDCCツールに慣れた方には違和感があると思います。APEXリグでは一つのオペレーターのヴューワー・ステートでアニメーション編集を完結させるという目的があり、そのために必要なデータを全てまとめたものをリグ構造としています。
guidesは他のDCCツールでもスキン・バインド用の骨とコントローラー用の骨は分けるので混乱はなかったです。
少し混乱するのは循環参照があるかないかという違いはありますが、KineFXで導入されたジョイント・ベースのスケルトンとAPEXGraphのどちらもポイントとラインプリミティブからなるジオメトリというところでした。たまにどちらの話かわからなくなることがあります。
ストリーム変換フェーズ
新しく導入されたAPEXPackedCharacterFormatについては混乱はなかったと思います。最上位がシーン・フォルダー、その下にキャラクター・フォルダー、その中にシェイプ、スケルトン、リグなどをファイルとして置いておき、拡張子で種類を判別できるようにしたファイルシステムのようなデータストリームです。マニュアルにあるこの画像がわかりやすいです。
わからなかったのは、なぜこんな事をする必要があるのかということでした。これに関しては、先述の通り、APEXリグでは一つのオペレーターのヴューワー・ステートでアニメーション編集を完結させるという目的があり、必要なデータを全て一箇所に集める必要があります。これはそのために用意された仕組みなのだということに後で気が付きました。
リグ構築フェーズとリグ評価・計算フェーズ
ここから先はAPEXの世界です。キャラクター・ストリームを流れるBase.rigがAPEXリグそのものであり、その実体はAPEXGraphだというのは良いと思います。
注意しなければならないのは、APEXGraphがプログラムとして扱われるのか、データとして扱われるのかはSOP次第という話です。APEXAutoRigComponetSOPはBase.rigをデータとして扱いますが、APEXSceneAnimateSOPはBase.rigをプログラムとして扱います。ここを理解するのにとても時間がかかりました。
APEXAutoRigComponentSOPの場合
APEXリグは一からすべて自分でAPEXGraphやAPEXScriptで構築することもできますが、様々なリグ・コンポーネントがAPEXAutoRigComponentSOPに用意されているので、いわゆるモジュラー・リギングが可能です。
リグ・コンポーネントはComponentScriptと呼ばれるプログラムとしてのAPEXGraphで与えられます。出ましたねScript。この言葉が出てきたら要注意でした。このComponentScriptはbgeoファイルとして読み込まれている事がComponentタブでわかります。
Visualizerタブで設定をComponentScriptに変えて、読み込んだbgeoファイルをAPEXNetworkViewで見てみると、確かにComponentScriptがAPEXGraphであると確認できます。
一方、APEXAutoRigComponetSOPに入力されるBase.rigはデータとして扱われます。これをプログラムであるComponentScriptに入力すると、必要なノードやエッジが追加されたBase.rigが返されるので、それをそのまま出力に流します。このようにしてAPEXAutorigComponentSOPをBase.rigが通過するたびにどんどんと機能が追加されていきます。
私は、当初、Base.rigとComponentScriptのどちらもデータとしてのAPEXGraphで、それらを結合するのがAPEXAutoRigComponentSOPの役割なのだろうと思っていました。なぜかというと、ドキュメントや動画で「リグが評価・計算されるのはAPEXSceneAnimateSOPだけ」という言説をよく耳にしていて、これを「APEXGraphが評価・計算されるのはAPEXSceneAnimateSOPだけ」と誤認していたからです。ここはリグでも、APEXGraphでもなく「Base.rigが評価されるのはAPEXSceneAnimateSOPだけ」と言ってもらえれば混乱がなくて良かったのになあと思います。
APEXSceneAnimateSOPの場合
ここで最後の最後に入力であるBase.rigが初めてプログラムとして扱われます。このプログラムはヴューワー・ステートからの入力に応じて、リグの評価・計算を行い、Base.skelのトランスフォームとBase.shpのデフォームを更新します。そこにキーフレームが設定されるというわけです。
また、パラメーターや入出力ポートの数を見てみるとわかりますが、ComponentScriptのようなAPEXGraphを使ってBase.rigを編集するということはここでは一切できません。このようにして作業フェーズが混ざらないようにしているのだと思います。
余談になります。私がアニメーション編集環境に疎いからかもしれませんが、APEXSceneAnimateSOPでのアニメーション編集は本当に画期的だと思います。様々なシミュレーションと手付けキーフレームが協調動作している様子には感動すら覚えます。おそらくAPEXリグは、このアニメーション編集環境を実現するために一から設計しなおされたAPEXSceneAnimateSOPありきのシステムなのだろうと思います。まだベータなのでバグがあって落とし穴満載ですし、Pythonなので速度的な限界は気になりますが、とても将来性を感じる魅力的なシステムだと思います。
まとめ
KineFX/APEXのAPEXリグについて、学習中につまづきやすいポイントを整理しました。KineFX/APEXは革新的なアニメーション編集環境であるため、他のDCCツールにはない概念を予備知識として理解しておかなければいけないこと、まだベータということで用語の統一がなされていないこと、これらに起因する混乱を自分なりに解消していった記録を記事にしました。
どなたかの参考になること、詳しい方にツッコミを入れていただけることを期待して筆をおきます。執筆の機会を頂き、ありがとうございました。