コンテンツにスキップ

USDの機能の多くはKitchen_setが教えてくれる

Universal Scene Description AdventCalendar2021 25 日目(最終日)は、
これまで多くの記事で紹介してきた USD の機能を Kitchen_set を使って改めて紹介していこうと思います。

Kitchen_set とは

Kitchen_set とは、USD の公式ドキュメントの Downloads and Videos からダウンロードできるサンプルアセットでです。
非常にシンプルなデータですが、このサンプルには
USD を使用するうえでは非常に有用で、参考になる要素が多く含まれています。

USD アドカレ最終回の今回は、この Kitchen_set に含まれる各要素を1つづ解説することで
USD をどのように構築していけばいいのか、どのように考えてレイヤーや Prim の階層を構築すればよいのかを
解説していきたいと思います。

全体のフォルダ構成

Kitchen_set は、「複数のファイルによって1つの Stage 構成される」という USD の特徴を表したサンプルです。
そのため、「Kitchen_set」という1つのシーンですが
多数の USD によって構成されています。

その構造はざっくり分けると2つで構成されています。

assets 以下には AssetName のサブフォルダがあり、
その下には各個別のレイアウトするためのアセットデータが置かれています。
このどちらも統一されたルールの上で構成されていて、実際に運用する上での良い参考になります。

assets

assets は、 ComponentBuilderで遊ぼう Pythonで作るUSDアセット の回で紹介したような
指定のコンポジションやレイヤーでセットアップされた USD のアセットです。

Kitchen_set で配置しているアセットは、すべて決められた構造でセットアップされています。

レイヤーと役割分担

「Payload の仕組みを追加する」のように、USD では役割に応じてレイヤーを分けることができます。
assets の各レイヤーと、そのレイヤー内の Prim を図に表すとこのようになります。
どのようにレイヤーを分けるかは難しい問題ですが、
まずは Kitchen_set を参考に、役割によって分割したり、更新する人や役割によって分割にすると
良いと思います。

AssetPath

Kitchen_set のアセットは、すべて Kitchen_set.usd からの相対パスで記述されています。
ためしに、 USDの便利なツールたち (2) usdcat で確認すると

このように、現在のファイルパスからのパス(AnchorPath) で指定されています。
このアセットまでのパスは、 AssetResolution という機能を使用して、
実際のリソースまでの解決を行います。

詳細は、以下のアドカレの記事にて紹介していますが、
assets をどこに配置してどのようにパスを解決するかはとても重要です。

AssetResolution(1) - usdResolverExample
AssetResolution(2) ResolveとContext

コンポジションアーク(Payload と Unlaod)

アセットは1つのレイヤーで構成されているわけではなく、複数レイヤーによって作成されています。

例えば Ball アセット(assets/Ball/Ball.usd) を開いて確認してみると、このように Payload と Reference が含まれています。
Geom や Material などをどのように分けるかは構成次第ですが
最終的に「Payload」をコンポジションに挟むことには大きな意味があります。

これは、アセットをレイアウトしたときにどのような方式でコンポジションしたとしても すべてのアセットはアンロードする
といったことが可能になるからです。

USD でレイアウトをした場合、1つのシーンに対して数千どころか万単位のレイヤーをコンポジションで合成することになります。
そうすると、1つのシーンのうちごく一部を修正したい場合であってもすべてを開かなければいけないのは非効率です。
ペイロードがアセット側に含まれていれば「アンロードする」というのが必ず可能になり
部分的なロードが用意になります。

1
usdview D:\Kitchen_set\Kitchen_set.usd --unload

試しに、 usdview で Kitchen_set を開くときに --unload を入れてみます。
入れるとすべてのアセットがアンロードされるのがわかります。

DefaultPrim と シーングラフの基本構成

各アセットのシーングラフは、リファレンス、あるいはペイロードを前提とした構造になっています。

リファレンスは、ある Prim に対して(Namespace に対して)べつのシーングラフを「接ぎ木」することです。
そのため、リファレンスでは @./assets/Ball/Ball.usd@ のようにファイルパスで指定はしていますが
実際には、その指定したレイヤー内にある Prim 以下を接ぎ木します。
この時に「どの Prim 以下を接ぎ木したいか」を、レイヤー側に指定していないと
どの Prim を使用していいのかわからないのでリファレンスができません。

USD のアセットを見ると、すべて「DefaultPrim」が /AssetName の Prim に対して指定されています。
また、アセットのデータはclass のように継承するための Prim を除き
こn DefaultPrim 以下に配置するようになっています。

