すあまの備忘録

誰得内容の自分のための非営利目的備忘録ブログ(筆者がわかっても内緒にしてください)

Solaris - 空フレームがある場合のUSD CacheとVisibility

08/11:hipのエラー修正

こういうことをやりたい人がどれだけいるかわからないですが、忘れないようにメモ。

かなり無理矢理解決しているのでもっと効率いいやり方がありそうな気もする。

シーンファイル

usdexportCustom_v2.hiplc - Google ドライブ

・Houdini 19.5.682 ・ファイルを使用してなにか起きても何も責任は取りません。

最終的なSubnet

問題

・空フレームが存在することがあるため空フレームをVisibilityのオンオフで制御したい。

・巨大なファイルサイズでもVisibilityのオンオフで制御したい。

・レンダー効率のためにhuskの-restart-delegateは使いたくない。

⇢USD Export (1 File)で書き出したときのような動作をシーケンスで達成したい。

USD Export (1 File)

USD Export (1 File)で書き出す場合はTrack Primitive Exsistence to Set Visibilityがオンであれば自動で可視不可視のチェックをしてくれる。

ただこれも万能ではないので、タイムスライダーより狭い範囲のキャッシュを撮る場合は前後の空フレーム部分がHoldされる。

USD Export (Sequence File)

シーケンスをシーケンスのまま$F4などを使用してLOPに読み込むと警告は出るのとレンダーシーン書き出し時にStitch処理が走ることを除けば割とほしい結果が得られる。

ただし、モーションブラーがちゃんとかからない。

$F4で読み込んだ場合

正しく計算したモーションブラー

Cacheノード(Motion Blurノード)とかを使おうとしてもたいていエラー

Geometry Sequence ノード

これとCacheノード(Motion Blurノード)を使えばブラーも掛けられるし、シーケンスファイルで扱える。

ただし、USDファイルは読めないので基本的にbgeoでの運用になる。

しかもこの方法は問題があり、基本レンダーシーンのUSDファイル内にGeometryが書き込まれる。

そのためレンダーシーンが肥大化&ファイルサイズが大きすぎると落ちる。

一応、レンダーシーンのUSDファイルをSeparate Layersにし、Geometry SequenceのLayer Save Path等を設定しておけば所定の場所に分割してファイルを書き出せる。これでメモリ不足等は少し解消できる。少し。

huskのオプション

USD Stitch Clips ROPを使用したとしても、USD Stitch Clipsだと空フレームがあった場合のVisibilityのオンオフが記録されないため

husk(バッチレンダリング)経由でレンダリングした際に問題が発生する。

フレーム 1 2 3 4 5 6 7 8
キャッシュ なし なし なし なし あり あり あり あり

上記のような状態で、1~5fをレンダリングすると5fはレンダリングされない。なぜかというとUSD Stitch ClipsはデフォルトでVisibilityにTime Sampleがないため、レンダリングを始めた最初のフレームのVisibilityの値を取得してしまい、非表示になる。

これはhuskのオプションにある--restart-delegate nのフラグを使用することによって回避できる。

ただしヘルプにもあるとおりレンダーシーンを都度再構築するためレンダリング効率が落ちる。

解決!

キャッシュ書き出し時にVisibilityのTime Sampleを含ませる方法。

USD Stitch Clipsにはそのようなオプションは見当たらないため、どうにかVisibilityにTime Sampleをいれる。まあ要はUSD Stitch Clipsの元のValue Clipを使って0から組む…

Render, Proxy

どうせ書き出す処理作るならProxy Geoも作りたいのでこんな感じに。

Houdiniで作るFXキャッシュは重いのでProxy GeoもBBOXでいいかなということでメインはBBOX

※BBOXの形状をしたポリゴンです。

Render Geo

Proxy Geo(bbox)

Proxy Geo(User Input)

BBOXを作る処理

path Attributeがある場合の回避

このpath階層でいいかはどうかはおいておいて単純な回避の方法。

何もないとpathがこうなりがちで/render階層が消失する。

SOPの段階で以下VEXを使用してpath階層をちょっと書き換える。

string path = s@path;
int check = re_find("/", path, 0, 1);
if(check == 1) {
    s@path = slice(path, 1, len(path), 1);
}

そうすることで自動的に/render/path〜〜になる。

USD Stitch

TOPを使い各種必要なファイルを書き出したものをUSD Fileとして結合する部分。

全体図

TOPで書き出したtopologyファイルをSublayerで読み込み、

別途元々のシーケンスファイルをValue Clipで読み込む。

Configure PrimitiveでPurposeをRenderとProxyにする。

同じことをProxyでも行い、WrangleノードでProxyのValue Clipファイルから取得した値からVisibilityを設定する。

Run on Elements of Array Attributes等を忘れずに設定する。

usd_setvisibilityは0か2で設定しないと正しく親の値を継承できないので注意

usd_setvisibility

string children[] = usd_childnames(0, "/proxy");
string path = "/proxy/" + children[0];
int check = usd_attriblen(0, path, "points");

if(check == 0) {
    usd_setvisibility(0, @primpath, 0);
}else{
    usd_setvisibility(0, @primpath, 2);
}

この部分はPayloadやAssemblyの階層を作っているだけなので省略

TOP

全体

RenderとProxyのGeoを両方シーケンスで書き出して両方終わるのを待機

その後以下Pythonでtopologyとmanifestを書き出す。

※雑なのでたまにエラーで落ちます。ちゃんと使う場合は見直しましょう。

import os
import glob
from pxr import Sdf, UsdUtils

out_path = str(work_item.attribValue("outputDir"))
purpose = str(work_item.attribValue("purpose"))
result = out_path + "data/" + purpose + ".usda"
clipPath = "/" + purpose
seq = glob.glob(out_path + purpose +"/*")

topologyLayerName = UsdUtils.GenerateClipTopologyName(result)
topologyLayer = Sdf.Layer.FindOrOpen(topologyLayerName)
if not topologyLayer:
    topologyLayerGenerated = True
    topologyLayer = Sdf.Layer.CreateNew(topologyLayerName)

manifestLayerName = UsdUtils.GenerateClipManifestName(result)
manifestLayer = Sdf.Layer.FindOrOpen(manifestLayerName)
if not manifestLayer:
    manifestLayerGenerated = True
    manifestLayer = Sdf.Layer.CreateNew(manifestLayerName)

UsdUtils.StitchClipsTopology(topologyLayer, seq)
UsdUtils.StitchClipsManifest(manifestLayer, topologyLayer, seq, clipPath)

元となっているPython$HFS/bin/usdstitchclipsです。必要そうな記述の箇所を抜き出して作ってるのでちゃんと読んで再構築しましょう。

Pythonでのtopologyとmanifestの書き出しが終わったら、すべてをStitchのUSDファイルを書き出します。

完成

取り敢えずこんな感じの階層になるように書き出してます。

Proxyを書き出しているのでViewport上は設定した軽いジオメトリが表示されます。

レンダリングすると実ジオメトリに。

/geo階層をPayloadしているのでUnloadも可

VisibilityのTime Sampleもあるのでちゃんと表示非表示が切り替わります。

もちろんMotion Blurも。