すあまの備忘録

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

Solaris - テクスチャのランダムオフセット

Instanceを使わずにテクスチャをランダムにしたり、個々でオフセットしたりする方法。

もちろんInstance状態にできたほうがいろいろ都合が良いしやりやすいと思う。

他にもあったら知りたいです。

まとめ

手法 設定しやすさ レンダーシーンの負荷 Prim毎の階層
Material Variation 1 簡単 必須
Material Variation 2 簡単 必須
VEX 少し手間 不要

hip

textureRandom.hiplc - Google ドライブ

Houdini 20.0506

使うマテリアルは共通でこれ

MaterialX系ノードはStringの扱いが微妙なのでUSD 〜を使います。

USD Primvar ReaderでTexture Pathを格納するPrimvar名を決めます。※なんでもOK

Material Variation 1

Copy to Points下後にAssembleでnameを作る。Packはしない。

LOP階層はこうなる

Material Variationを繋いで以下設定にします。

Primitivesで/grid/以下のすべてのメッシュを指定し、先程作ったUSD Primvar Readerで設定したPrimvar名をいれる。

index=Primitiveの番号なので、以下VEXをでそれぞれ1~6の数字が作成されて蝶の画像がかわる。

ただしPrimitiveの順番などが指定できないため、Primitiveが消えたりするとランダム値がおかしくなる。ずっと固定ならこれが簡単でいい。

int frame = index%5 +1;

string dir = "$HH/pic/";
string filename = "butterfly";
value = dir + filename + itoa(frame) + ".pic";

Material Variation 2

最後のVEXだけ処理を変える。indexではなく、SOP上で作成したrndIDというidを元にランダムにする。

こうすることでPrimitiveが消えてもランダム値が固定できる。

SOP Import/USD Exportでここを設定しておくこと。

usd_primvarでrndIdを各Primitiveから取得している。

int frame = usd_primvar(0,@primpath,"rndId");
frame = frame%5 +1;

string dir = "$HH/pic/";
string filename = "butterfly";
value = dir + filename + itoa(frame) + ".pic";

VEX

nameで階層を切りたくない場合は多分これしか方法がない。が、SOPで言うPrimitive(ポリゴン面)ごとにPrimvarを作成するので重くなりがち。

Run on Elements of Array AttributesとArray Lengthを両方使うことで、指定したPrimvarの配列でVEXを処理できる。今回はランダムの元になるアトリビュート、rndIdを使っている。

重くなりがちなので、処理する対象のPrimitivesはマッチングパターンの併用でなるべく最小を目指す。作例では%descendants(/grid) & %type:Mesh

usd_setprimvarelementやusd_setattribelement等の配列に書き込む系VEXをを使用した後は必ず、usd_setprimvarinterpolationを使用してその配列アトリビュートの保管方法を指定すること。これが間違っていると正しく表示されなかったりする。シェーダーで使う場合はほぼuniformで問題ない。

int frame = usd_primvarelement(0,@primpath,"rndId",@elemnum);
frame = frame%5 +1;

string dir = "$HH/pic/";
string filename = "butterfly";
string path = dir + filename + itoa(frame) + ".pic";

usd_setprimvarelement(0, @primpath, "tex_path", @elemnum, path);
usd_setprimvarinterpolation(0, @primpath, "tex_path", "uniform");

この手法はこういうモザイク画像も作れて面白い使い方ができる。

面ごとにPrim Num = rndIDにしたもの

番号を4桁等にする

sprintf('%04d',frame)

にすると4桁になる。