図に表すとこのようになります。
AssetName 以下には Geom Looks(material) Render といった大分類の Prim があります。
それ以下に関しては、Reference することでかならずユニークになるので
いわゆるカプセル化された、この Asset 内で完結したデータになります。

参考: CompArc(4) リファレンス・ペイロード

VariantSet

Kitchen_set でレイアウトされているモデルには、VariantSet が含まれているものがあります。
例えばスクリーンショットの Cube は、同じ Cup.usd をリファレンスしていますが
ShadingVariant と modelingVariant という2つの VariantSet によって
同じアセットでもヴァリエーションができるようになっています。

このように、VariantSet を使用することで、配置したあとにマテリアルやモデルを調整するといったことが可能になります。

参考: CompArc(3) バリアントセット

AssetInfo

AssetInfo とは、USD で作成されたアセットを管理・識別するために、
Prim や Property に対して指定することができる辞書型のメタデータ です。

詳細は、 AssetInfoについて こちらのアドカレにて解説していますが
Kitchen_set のアセットにも、この AssetInfo が含まれていて
アンロードしている状態であっても、どのファイルが依存しているのかを確認できるようになっています。

Kind

Kind とは、Prim 単位で指定することができるメタデータの一種で
ModelHierarchy」と呼ばれる、USD でアセットをレイアウトするときに
どのようなルールで階層構造を作り、どのようにリファレンスをするかの指針で
使用される情報です。

Kind や ModelHierarchy だ一体どういうものかというのは Kind と Model と ModelHierarchyので
そちらを参考にしてもらえればですが、
Kitchen_set はこの ModelHierarchy のルールにのっとって
作成されています。

Kind は、ルートの DefaultPrim を assembly それ以下の Asset をグループ化する Prim は group そして
リファレンスをしている Prim(リファレンスしたモデルの Transform の値を持つ Prim)には component とつけます。
この component は「leaf model」と呼ばれていて、ModelHierarchy の概念では末端の構成要素になります。
そのため、Component 以下には Component は作ってはいけないことになっています。

Info

これは可能ではあるものの、USD のコンポジションやレイヤーの構成上
シンプルな状態を保つ(いくらでも複雑化できるけど、適切に扱える範囲に整理する)ための
ルールです。
もちろん、このルールに沿わなくてもシーンの構築は可能ですが、
あまり推奨されません。

Kitchen_set のアセットは、

各アセットの RootPrim に対して、component が指定されています。
つまり、アセットを配置すれば、そのアセットは Model として扱われ
PickMode でリファレンスした Prim を掴むようになるわけです。

Kind 指定によるモデルのピックアップ

上記に書いた通り、各アセットに対して適切に Component を指定している場合

レイアウトする場合は、TreeView などではなくビューポート上で選択して移動したいということは
よくあると思いますが、
usdview の Pick mode を Models にすることで、
ビューポートでピックする場合、MeshPrim ではなく Component の Prim(Model の Prim)を選択できるようになります。

Instance

サンプルの Kitchen_set.usd とはべつに、もう1つインスタンスで配置した Kitchen_set_instanced.usd があります。
USD の Instance は、「同じ」オブジェクトのインスタンスが、UsdStage 上で同じ Prim を共有する機能ですが

参考: https://graphics.pixar.com/usd/release/glossary.html#usdglossary-instancing

instanced.usd の場合は、各アセットが Payload で呼ばれているのは共通ですが
それに加えて「instanceable」が True に指定されています。
instanceable とは

Instanceable is a metadatum that declares whether a given prim should be considered as a candidate for instancing
引用元: https://graphics.pixar.com/usd/release/glossary.html#instanceable

とあるとおり、インスタンス化の候補とみなすかどうかの宣言です。
このあたりはまた別の記事に使用と思います。

まとめ

以上、Kitchen_set の紹介でした。

個人的に、私はおそらく日本で一番この Kitchen_set を見ているんじゃないかというぐらい
日ごろからあらゆるツールで開いたり、Python を使って Traverse したり観察していますが
USD の学習を進めるたびに、個のサンプルデータを見ることで新たな発見をする事が良くあります。

今回の USD アドカレ、あるいはそれ以前から書いてきた USD の記事を通じて
USD の解説をしてきましたが、
その多くが、この Kitchen_set を見ることで理解できます。
ぜひともこれを機会に、記事を見ながら Kitchen_set を
usdview SOLARIS python omniverse Blender Maya 等々 USD に対応した様々な環境で観察してみると
USD を導入する上で、あるいは勉強する上で、大きな助けになるのではないかと思います。