Stage/Layer/Spec
Universal Scene Description 8 日目は、 USD の Stage と Layer、そして Spec とはなにか?というのを説明していこうと思います。
Stage とは
USD に触れていると、この「Stage(ステージ)」という言葉はあらゆるところで見られます。 アドカレ2日目の記事曰く
しかしちょっと待ってください。USD では厳密に言うと、 usda ファイルとは「私はこうしようと思うんだけどな」という 計画の記述 なのです。 従ってこの時点ではまだ誕生はしていません。そうなんです。実はあなたの他にも神がいるのです。 八百万の神々が集まり本当に世界を生み出すところは出雲(Stage)と呼ばれますが、 その話はこのアドカレの別の記事 で @fereria さんが明らかにしてくれるでしょう。
ということで、今回はその Stage と現在開こうとしている USD ファイルとの違い 八百 万の神々が集まり本当に世界を生み出すところは出雲(Stage)について詳しく説明したいとおもいます。
USD と今までのフォーマットとの違い
多くのフォーマット(FBX だったり、OBJ だったり、GLTF だったり)では、 1つのファイルに1つのシーングラフが保存されています。
なので、たとえば複数に分かれた FBX をレンダリングする場合などに Maya でインポートなどをした場合も、それはあくまで1つの Maya シーンになる(統合される) だけで、Maya シーンが複数の FBX を持っているわけではありません。 (追いかけようとした場合は、別途なにかしらの情報を持っておく必要がある)
ですが、USD の場合はコンポジションアークによって 複数の USD ファイルが合成されて、その結果1つのシーングラフになります。 そのため、 開いた USD ファイルと実際に出来上がったシーングラフは一致しません。
このあたりは具体的な例を見ていったほうがわかりやすいので、Kitchen_set をみていきます。
Kitchen_set でみる Stage そして Layer
Kitchen_set をダウンロードして解凍したフォルダ内には Kitchen_set.usd というファイルがあります。
usdview D:\Kitchen_set\Kitchen_set.usd
このファイルを、 usdview で開くとこのように Kitchen_set が表示されます。 開くと、モデルが配置されていて1つの完成されたシーンになっています。
ですが、この Kitchen_set.usd を、 を使用してアスキーファイルでどうなっているかを見てみます。
usdcat D:\Kitchen_set\Kitchen_set.usd
実行すると、このような usda で表示されます。 見てわかる通り、ここにあるのは Xform(Maya でいうところの Group ノード)と リファレンスをしている Prim(Kitchen_1 等)と、その配置情報(xformOp:translate)のみが 書かれているだけで、Mesh の情報などは見当たりません。
つまりは、開いているファイルは Kitchen_set.usd ではあるものの このファイルに書かれているのは「私はこうしようとおもうんだよな」という主張(オピニオンと呼ぶ)が書かれているだけで、 これが最終的なシーングラフの形ではありません。
この計画の記述が書かれているファイルのことを、USD では Layer(レイヤー)と呼び このレイヤーがコンポジションによって組み合わされた結果出来上がったものを Stage と呼びます。
実際に配置されているオブジェクトは、 add references = @./assets/Kitchen/Kitchen.usd@ とか書かれている通り Kitchen_set/assets/Kitchen フォルダ以下にあります。
このアセットフォルダ以下も、1つのファイルではなく複数ファイルで構成されています。 このあたりの詳しい事は別途記事にする予定です。
Layer と Spec
Kitchen_set だと複雑なので、もっとシンプルな usd ファイルで確認してみます。
このような、samplePrim に sampleValue = false を設定したレイヤーと そのレイヤーをサブレイヤーしているレイヤーを用意します。
この2つの Prim を usdcat を使用して Flatten(コンポジションした結果)を表示してみると このようになります。
書き表すとこのようになります。
Stage は、コンポジションアークによって(この場合 サブレイヤー によって合成された結果出来上がったものです。 今回のサンプルならば、 subLayer.usda と root.usda が合成された結果出来上がったシーングラフが Stage です。
Layer と Stage、というのの何が違うのか?というのは、 たとえるなら PhotoShop のレイヤーがわかりやすいです。
このような赤いレイヤーと青いレイヤーがあった場合、最終的に表示される色は何色になるでしょうか。 上にあるレイヤーが赤なのだから、赤!とも思えるかもしれませんが
合成方法が乗算なら
黒になります。
今は2つのレイヤーだけでしたが、これがもっとレイヤーが増えて、フォルダでまとめられていたりしたら? 重ね方が複雑になっていたら? レイヤーにある絵がなんであろうと、最終的にすべてが合成されるまでどんな絵(どんな色)になるかはわかりません。
これと同じ考え方が USD にもあります。
PhotoShop のレイヤーが、すなわち USD の Layer = usd ファイルにあたりますし、 キャンバス上に表示されている最終的な絵が Stage です。
この合成前の USD の Layer 内にも Prim や Property の記述はあります。 ですが、これは最終的な形と同じとは限りません。 なぜならば、ほかのレイヤーによって上書きされている可能性があるからです。 PhotoShop の別のレイヤーに別の何かが書かれていて絵が上書きされるように、 Prim や Prim に指定されている Property は別のレイヤーによって上書きされる可能性があります。
そのため、USD では合成前のレイヤーに書かれている記述を「Prim」とは別に 「PrimSpec」
A PrimSpec can be thought of as an “uncomposed prim in a layer”. 引用: https://graphics.pixar.com/usd/release/glossary.html#usdglossary-primspec
レイヤー内にある 「合成されていない Prim」 として区別して呼びます。 Property に関しても同様に「PropertySpec」と呼ばれ、合成後とは区別されます。
図に書き出すと、Layer 内に記述されている内容はこのようになり、
すべての Layer が合成された結果、出来上がったものが Stage であり Prim であり、Property です。
言い換えるならば、 各 Stage にある Prim や Property とは多くのレイヤーに記述されている PrimSpec あるいは PropertySpec の寄せ集められた(合成された)結果とも言えます。
usdview で確認したい場合
この Layer や PrimSpec、PropertySpec は usdview の Layer Stack と Composition で確認することができます。
samplePrim を選択すると、この Prim がどのレイヤーにどのように定義されていていたのか 結果どのような SdfPath になったかがわかりますし、
Property の場合は、
Composition を見ると、sampleValue の Composition には2つのレイヤーに主張(オピニオンと呼ぶ)があり レイヤー内に Spec (合成されていない「合成予定のもの」)があると示す Has Spec が yes になっています。
さらには、 Layer Stack を見ると、それぞれのレイヤーにある Value(PropertySpec)が書かれていて どのような順番で合成されて、結果なにになったか(上のほうが強い)がわかります。
これは、これよりも多くのレイヤーで、複数のコンポジションが絡んできても同様で、たとえば Kitchen_set を見ると
どのレイヤーで定義されているのか、 そのレイヤー内のどの PrimSpec(LayerStack に書かれている Path が、PrimSpec の Path)がもとになっていて
それら PrimSpec が、 どのようなコンポジション順序によって、結果この Prim が出来上がったのかがわかります。 (Composition の ArcPath が PrimSpec の Path)