Houdini Grain 学习笔记

// Grain 使用PBD算法,说白了就是先更新位置,再更新速度,Houddini Masterclass Grain 中的案例有一些简单的实现(最基本的原理)

 比如跟新位置(这里为了简化Jeff 把粒子的pscale大小都看成一样),如果粒子有重合, 直接更改位置

int n[] = pcfind(0, 'P', @P, @pscale*2, 100);

vector change = 0;
float weight = 0;
foreach (int npt; n)
{
    if (npt == @ptnum)
        continue;
    vector op = point(0, 'P', npt);
    float d = length(op - @P);
    if (d < @pscale*2)
    {
        change += normalize(@P-op) * (@pscale*2-d)/2;
        weight += 1;
    }
}
@P += change / weight;

如果考虑质量的话,大概的算法:

int n[] = pcfind(0, 'P', @P, @pscale*2, 100);

vector change = 0;
float weight = 0;
foreach (int npt; n)
{
    if (npt == @ptnum)
        continue;
    vector op = point(0, 'P', npt);
    float d = length(op - @P);
    if (d < @pscale*2)
    {
        float omass = point(0, 'mass', npt);
        float ratio = omass / (@mass + omass);
        change += normalize(@P-op) * (@pscale*2-d) * ratio;
        weight += 1;
    }
}
@P += change / weight;

然后再根据位置的变化更新速度

if (i@has_pprevious)
    @v = (@P - v@pprevious) / @TimeInc;

注意POP Grain 节点会在粒子上添加一个属性 ispbd 值为1 , 这样POP  Solver 就 不会更新P (位置) ,只在POP Grain 节点中更新

 //  Grain 中mass为0时的 特殊意义

如果粒子的属性mass值为0(特殊值),代表的意义是粒子质量无穷大,这样根据上面的算式  

float ratio = omass / (@mass + omass);
change += normalize(@P-op) * (@pscale*2-d) * ratio;

omass 是搜到的附近的粒子的质量,@mass 是粒子自身的质量,@mass无穷大, ratio无穷接近0

在试验中,在grainsource节点后选中上面的粒子,建组zero_mass

然后在popnet 中,popwrangle,

第一句 float @mass = 1 必不可少啊(Bug ), 他的作用是为所有的粒子声明创建一个属性,初始值为1,看起来只给zero_mass组里面的操作,实际不是:(

下面一句才是只是对zero_mass组里的粒子操作,mass值为0

这样,上面的粒子静止,下面的粒子由于重力散开, 图为结算第一帧和第14帧对比

原文地址:https://www.cnblogs.com/peng-vfx/p/9626512.html