美文网首页程序员
Houdini学习笔记 | Applied Houdini -

Houdini学习笔记 | Applied Houdini -

作者: 大师的学徒 | 来源:发表于2020-04-19 01:35 被阅读0次

    IsoOffset节点

    可以基于原几何体生成offset关系的数据,数值>0 向外扩散,最多可扩散至物体boundingbox,<0向内扩散,fog选项配合scatter可以将点数据深入到表面以内,获得更好的破碎效果。


    isooffset 后的 fog volume, 非常均一化

    此时fog的浓度是均匀的,意味着破碎效果也比较单调。既然fog是volume的一种形式,那么就可以用volume vop来修改density属性。通过创造不同的浓度,达到不同大小碎块的破碎效果。

    用原始density和turbnoise相乘得到新的density,

    需要注意noise产生随机值,而density值必须>=0,用max函数设定最低值,从而达到过滤掉负值的目的。

    添加ramp parameter

    可以在noise后加入ramp parameter,需要将数据类型改为float,ramp会自动promote到vop节点界面,通过调节曲线获得理想状态。


    volumeVOP界面中的ramp

    Voronoifracture的算法

    假设基于scatter只有两个点的平面来做fracture,得到如下图


    可以看出分割线在两点的中线上

    assemble节点

    类似pack节点的算法,勾选Create Packed Geometry将mesh数据转为代理,并不占用当前内存,将用于voronoifracture解算的点作为数据,即,当前点数即为当前数据量,大大节省数据负荷。


    原始Mesh不再占用数据,只有scatter生成的20个点坐标

    注:同时可以在此基础上对点的位置进行修改,以达到理想的视觉效果。

    assemble以后的rbd packed object

    此时rigidbodysolver 需要接受rbd packed object 的输入才能正确解算。

    针对rigidbody solver,可以输入pop force 或者在popwrangle用表达式输入,例如

     @P.x = @P.x + 0.1;
    

    即为当前输入点在x方向持续添加0.2的位移,结果和在pop force 中添加x方向速度基本一致。

    关于voronoiFracture中取消掉的cluster选项,可以参照如下链接
    https://www.sidefx.com/forum/topic/59435/?page=1#post-292099
    cluster可以将距离在一定范围内的点所对应的碎块绑定在一起,节省了资源,但是由于cluster会导致Convex Hull解算出现错误,所以如果是精细镜头请谨慎使用。大场景可配合smoke和motion blur一起使用,节省解算资源。

    Houdini18 在voronoiFracture中取消了visualizer,但是考虑到碎块是由point生成的,可以加入color节点来为point增加Cd属性,值为random,然后通过voronoiFracture中的Copy Cell Point Attributes 中的To Piece Primitives来获得传入点的Cd值,从而达到visualizer相同的效果。

    更新: 也可以加入visualizer节点,用需要的属性绑定visualizer的节点也可以实现,比如当前是用点的ptnum绑定颜色Cd。这应该是visualizer节点设计的初衷吧。


    添加color节点后的效果

    此时碎块之间实际是没有相互连接的。尝试在rbd packed object中更改角速度属性,可以发现在碰撞之前碎块已经散开,合理的碰撞应该是从着陆点散开的,而不是同一时间,所以需要添加粘性约束来控制形态。

    ConnectAdjencentPieces节点

    顾名思义就是将碎块粘合,通过调节以下参数获得理想的黏连关系。


    调节Radius和Connections获得理想连接效果

    需要注意,ConnectAdjencentPieces的算法是依据碎片绑定的point,所以可能会出现实际物体和point不相连,从而造成破碎关系错误的情况,需要将mesh template仔细查看。


    图中耳朵部分和脸颊部分相连后,脸颊破碎会提前导致耳朵破碎

    PrimitiveWrangle节点

    针对primitive属性调节的VEX表达式节点

    s@constraint_name = "CoolGlue";
    f@strength = 0.05;
    

    定义约束名称为“CoolGlue”,强度0.05。
    注:由此也可以看出,可以通过并行的几个connectAdjencentPieces节点和primitiveWrangle节点来同时控制物体。

    ConstraintNetwork在dopnetwork中

    将破碎物体和约束分别接入DOPnetwork的第一个点和第二个点,接下来就可以通过语句调用,0为第一个点。这样和通过Null来调用结果是一致的。

    `opinputpath("../", 0)`
    

    将constraintnetwork节点置于gravity节点之前,SOP Path指向约束输入点,如果连接成功,Guide Option会显示蓝色。


    constraintNetwork,一端链接几何体,另一端链接glueconrel 将Data Name指向VEX中定义的constraint_name = "CoolGlue"

    注:
    1.此处的Strength值和之前定义的strength乘积为最终值。
    2.DataName必须是已经定义过的字符串,否则会导致constraintNetwork节点报错。

    同样的,如果在之前的connectAdjencentPieces和primitiveWrangle中多次定义约束,此处也可以merge多个glueConrel来调用。

    在primtiveWrangle中添加一些条件,获得更真实的碎片效果。

    s@constraint_name = "CoolGlue";
    f@strength = 0.01;
    
    if(rand(@primnum) < 0.15){
        f@strength = 10;
    }
    

    如果当前随机数返回值小于0.15 则约束强度为原来的1000倍。

    拓展阅读:
    此处rand()为随机数,houdini中的随机返回值是固定的,(不然演算每次都不一样计算机要累死了),如果想要更改随机返回值,需要更改seed。rand(@primnum)就是以每一个primitive的编号为seed来返回随机数。默认rand返回值的范围是[0, 1]内的浮点数。


    random在Expression和VEX的不同表达方式 random函数的拓展阅读

    打开Guide Geometry,发现Convex Hull并没有像直接使用Cluster一样产生重合,是因为约束将多个碎片的convexHull粘在一起,并没有独立解算。

    碎片convexHull相对独立,由于约束关系仍然绑定在一起,解算正确

    拓展阅读:

    detail表达式

    detail(surface_node, attrib_name, attrib_index)
    

    这个表达式可以用于读取 geometry spreadsheet 中detail(第四个)tab下的数值

    for each loop模块

    for each loop 在Houdini15后取消了,但是通过geometry speadsheet可以发现voronoiFracture输出的碎片“piece”对应的index统称name,所以loop循环需要的是参数"name",在H18中对应的模块则为“for each Named Primitive”,检查loop end 的piece attribute应该也是“name”。

    在for each loop 开始创建Metadate, 从geometry spreadsheet中获取数值

    通过表达式detail()从metadate中调用参数iteration

    detail("../foreach_begin1_metadata1/", "iteration", 0)
    

    其中detail()语法如下:
    detail(surface_node, attrib_name, attrib_index)
    因为iteration是一个浮点数,所以序列index为0,符合list数据特性。

    在loop中通过switch来添加丰富性
    由于switch 只接受 >= 0的整数输入,比较类判断条件的返回值True = 1 False = 0,非常适合作为输入。

    rand(12345 + detail("../foreach_begin1_metadata1/", "iteration", 0)) < 0.25
    

    此处利用iteration的值作为seed输入给rand(),
    rand()默认返回值在0-1之间。添加常量12345可以使随机值更丰富。

    注:如果添加额外条件,则一定要注意是否存在空值情况。如

    rand(12345 + detail("../foreach_begin1_metadata1/", "iteration", 0)) < 0.25 && npoints("../scatter2/" > 0)
    

    此时条件为“随机值<0.25 && scatter节点产生了point”,可能会存在缺面的情况,需要适时调整switch条件语句。

    将loop输出接入assemble节点,取代原本的voronoiFracture,获得更为细分的破碎效果,可以通过exploded view查看。
    另一方面,点数的增加又为connectadjencentpieces节点带来了新的数据,从而有产生计算错误的可能,如下。


    在耳朵附近又出现了bug,通过降低search radius可以改善

    另:此时预览动画,发现有些碎块碰撞不自然,检查rbdpackedobject发现,Convex Hull解算出了问题,可能是由于loop内再次细分导致。

    勾选为每个几何体单独计算convexHull

    此时如果用copy节点复制多个物体碰撞有两种方式

    *1.将约束和dop节点同时置于copy节点后

    这样是把copy后的点云共同计算,当单体间距较大时可以保证效果,当单体间距变小时可能会出现互相约束的问题。


    复制后的点云整体运算,导致单体之间出现了相互约束

    另,通过观察geometry spreadsheet,发现copy后的name其实是重复了单位几何体的矩阵(piece155在2*2的矩阵中共出现了四次),所以输出到约束的点只是单个几何体约束的复制,相应的解算也会出现问题。


    当前物体为156个点(从0开始),name重复了四次,然而点云总量已成倍增长

    *2.将copy后的点云重新命名并输出给约束

    此时由于约束只作用在了一个原几何体,导致解算出现问题

    name相同而空间位置不同的点云会导致约束解算失败,
    为了达到最理想的效果,需要把复制后的每一个点单独添加到约束内,进一步明确name的指向。

    通过pointWrangle节点,以@ptnum为后缀,重新为字符串name命名

    通过pointWrangle节点,将name以点的index序号来重新命名,这样保证了name唯一性,约束解算也变得合理。
    语句为:

    s@name = sprintf("piece%d", @ptnum);
    

    最终多物体碰撞效果


    四个猪脸砸地上

    总结:

    1.随时检查rbdPackedObject 里的Convex Hull;
    2.随时检查connectAdjecentPieces里的约束是否合理;
    3.随时查看Geometry SpreadSheet,观察当前节点内的数据类型;
    4.巧妙运用判断语句与 switch 的输入;
    5.voronoiFracture产生的碎片内面是不带UV的,但是会将内面分在inside组下面,可以用UV unwarp 和UV Layout配合重新排布UV,需要注意不要和外部UV重合。

    相关文章

      网友评论

        本文标题:Houdini学习笔记 | Applied Houdini -

        本文链接:https://www.haomeiwen.com/subject/bhfbvhtx.html