CompArc(1) サブレイヤー
前回ざっくりと個々のコンポジションアークの概要をしたので
これからは個々のコンポジションについての動作を説明していきたいと思います。
まず第一回は「サブレイヤー」について。
サブレイヤーとは
サブレイヤーとは、プログラム言語的に言えば「Import」や「Include」
DCC ツール的に言えばシーンのインポートに近い処理です。
図で表すとこのような処理になります。
各レイヤーごとのノードツリーの階層構造を維持しつつ
同階層がある場合はいいかんじに階層を維持しつつ
レイヤーをまるごとマージしていきます。
ルートレイヤーとは
まず個々で新しく「RootLayer」と呼ばれる概念が出てきました。
これは、ざっくり言うと「現在 開いている USD ファイル」が RootLayer となります。
サブレイヤーの評価は、RootLayer つまりは現在開いたレイヤーから見て
一番遠いレイヤーから上書きして行きます。
散々参考にだしているこの図で言うと
まず base.usda を usdview で開いてみると緑の玉が出てきます。
#usda 1.0
def "Model"
{
def Sphere "Sphere"
{
rel material:binding = </Material/MyMat>
}
}
def "Material"
{
def Material "MyMat"
{
token outputs:surface.connect = </Material/MyMat/testShader.outputs:surface>
def Shader "testShader"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0, 1, 0)
float inputs:metalic = 0.9
float inputs:roughness = 0.2
token outputs:surface
}
}
}
usda の中身はこんな感じ。
次に add_color.usda を開いてみると
見た目はこのように「赤い Sphere」が出ています。
usda を開いてみると
#usda 1.0
(
subLayers = [
@base.usda@
]
)
over "Material"
{
over "MyMat"
{
over "testShader"
{
color3f inputs:diffuseColor = (1, 0, 0)
}
}
}
こうなっています。
このフォーマットを見てみると、
上の base.usda に対して testShader にある inputs:diffuseColor = (1,0,0) だけが書かれ
かつレイヤーのメタデータ内に subLayers がある事が分かります。
!!! info
プリムの定義部分は、他では def ~~~ になっ ていましたが
このファイルの場合 over になっています。
これは、サブレイヤー時に「もし定義がなければプリムを作らず、あったら上書き」
という定義になります。
なのでこの例の場合、「マテリアルの定義がすでにあったら、diffuseColor を赤にする」
という意味になります。
繰り返しになりますが、USD の特徴はコンポジションをしてシーンを構築していくことにあります。
それはどういうことかというと
各 USD は「他のレイヤーとの差分を、それぞれ保持」しているという事です。
サブレイヤーに限らず、コンポジションアークでレイヤーを合成するときには
この差分情報を評価し、最終的なステージのシーングラフを構築します。
なので、最後の final.usda を開いたときにこのような Cube が出てきますが
#usda 1.0
(
subLayers = [
@add_color.usda@
]
)
over "Model"
{
def Cube "Sphere"
{
}
}
マテリアルの色情報や構造は base.usda + add_color.usda の情報が来ていますが
最後の final.usda で、形状の Sphere プリムを Cube にオーバーライドしているので
形状が Cube に変化しつつも
差分情報以外はサブレイヤーの情報が引き継がれていることが分かります。
評価順序とレイヤースタック
それぞれのレイヤーが差分情報を持ち、オーバーライドされていくのはわかりましたが
では、このレイヤー結合はどのような優先順位で評価されるのでしょうか。
サンプルシーンで試してみます。
#usda 1.0
(
subLayers = [
@subA.usda@,
@subB.usda@
]
)
def "testPrim"
{
}