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幀對比

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM