很久以前看巫妖王之怒開場動畫的時候就一直在想那把劍上的魔法是怎樣做的,最近做了一個類似的實驗完成了一個簡易的屬性傳遞模型,這個方法能夠適用於熱量傳遞,腐蝕或者蔓延的效果。
模型的原理是使用點雲中的pcfilter()函數來將目標屬性是進行類似模糊的擴散,同時使用sop中的solver來將模糊值進行累加,並定義如果該值累加超過一定閾值之后便不會再繼續增加,這樣就產生了擴散的這個效果。本人在之前Gray Scott Reaction-Diffusion 文章中也提到了擴散的一個方法,不過那個方法更適用於一定總和的值在點之間均勻的攤開,而現在的這個方法是入侵式的擴散。
在做好擴散的方法后就是定義非均勻的方法,這個能夠增加更多的趣味性,也讓擴散顯得更加自然。方法是給每個點通過noise定義不一樣的擴散速率。然后用這個擴散速率在累加過程中乘以擴散值。noise圖案的不同能夠產生多種不一樣的侵襲擴散效果。
在傳入solver之前,我在每個點上定義了 float heat(傳遞屬性), float factor(傳遞速率), int edge(判定擴散邊緣)這三個屬性,並提前設定了屬性擴散開始的點和factor的值。
下面是在solver下point wrangle里面用到的核心代碼:
//search the pre frame point cloud,
//point number will affect the sensitivity of diffusion
int handle = pcopen(1, "P", P, 99, 8);
//get the global speed
float speed = chf("speed");
//get the loacl speed of each point
float factor = f@factor;
float threshold = 1.0;
//excute diffusion fuction if the attribute is less than the threshold
if (f@heat < threshold){
float influence = pcfilter(handle, "heat");
f@heat += influence * speed * factor;
//the attribute value cannot be bigger than threshold
if(f@heat > threshold){
f@heat = threshold;
}
// define the edge area
if(f@heat < threshold && f@heat > 0.03){
i@edge = 1;
}else{
i@edge = 0;
}
}
pcclose(handle);
@Cd = set(f@heat,0,0);
代碼其實除開注釋,基本上就十行左右,簡單但是效率和效果都非常的好。這里主要是利用好的pcfilter這個函數。