原視頻:https://www.youtube.com/playlist?list=PLzRzqTjuGIDhiXsP0hN3qBxAZ6lkVfGDI
Bili:Houdini最強VEX算法教程 - VEX for Algorithmic Design_嗶哩嗶哩_bilibili
Houdini版本:19.5
1、什么是SDF
Houdini支持兩種體積類型,它自己的體積格式(也有兩種,Fog 和SDF )和VDB格式。
Volume的兩種類型:Fog volume和SDF volume。是Houdini自帶的不同類型的體積,特點是每個體素都有值。Volume(體積)由voxel(體積元素,后面簡稱為體素)組成。
Fog volume實際是儲存了每個體素的密度,常應用于流體模擬等。(想了解可以前面的第10節筆記)
SDF volume中(SDF Signed Distance Filed 是帶符號的距離場),每個體素存儲了一個數值,數值大小表示到表面的距離,正數代表在物體外,負數代表在物體內,0表示在物體表面(需要精度較高)。所以將幾何體轉化為碰撞物的時候,實質就是轉化為SDF,利用體素的數值來判斷是否發生碰撞等。
更多體積相關可以看這篇文章的簡單介紹:Houdini中體積SDF/fog/volume/db的一些理解和區別
2、SDF節點及參數
①創建一個類型為Polygon的Sphere節點,再添加一個vdbfrompolygons節點,及一個VolumeWrangle節點,
②用上面為例,講講vdbfrompolygons節點的一些設置,
③我們僅保留點,看看vdbfrompolygons節點設置的具體表現,
?第三、四、五張圖為用點代替體素,的一個截面,
?3、volumegradient函數?
volumegradient() 函數返回一個向量值,該值為距離值遞增方向的矢量值(下面試試讓這個值代替體素的法線),(gradient的中文感覺總差點意思,后面還是以英文代替吧),
4、使用Fog Volume可視化SDF值
挺簡單的,還是記錄下,
5、使用VEX對SDF輪廓簡單修改
可以直接修改SDF的【@surface】值,來實現物體表面/輪廓的改變(對輪廓進行偏移操作),
值相加,物體的表面/輪廓向內偏移,即收縮;
值相減,物體的表面/輪廓向外偏移,即擴大;
eg.簡單記錄下,感興趣可以試試,
?6、Exercise—修改SDF輪廓與Animated
基于時間和三角函數,對SDF輪廓進行動態修改。
eg.直接使用【5、使用VEX對SDF輪廓簡單修改】的案例,僅對VolumeWrangle節點進行修改,
float val = sin(@P.y * $PI * chi('num') + @Time * 10) * chf('dist');f@surface += val;
結果為:在 num = 6,dist = 0.07條件下,
7、修改SDF的Gradient值
還是基于三角函數對物體輪廓進行偏移,比上面的稍微復雜一丟丟, 不曉得可以應用到哪方面(云層?),還是記錄下。
eg.先上結果,
①節點及設置如下,
②對offset_with_voxel_val_and_gradient節點的一些補充,
float val = f@surface;
vector dir = volumegradient(0, 'surface', @P);//頂視圖視角下,Gradient值與dirXZ.x值的夾角
vector dirXZ = dir;
dirXZ.y = 0.0;
dirXZ = normalize(dirXZ);
float ang = atan2(dirXZ.z, abs(dirXZ.x));
//atan2返回兩個向量之間的夾角
//因為atan2三角函數范圍是-π到π,所以使用絕對值abs,使其范圍為0到π//多重映射
float v = sin(ang * chi('num')); //值范圍-1到1
v = fit11(v, 0, 1.0); //重映射,值范圍0到1
v = chramp('ramp', v); //繼續重映射,隨便設
v = fit01(v, 0.0, chf('dist')); //重映射,值范圍0到【自定義】f@surface += v; //結合sin函數的規律,去理解v值的變化
?8、SDF與基礎碰撞
挺簡單的,僅記錄下,
9、Exercise—SDF碰撞與Animated
與上類似,不過這次加入解算器,讓小球在Grid上轉動,也不算復雜,記錄下,
10、Exercise—SDF Gradient與向量Animation
點由內向外運動,運動方向位gradient。
eg.先上結果,原模型為橡皮模型,
①節點連接及設置,(代碼在下一個案例),
11、基于SDF的擴展向量場
大概與上類似,不過加入了curlnoise() 噪波函數,讓其運動起來跟隨噪波特性(隨機但又有序)。
eg.先上結果,
?①直接使用【10、Exercise—SDF Gradient與向量Animation】的案例,下圖為節點連接及設置,相同設置部分不再贅述,② 完整代碼如下,
// copy SDF節點代碼
vector dir = volumegradient(1, 'surface', @P);
vector cdir = curlnoise(@P * chf('smoth') + @Time * chf('speed')) * chf('scale');v@velocity = normalize(dir + cdir);
// move節點代碼
float val = volumesample(1, 'surface', @P);
vector dir = volumesamplev(3, 'velocity', @P);
//vector dir = volumegradient(1, 'surface', @P);if(val >= 0.0){ //在輪廓外面的點重新實例化vector pos = point(2, 'P', @ptnum);@P = pos;
}@P += dir * chf('speed'); //點沿法線/gradient方向移動
@N = dir;
f@val = val;
// pointwrangle3節點代碼(最后一個節點)
int pt = addpoint(0, @P + @N * 0.5);
setpointattrib(0, 'Cd', pt, v@Cd);
int line = addprim(0, 'polyline', @ptnum, pt);