• Houdini Volume Deform 奇 思


    最近在做Houdini Volume的一些结算,工作的过程中突然闪现一个想法,可不可以把Houdini 中 Point Deform 节点的原理和算法运用到Volume上 ? 经过测试, 发现是可以的。

    Point Deform 是根据 模型的变形(Geometry Deform) 来改变点的位置。利用模型的变形的好处是:模型本身的点相对少,内存占用少些,效率更高。Volume Deform 运用Point Deform相同的原理,利用模型变形的信息的话,会继承它的这些优点。

    在这之前想说的是,还有很多Volume Deform的方法,这里只是提供另一个思路~

    测试的Demo如下:

    这题的框架如下图:

    其中compute_xforms_sequential是Point Deform节点中对应的相应节点,注意的是我测试用的Houdini版本是16。目前houdini 18的话,Point Deform会:如果模型中(第二个端口)存在id属性,会优先使用id,而不是ptnum(点号)。

    上图中VolumeDeform的参数和代码整合如下:

     // vex

    // ************************************************
    // Capture and CaptWeights
    // ************************************************
    float radius = ch("radius");
    int maxpt = chi("maxpt");
    int minpt = chi("minpt");
    
    int pCaptPts[];
    float pCaptWeights[];
    
    pCaptPts = pcfind(1, 'P', @P, radius, maxpt);
    if (len(pCaptPts) < minpt)
    {
        pCaptPts = pcfind(1, 'P', @P, 1e15, minpt);
        radius = 1.1 * distance(@P, point(1, 'P', pCaptPts[-1]));
    }
    
    foreach (int pt; pCaptPts)
    {
        float r2 = distance2( vector(point(1, 'P', pt)), @P );
        r2 /= radius*radius;
        float weight = 1-r2;
        weight *= weight;
        //weight = 1-weight;
        
        push(pCaptWeights, weight);
    }
    
    // ************************************************
    // Compute Offset
    //*************************************************
    float totalweight = 0;
    vector delta = 0;
    matrix3 totalxform = 0;
    vector offset;
    foreach (int idx; int pt; pCaptPts)
    {
        vector oldcenter = point(1, 'P', pt);
        vector diff = point(2, 'P', pt) - oldcenter;
        matrix3 xform = point(1, 'xform', pt);
        float weight = pCaptWeights[idx]; 
        
        // Compute our new location according this xform.
        vector newp = @P;
        newp -= oldcenter;
        newp *= xform;
        newp += oldcenter;
        newp += diff;
        diff = newp - @P;
        delta += diff * weight;
        totalweight += weight;
        totalxform += xform * weight;
    }
    
    delta /= totalweight;
    //@P += delta;
    offset = delta;
    
    if (totalweight > 0)
    {
        totalxform /= totalweight;
        if (chi("rigidprojection"))
            totalxform = polardecomp(totalxform);
       
    }
    
    // ************************************************
    //Deform
    // ************************************************
     f@density = volumesample(3,0,@P + offset);
    View Code

    另外的思路

    //利用 Tetrahedral Mesh 来Deform Volume,在Applied Houdini - Volumes VI 中学的新思路

     主要是利用了tetrahedral mesh的一个特性,tetrahedral mesh是由一个个四面体组成的,而且是实体的四面体,基本结构如下图:

    tetrahedral mesh 很重要的一个特性 ,是用xyzdist 函数时, 比如

    int prim;
    vector uvw;
    xyzdist(1,@P,prim,uvw);
    v@pos = primuv(1,"P",prim,uvw);

    使用xyzdist采样第二个接口的tetrahedral mesh时, 如果这个点在tetrahedral mesh的体积内,最终的pos其实就是当前点的位置 即 @pos等于@P;如果在tetrahedral mesh的体积外,位置就有误差了。这也侧面解释了,如果对tetrahedral mesh变形用力过大,比如组成它的某个四面体,如下变形(翻转了,1点本来在2、3点的左边,后来跑右面了)

    这种变形过大的情况会造成Volume Deform的误差。

    利用这个特性,完全可以先变形tetrahedral mesh,然后利用primuv得到点在变形后的tet mesh的prim和uvw,再根据prim,uvw得到点在原始的tet mesh中的位置信息,最后用得到的位置信息采样原始的Volume,结构如下图

    pointwrangle2中的代码如下:

    int prim;
    vector uvw;
    
    float dist = xyzdist(1,@P,prim,uvw);
    vector origP = primuv(2,"P",prim,uvw);
    
    @density = volumesample(3,"density",origP);
  • 相关阅读:
    index()方法
    extend()方法
    count()方法
    copy()方法
    clear()方法
    append()方法
    IE botton 点击文字下沉
    IE滚动条
    关闭windows10自动更新
    vue文件名规范
  • 原文地址:https://www.cnblogs.com/peng-vfx/p/12495492.html
Copyright © 2020-2023  润新知