SOLARISで理解するレイヤー・ステージ
前回書いたこちらの記事「Pythonで始めるUSD」をベースに
これをHoudini SOLARISに置き換えることで、さらに理解を深めてみようというのが
今回の記事になります。
ステージ
HoudiniのLOP(SOLARIS)はUSDの構造を非常にわかりやすく表現しています。
LOPの世界は「Stage」と呼ばれる空間で操作します。
USDにおけるステージとは、前回にも書きましたが
複数のレイヤーを合成した結果できあがったシーングラフ
のことを指しています。
つまり、このStage以下でノードを組み合わせて出来上がった結果=ステージ
USDの合成した結果であることから、LOPは Stage という名前がつけら得れているのだと思います。
わかりやすいです。
レイヤーとノード
ステージとは、複数のレイヤーが合成された結果できあがるものであることから
このLOP世界内におけるノードが何を表しているかというと
1つのノードが1つのレイヤー扱いになっています。
たとえば、このようなシンプルなキューブのノードを作成してみます。
このノードは、
Inspect Active Layer からレイヤーの中身を確認すると、
#sdf 1.4.32
(
framesPerSecond = 24
metersPerUnit = 1
timeCodesPerSecond = 24
)
def HoudiniLayerInfo "HoudiniLayerInfo" (
customData = {
string HoudiniCreatorNode = "/stage/cube1"
string[] HoudiniEditorNodes = ["/stage/cube1"]
}
)
{
}
def Cube "cube1" (
customData = {
int HoudiniPrimEditorNodeId = 13
}
)
{
float3[] extent = [(-1, -1, -1), (1, 1, 1)]
double size = 2
matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
}
アノニマスレイヤー(メモリ上にのみ存在するレイヤー)となっていて
そのレイヤーには、「こういうPrimを作って欲しい」というオピニオン(意見)が
記述されています。
更にノードを詳しくみていくと、
ノードのInputとOutputを見てみると、
ノードのInputは「Input Stage」、Output側が「Output Stage」となっています。
つまりは、ノードはレイヤーで
「あるステージをInputとして受け取り、ノードのレイヤーを合成してその結果のステージをOutput」する
という構造になっていることがわかります。
いったんまとめると、
- LOP世界はステージ
- 1つのノードはレイヤー
- ノードはステージを受け取って、自分のレイヤー(意見)を合成してその結果のステージをOutputする
という関係性になっています。
SceheGraphTree
SOLARISにはSceneGraphTreeというパネルが存在しています。
このパネルが何を意味するかというと「現在選択しているノード(レイヤー)まで合成した結果のステージ」になっています。
例として、このようなノード構成になっていたとします。
SphereレイヤーとCubeレイヤーがMerge(サブレイヤー)されています。
選択を切り替えてみると、選んでいるノード(レイヤー)までの
シーングラフになっていることがわかります。
load Layer
このLOPにおけるレイヤーとステージについてを理解した上で
usdファイルをロードするノードを見ていきます。
USDは1つのファイルのことを「レイヤー」と呼びます。
レイヤーは、最終的にどのようなステージになるかわかりません。
たとえば、このノードでKitchen_setをロードした場合。
LoadLayerノードは、指定したFileをロードして、
Inputで受け取ったステージに対して、 Kitchen_set.usd を合成した結果の
ステージをOutputします。
なので、Load「Layer」ですがステージとしてOutputできているわけです。
Sphereレイヤーに、Kitchen_setレイヤーを合成した結果のステージは
このようになります。
RootLayer
ノード1つがレイヤー、レイヤーはステージをうけとり自分の意見を合成して
その結果のステージを出力します。
このときに、最後の末端(あるいは選択しているノード、レイヤー)のことを
USDではルートレイヤーと呼びます。
ステージは、複数のレイヤーを合成した結果であり
単純にステージを受け取った場合は「どのレイヤーを編集するか」というのは
わかりません。
ので、ステージには「EditTarget」という概念があり
ステージを経由してシーングラフを操作した場合「EditTarget」に指定された
レイヤーに対して編集が行われます。
で。
デフォルトではこの「EditTarget」は「ルートレイヤー」が指定されています。
LOPの場合は、特に変更していない場合、
末端の(選択しているノード)のレイヤーがルートレイヤー扱いになります。
なので、ノードの挙動は
- あるステージにサブレイヤーでレイヤーを追加
- そのレイヤーをEditTargetに指定して意見をレイヤーに書く
- 結果のステージを返す
となります。
レイヤーと分割
Houdiniのノードはレイヤーと同等という説明にあるとおり
ノードを接続していくと ## Layers という表示がノードの右下に表示されます。
これは、ある地点(この場合は loadlayerノードまで)のステージに
どれだけのレイヤー(なにかしらの意見を持つレイヤー)があるかどうかを
示しています。
ある地点までの合成結果=ステージ
1つのノード=レイヤー
なので、ノードを増やせばそれだけレイヤーは増えていきます。
たとえばこのような構成の場合。
Cubeレイヤー(Cubeを作れという意見を持つレイヤー)
Sphereレイヤー(Sphereを作れという意見を持つレイヤー)
Kitchen_setレイヤー(Kitchen_set.usdというレイヤー)
これらはすべて別のUSDファイル扱いになっています。
そしてその結果できあがっているステージは
「3つのレイヤー(3つのファイルを持つ)を持つステージ」
になりました。
ノード1つがレイヤーとして扱われていても、それだと粒度が細かくなりすぎて
管理できなくなります。
なので、ある程度書くノードごとの意見をとりまとめて
1つのレイヤーにまとめる処理を「Flatten」と呼び
Mergeノードの「Flatten Layers」を選択すると、
Mergeの入力されたステージの意見を1つのレイヤーにとりまとめることができます。
これで、
「Cubeをつくる・Sphereを作る意見を持つレイヤー」と
「Kitchen_setのレイヤー」
2つのレイヤーになり、
最終的に1つのステージが出来上がります。
まとめ
こんなかんじで、SOLARIS(LOP)の世界は
USDのレイヤーやコンポジションをノードでそのまま表現したもの...というのが
なんとなくわかるのではないかなと思います。
なので、前回のUSD+Pythonで説明した内容をHoudiniSOLARIS上で説明すると
USDの理解もSOLARISの理解もより理解しやすいのではないかな?
とおもいます。
Discussion