Houdini カールノイズ関数について

Houdiniにおけるカールノイズについて。

カールノイズを使用したサンプルファイルでよく見かけるのは
「CurlNoiseノード」を使用した以下のようなVOPネットワーク。

CurlNoiseノードが返すベクトルは湧き出しや吸い込みがない(発散がない)流れ場を構成するが、
CurlNoiseノードにはSDFSigned Distance Field)が接続できるようになっているので
ボリュームとの衝突を回避させることもできる。

CurlNoiseのCurlとはベクトル解析におけるベクトル場における回転を意味する。
ベクトル場に対してこの「回転」という演算を施せば、ある地点の渦度を表すベクトル(回転軸+回転の大きさ)が手に入る。また、ベクトル解析の基本公式により、回転演算によって求めたベクトル場には発散がないことが保証される。(この「発散がない」ことによってパーティクルを「いい感じ」に流すことができる)

しかし実は、このVOPノードに1対1で対応するVEX関数はヘルプには記載されていない。
ヘルプに記載されている以下の2つのカールノイズ関数(curlnoise関数、curlxnoise関数)は
位置に応じたカールノイズは生成できるが、衝突用のSDFボリュームを渡すための引数がない。

vector  curlnoise(vector xyz)
vector  curlnoise(vector4 xyzt)

しかし、以下のようにVEXコードの先頭でvoplib.hをインクルードすることで
CurlNoiseノードに対応するVEX関数(vop_curlNoiseVV関数)を使用することができるようになる。これによりVEX関数だけで障害物ボリュームとの衝突を避けつつ、発散がない流れ場に沿ってポイントを移流させるアニメーションが可能となる。

#include <voplib.h>

v@curlnoise = vop_curlNoiseVV(
    @P, 1*{1,1,1}/*周波数*/, {0,0,0}/*オフセット*/, {0,0,0}/*法線ベクトル(0の場合はSDFからgradient(勾配)を自動的に計算)*/,
    "pnoise"/*ノイズタイプ(Perlin Noise)*/, @OpInput2/*衝突用のSDFボリューム*/,
    3/*乱流*/, 1/*衝突の際に速度の反転*/,
    0.3/*振幅*/, 0.5/*粗さ*/, 1/*減衰*/, 
    0/*サーフェイスまでの距離(衝突ボリュームを設定しない際に有効)*/, 
    0.1/*衝突回避処理を発動する際のサーフェイスからの距離*/, 
    0.0001/*ステップサイズ*/);

@v = {0,0.2,0}+v@curlnoise;// 上昇するよう+Y軸方向に指向性を与えて速度とする
@v = clamp(@v,-0.4,0.4);// 速度の大きさに制限をかける
@P += @v*@TimeInc;// 速度から位置を求める積分計算

実際のVEXは以下のようにSolver内のWrangleノードに書いてやればよい。


vop_curlNoiseVV関数は、2007年のRobert Bridson氏の論文
「Curl-Noise for Procedural Fluid Flow」を忠実に実装したものとなっている。
https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph2007-curlnoise.pdf

 

ちなみに、CurlNoise VOPノードを右クリックして「View VEX Code」を選択すると
VOPが生成するソースコードを見ることができる。
そこでvop_curlNoiseVV関数の名称が確認できる。


vop_curlNoise関数は2つあるが、それぞれ以下のような役割。
vop_curlNoiseVV関数 → 最初の引数にvector(位置)を渡す。vectorが返る
vop_curlNoiseVP関数 → 最初の引数にvector4(位置+時間)を渡す。vectorが返る

【まとめ】カールノイズを使用するメリット
1.  VEX関数のみで吸い込みや湧き出しのないベクトル場が作成できる
2.  SDFボリュームを関数の引数に設定すれば、障害物との衝突を回避しながらの移流ができる
3.  SOPだけで計算が完結するため処理が軽い

Windowsではvoplib.hは以下のパスにある。(**はバージョン)
(C:\Program Files\Side Effects Software\Houdini 17.
.***\houdini\vex\include)