はじめに
APEXとは
APEXは、Houdini 20から導入された新しいキャラクターリギングのしくみです。従来の複雑なリギング作業をよりシンプルに、効率的に行えるように設計されたシステムです。
このシステムが出た当時、こう思った方もいるかもしれません。「あれ?Houdini18.5(2020年)で新しいキャラクターリギングシステムのKineFXを出したのに、また新しい機能が出て、また覚えないといけないの?面倒だな」と。
APEXは直訳すると「(三角形・円すい形・山などの)頂点、絶頂、極致」ですが、このHoudiniのAPEXは(All-Purpose EXecution:多目的な実行)が正式な名称です。All-Purpose(汎用・万能・多目的)とは、かなり強気な名前です。もしかするとダブルミーニングで「頂点に様々なAPEXの情報を格納する」という意味も含まれているかもしれません。
※現在APEXはBETA版のため、今後動作や操作方法などが変更される可能性があります。この記事を書いている時点では20.5.378で動作検証を行なっています。その点についてはご了承ください。
なぜAPEXが必要になったのか
端的に言えば、KineFXの機能だけでは、十分なアニメーション付けの操作が難しかったからです。
Houdini18.5で登場したKineFXはまだ歴史の浅い機能です。旧機能のオブジェクトボーンからの刷新で、SOPベースかつジョイントベースの操作ができるようになったKineFXは、過去の思想を一度すべて捨て、全く新しいスケルトンのシステムとして生まれ変わりました。
図:オブジェクトボーンとKineFXの比較 設計思想から全然違う!!!
ボーンがSOPレベルに!非常に大きな変更点であり、プロシージャルワークフローとして、SOPレベルで制御できることの利便性と可能性は非常に大きいものでした。
古いオブジェクトボーン KineFX
[Objectレベル] [SOPレベル]
↓ ↓
ボーンベース ジョイントベース
1スケルトンに1ノード必要 SOP内のポイントとラインとして表現
しかしながら、これらのリギングには、いくつかの大きな課題がありました。
従来リギング機能は具体的にどこが使いにくかったのか
課題:Houdini〜18.0(オブジェクトボーン)
これはオブジェクトレベルで呼び出される古いボーン機能です。
現在はほぼ利用されていません。 Houdiniの旧バージョン互換性のために最新のHoudiniでもノードを呼び出すことは可能です。
しかしこのボーンはもう使うべきではありませんし、そもそもオブジェクトボーンに関する公式ヘルプ情報はすでに消えてアクセス不可能です。
まず、オブジェクトレベルでのリギング処理は、他の3Dソフトウェアとは大きく異なる独特な仕様であったため、新規ユーザーの学習障壁が非常に高いものでした。特に、ジョイントベースではなくボーンベースを採用していたことで、Maya や 3ds Max などから移行してきたユーザーが混乱する原因となっていました。
そして何よりも、ボーンチェーンの管理が複雑でした。各ボーンが独自の方向と長さの情報を保持する仕組みは、理論的にはシンプルかもしれませんが、実際の作業では扱いづらい面がありました。特に、複雑なキャラクターリグを作成する際に、ボーンチェーン間の関係性を適切に設定・管理することが困難でした。
図:オブジェクトボーン利用時の/objネットワーク
(それぞれのアニメーションをつけるためにオブジェクトレベルのボーンを扱う必要があった・・・面倒臭い!)
このような問題点を解決するため、満を持して新しいリギング機能:KineFXへの移行が進められることとなりました。
しかしKineFXにも課題がありました。
課題:Houdini18.5〜19.5のリギング(KineFX)
評価の分断
- リグの評価が複数のステップに分かれていた。例えばリグビヘイビア系ノード(Rig Pose SOP、IK Chains SOP、Full Body IK SOPなど)がそれぞれ個別で計算されていた。
- あっちこっちで計算(リグの挙動とその評価)がされており、まとまりのない処理フローとなっていた。その結果パフォーマンスにも影響が出ていた
- 例:これはセットアップにもよりますが、以下の図のようにそれぞれ個別にアニメーションを評価・計算していた(赤枠内)
操作の煩雑さ
- アニメーションと変形の結果を別々のノードで確認する必要があった
- 例:RigPoseでスケルトン操作→bonedeformで確認 行ったり来たり
- スクイーズ&ストレッチのようなアニメーション効果の実現が困難
- 結果的に直感的な操作が困難となり、しまいにはハッキング的な手法で解決することも(全く実用的でない方法を過去のHoudiniHiveでは紹介していました。こんなの使い物にならない!)
こうした課題に対してHoudiniユーザーが悩んでいた中、Houdini20で突如登場した機能が「APEX」でした。
一体なんなんだこれは!?
APEXを学んでいこう
APEXは明らかに従来の問題を解決するために実装された機能です。
では従来の問題をAPEXはどうやって解決しようとしているかというと。
バラバラだった評価システムをまとめる
- すべての処理を一つのグラフ内で管理
- 明確な依存関係の可視化
- データ駆動型のアプローチでリグとアニメーションを定義・評価
という手段をとっています。
さらにAPEXには驚きの特徴があります!
- SOPのジオメトリに全てのアニメーション関連データを埋め込む、そしてネットワークはジオメトリのまま可視化される
- パックされたジオメトリフォルダを使用してデータを整理する。ファイル拡張子に似た命名規則でビューポートの動作を制御する
- 遅延評価と部分評価をサポート、それにより必要な時にのみ計算を実行されパフォーマンスが向上...
ちょっと待ってほしい、、そもそもグラフって何?依存関係?評価?保存しないのにファイル拡張子?どういうこと???
ここでAPEXを学ぼうとする初学者に情報の洪水が襲います。
そうしてよくわからないままAPEXを学ぶのを諦めるという方もいるのではないでしょうか?ちなみに私はそれでした。
APEXは情報が多く、それが初心者の心を折る原因の一つにもなっていると思うので、一旦初めはAPEXグラフの中身についてはあまり触れません。まずはAPEXを利用した従来のリグの使い方を先行して記述し、一つひとつ説明していきます。
APEXの特徴
初めてのAPEXリギング
さっそくAPEXでリグを作ってみましょう
APEXでのリギングを利用する上で、最も多用するのがAPEX Autorig Componentノードです。
このノードは、あらかじめSideFXがHoudiniに構築されたリグコンポーネント(FKやIK、BlendShapeなど)を用意してくれているもので、ほとんどの場合はこれで課題を解決できます。
※コンポーネントは自作で作ることも可能です、しかしその作業を毎回行うのは大変なのでAuto(自動)でリグコンポーネントを作ってくれるのがこのノードです
コンポーネントとは:
コンポーネントは、「再利用可能な機能のパッケージ」と考えるとわかりやすいと思います。例えば、レゴブロックのように、異なるパーツを組み合わせて大きな構造を作るように、コンポーネントを組み合わせて目的となる大きなリグを構築していきます。
まずは最も初歩的なFKから作っていきましょう
FK(フォワードキネマティクス)
まずGeometryノードを/objに作成し、中に入ります。
ここでSkeletonノードで3つのジョイントを作成します。
Skeletonで3つのジョイントを作成します。それをPackFolderの第2インプットに入力して包み、Base.skelと命名します。(Typeにskelと入力するか右側のハンバーガーメニューからSkeletonを選択します)
そしてAPEX Autorig Componentノードを接続してComponentはfkcontrolを選びます。Sourceタブ内のSkeletonをBase.skelを選択します。guidesourceはそのままでもGuides.skelを消してもどちらでも良いです。
※注意:上記はHoudini20.5での操作です。Houdini20ではAutorigComponentのデフォルトが異なります。将来的に21以降でまた操作が変わる可能性があります。繰り返しになりますが、APEXはまだBETA版という扱いです。Houdini20ではAutorigComponentのComponentデフォルトはfktransform、20.5ではUse Snippet。Sourceタブのskeletonのデフォルトが20ではBase.skel、20.5ではGuides.skelがデフォルトになっています。よって、Houdini20でのAPEX解説動画を見る際には注意が必要です。ここが変更された理由は20.5でtagsとGuides.skelの機能が強化されたことが要因だと考えられます。
これで通常のFKのアニメーションができるようになりました。
疑問:Base.skel 急に出てきたこれは何?
これはCharacter elementのコンテナと呼ばれています。とはいっても中身は、ただのパックドジオメトリデータです。では何で拡張子があるのかというと、パックされた中身がどのような要素なのかを定義するためです。例えばキャラクタをアニメートする際に、仮に拡張子が無いとそのパックドジオメトリがKineFXスケルトンなのか、変形用のシェイプなのか、APEXグラフなのか、判断ができません。そこでこのパックドジオメトリはKineFXのスケルトンです(=.skel の拡張子を付けます)という宣言をしているということです。
また、なぜBaseという名前なのかですが、実は名前は何でも良いのです。ただ、APEX関連のノードではデフォルトでBase.skelやGuides.skel(キャラクターのスキンジオメトリのデフォームに使用するBase.skelとtagsなど追加のAttributeを加えて操作しやすくしたガイド用スケルトンGuides.skel)などの値が入力済みの状態で作られることが多いため、よほどのことがなければKineFXスケルトンをPackedFolderに入れる際はBase.skelやGuides.skelという名前で設定することをお勧めします。
疑問:パックドジオメトリとは?
ジオメトリを単一プリミティブにパック化したものです。イメージとしては複数のファイルをzipファイルにしているようなものです。ヘルプ
疑問:なんでPackFolderの第1インプットではなく、第2インプット?
第1インプットがTarget Folder Structure、第2インプットがSource Inputsです。
このノードの特性として第1インプットを 空っぽのままにすると、新しいフォルダ構造を作成してくれます。第1インプットはすでにフォルダ構造になっているものがすでにある場合は接続するということですね。ちなみに何が入っているかを確認するにはRigTree Paneで確認、GeometrySpreadSheetsで確認する方法があります。
図:RigTree Pane( + > New Pane Tab Type > Animation > Rig Tree)
guidesourceが空の場合
図:GeometrySpreadsheet AutorigComponentを経由すると、Base.skel以外にBase.rigが生成されます。guidesourceでGuides.skelを指定しているとこの時点でGuides.skelも出力されます ここにあるのは3つのパックドジオメトリです
これでリグを操作してキーアニメーション(HotKey:K)をつけて、よし完成!
とはなりません。
アニメーションの基本フロー
このAPEX Autorig Component内は、アニメーションを付ける場所ではありません。
この場所はアニメーションを付けるためのリグのロジックを定義し、そのアニメーションのテストが一時的に保存されるだけです。
よって、例えば他のノードに移動(ディスプレイフラグを移動)してAutorigComponentに帰ってくると一番最初の形状に戻っています。付与したキーアニメーションも消滅します。
せっかく作業したのに!とならないように注意してください。ここで行うのは例えば肩を上げる確認や首を回す確認など、ちょっと確認してみようというアニメーションにとどめてください。
実際のアニメーション付けは、APEX Scene Animateノードで行います。
APEX Scene Animateノードの使い方はこちらの記事を参照してください。
AutorigComponentの出力を繋いでアニメーションを付けます。このデータは一時キャッシュされています。
APEX Scene Animateノードの中身は実質一時保存しているstashノードです。そういった意味ではここでアニメーションを付与するとResetするまでは上流から切り離されたプロシージャルではない状態にあります。
編集も「Animate」が有効の場合のみ可能です。
図:Animate
つまり、ここまでの行程は
スケルトンの準備(Prepare)→リグのロジック作成(Rig)→アニメーションのテスト(Test)
であり、アニメーションの結果は出力されていません。
ですので、最後はAPEXAnimateInvokeノードでアニメーションデータを出力させます。
APEXAnimateInvokeノード内のOutput All Character Shapesボタンを押すことで、これでアニメーションが出力されます。
ボタンを押すと、Outputsが1つ増え、Scene Output Pathには/Base.rig/output というパスが自動で入ります
これ以降は、ファイルを開き直したり、Animateが無効状態でもリグが表示された状態となります。
疑問:Invokeとは? 直訳すると「呼び出す」や「召喚する」ですが、呼び出すって何を?呼び出して結局何をしているの?
アニメーションを実際に使えるかたちで呼び出し、出力します。
ここでは上流にあるAPEXの情報(APEXグラフ)を見て、評価 という作業を行なっています。
このInvokeがAPEXにおいて非常に大事な考え方です。しかしここでその詳細の話をすると頭が混乱するかもしれないので、今はInvokeではAPEXの情報を評価しているという認識だけでOKです。この話は後ほど紹介します。
これでようやく完成です!
さて、確かにAPEXという名前のついたノードをいくつか使いましたが、だから何?という状態かと思います。一体何が起こっていたのかを振り返ってみていきましょう。
APEXネットワークとAPEXグラフ
ここで新しいPaneを表示させます。+ボタンから > New Pane Tab Type > Animation > APEX NetworkViewを選択し、APEX NetworkView Paneを開いてください。
図:APEX Network View : No APEX graph node selected(APEXグラフノードが選択されていません という状態)
このAPEX NetworkViewはGeometrySpreadsheet同様、選択しているノードに応じて表示が変化します。
試しにSkeleton,packfolder,autorigcomponent,sceneanimateと順に選択してみてください。
それぞれ表示が異なるはずです。
AutorigComponentノードを選択した時だけAPEX Network View内になんらかのネットワークが表示されているのが確認できます。その前後はAPEXグラフノードが選択されていません という状態のようです。SkeletonはEmptyNetworkとあり、少し表示されている内容が異なります。
AutorigComponentノード内のネットワークも表示はされていますが、グレーアウトしており何も操作できません。これって何?
結論から言うとこのネットワークの依存関係はAPEXグラフと呼ばれます。
図:APEXネットワーク何に表示されたAPEXグラフ
言葉の整理をすると、APEXネットワークはこのインターフェースや大きな枠組み全体のことで、実際に処理や評価が行われる実体がAPEXグラフ(データ構造)となります。
初めてAPEXを見た人は、これってVOP?と思ったかもしれません。Houdiniヘルプが言うには
- APEXは、SOP の下のレイヤーにある
- どのネットワーク コンテキストにも結び付けられていない
- APEX は中レベルのビジュアル プログラミング フレームワークで、VEX より高く、SOP より低いレベル
- VEX以外にも、より多くの型 (拡張可能な型システム経由) をサポートする手続き型 VOP
とあります。ひとまず、SOPとVEXの隙間に入り込んだVOPっぽい凄いやつと言う認識で良いかと思います。
話を戻します。現状見えているAPEXグラフのネットワークはAutorigComponentノードを選択した時だけ存在しているように見えます。しかし、冷静に考えるとこれは妙です。
1. skeleton「APEXグラフは存在しているけど空っぽです」
↓
2. pack folder「APEXグラフはありません」
↓
3. autorig component「APEXグラフで作ったリグロジック(FK)があります」
↓
4. scene animate「APEXグラフはありません」
↓
5. scene invoke「APEXグラフを評価します」
最後の5.scene invokeでAPEXの評価をするって言うのに、なんで直前の4.scene animateでAPEXグラフが無いんだ?!
packfolderノードとsceneanimateノードどちらもNo APEX graph node selected(APEXグラフノードが選択されていません)と表示されていますが、この2つは実態が異なります。
scene animateは見た目上、表示されていませんがRigTreeを見ると情報は消えていません(むしろ増えている)。つまりパックされた裏側にはAPEXグラフデータを保持しています。
この隠されているAPEXグラフデータを見る一番簡単な方法はunpackすることです。
最初のskeletonに空のAPEXグラフがあったのは、stashノードを含んでいるためです。よって1.skeleton,2.packfolderには何も情報はありません。初めてAPEXグラフが作られるのが3.autorigcomponentです。
unpackするとAPEX NetworkView上にAPEXグラフが出てきました!データは消えていなかったようです。
と同時にViewportに妙な物体が出てきました。
なんだこれは??
初めて見る形状ですが、なぜかデジャブを感じます。
どこかで似たような形状であることに気が付きませんか?
ちょうど真下に表示されているAPEX NetworkViewとViewPortに表示されている形状が同じです。
そう。このジオメトリデータは、ネットワークの情報そのものなのです。
ここでのポイントがノード・ポリラインが接続状態です。
そして、GeometrySpreadsheetを見ると、callbackやnameにネットワークに関する情報が含まれていることが確認できます。
通常はpack化されてグレーアウトしていますが、unpackした状態であればAPEX Edit Graphノードで編集することも可能です。
実際の処理の内容は、左側のinput(3つのポイントのr(回転情報))を3つのポイントごとにTransformObjectを経由し、pointTransformで変形させ、最終的にgeo情報をoutputに渡しています。
一連のノードはparentに接続されたxform情報が流れ込んでくるため親の変形が子供にも伝わるFKの動作となります。
なんということでしょう。SideFX社はKineFXでボーンのジョイントをSOPのポイント、ポリラインをボーンの接続に置き換えるだけでは飽き足らず、ノード自体をSOPのポイント、ノードの接続状態をポリラインにしてしまいました。
確かに理にはかなっていますが、力技にも程があるだろう!と思います。
しかし、ちょっとまわりくどいというか、なんでこんなヘンテコなことをやっているのでしょう。
ここでKineFXの課題を思い出してください。
- リグの評価が複数のステップに分かれていた。例えばリグビヘイビア系ノード(Rig Pose SOP、IK Chains SOP、Full Body IK SOPなど)がそれぞれ個別で計算されていた。
- あっちこっちで計算(リグの挙動とその評価)がされており、まとまりのない処理フローとなっていた。その結果パフォーマンスにも影響が出ていた
これの解決策が、バラバラだった評価システムをまとめる という考え方でした。
つまり、APEXは
- やりたい処理を個々が勝手に計算するとまとまりが無くて収集がつかないから、「こういう処理をする」と言う設計書だけを用意しておき、パックされた情報として準備しておく(プレビュー時を除き計算はしない)
- そして、決まったタイミングでその設計書の実行を行い計算する
- この決まったタイミングで計算を実行するタイミングこそがInvoke:評価を行うタイミング
ということです。
ただし機能が非常に少ない場合はネットワークを見て理解できますが、複雑になってくるとカオスとなります
図:複雑なAPEXネットワーク (人間が目視で理解できないレベルに)
こうした場合を考慮して、設計書となるAPEXグラフ自体を作る・もしくは改造する仕組みも用意されています。
これをサブグラフと呼びます。また、APEXはグラフベース以外にもPythonライク(リガーがPythonに詳しいことから)なAPEX Scriptなどが用意されています。状況に応じて使い分けましょう。
APEXグラフの編集は、やはりAPEX解体新書の記事がめちゃくちゃ丁寧に解説してくれています。
これまでの情報を頭の中に入れて、改めて記事を読むとより理解が進むのでは無いかと思います。
APEXまとめ
- APEXはジオメトリに全てのアニメーション関連データを埋め込んでいる
- パックされたジオメトリフォルダを使用してデータを整理している
- ファイル拡張子に似た命名きそくをしようし、ビューポートの動作を制御している
- モジュラー設計による柔軟な拡張性:リグコンポーネント
APEXは、元々リギングの課題を補うために作られたものではあるのですが、調べれば調べるほど、化物のようなポテンシャルを秘めた機能であると感じられます。
現状はBETA版ではありますが、将来が非常に楽しみな機能です。
今回は、なぜAPEXを使うのかと言う点に焦点を当てて丁寧に説明したため、お伝えできなかった機能面についてまだまだ追記したい内容が山のようにあります。もう締め切りが間近のため一旦の区切りとしますが、引き続きこの記事に追記していきたいと思います。