很久以前看巫妖王之怒开场动画的时候就一直在想那把剑上的魔法是怎样做的,最近做了一个类似的实验完成了一个简易的属性传递模型,这个方法能够适用于热量传递,腐蚀或者蔓延的效果。
模型的原理是使用点云中的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这个函数。