1-4期
195人加入学习
(33人评价)
Houdini 影视特效实验班

6个月零基础到入职

价格 ¥ 6198.00
教学计划
承诺服务

主体闪电上自己创建的四个初始属性,第一个i@branch_time属性用来规定分支闪电的存在时间,初始值是8帧到15帧之间;   

 

i@branch_count属性用来规定分支闪电的数量,初始值是-1,表示现在还没有任何分支闪电。主体闪电上的点每找到一个分支闪电的目标点,那么就会形成一个分支闪电,这个属性的值就加1;   

 

并且可以拿i@branch_time属性的值和i@branch_count的值做一个比较,当i@branch_count的值大于i@branch_time属性的最大值的时候,就可以让大于15的分支闪电清除掉;         

 

i@branch_point属性是用来记录主体闪电上的点找到了哪些分支闪电的目标点,初始值是-1,表示主体闪电上的点还没有找到任何一个分支闪电的目标点;

 

v@Cd属性是用来做debug的,初始值全部设置成黑色

 

i[]@already_taken属性是一个数组,同样也是用来存储被找到的分支闪电的目标点的序号,初始值只是一个{},代表是一个空数组,还没有写进任何点序号,这个属性的作用是这样的,比如分支闪电的目标点上有一个序号是147的点,主体闪电上有一个序号为444的点,主体闪电上序号为444的点找到了分支闪电的目标点上序号为147的点,由此创建了一根分支闪电,那么主体闪电上别的点也有可能找到分支闪电的目标点上序号为147的点,也由此创建了一根分支闪电,这样形成的分支闪电就很奇怪,为了避免这种情况,分支闪电的目标点每被找到一个通过append函数被储存进i[]@already_taken属性这个数组中,再通过find函数,确认被找到的分支闪电的目标点的唯一性,那么主体闪电上别的点再去找分支闪电的目标点便会跳过这个已经被找到了的点

[展开全文]

guiding surface: 动态的碰撞对象,来控制水的运动

 

guiding sink: 如果有的粒子进入到guiding surface场里比较深, 那这个场就会删除这些粒子,只保留一层, 会回流到上面的粒子中去

 

如果洋面太汹涌,打开gas guiding volume中 stick on guiding surface选项, stick scale如果为1, 则粒子完全跟随guiding surface运动, max distance设置为1, 即只有1米深度的粒子跟随

[展开全文]

wavetank设置: velocity标签下,max extrap cells选项, vel场往外推测的最大数量, 这个数值越高,速度匹配越精准,这里使用8, 影响产生多大的波浪,如果想要更大的波浪,就调大这个数值

 

boundary layer:边界缓冲区域,防止流体模拟时在边缘反弹回来

 

surface evaluation:

主要是max resolution设置, 影响精度,但是不需要特别高的精度,默认8就可以

[展开全文]

在SDF外的数值大于0, 在SDF内侧的数值小于0, 在SDF表面的数值为0

[展开全文]

popinteract节点:

position force为1: 为排斥力

velocity force为1: 让周围粒子找相邻,共享一个相同的速度,这样就可以有这种条状的效果

[展开全文]

oceanfoam解算器下 downsample为降低分辨率, 降低为2的()次方, 输入1, 即为降低2的1次方

[展开全文]

VOP中mix节点: 设置一个0-1的bias值, 当为0时使用的是input1, 为1时使用的是input2, 中间进行差值(本例中是基于寿命)

[展开全文]

最后already_taken并没有被写上数字,失败了,还要回去多检查几遍代码。

[展开全文]

当速度和角速度都小于某一个数值的时候就让速度和角速度乘一个0.97,以此来拖慢速度和角速度,实现拖拽的作用,这是在DOP网络里,所以实际上是当速度和角速度都小于某一个数值的时候每一帧都会在上移帧的速度和角速度基础上乘以0.97

 

f@cumulative_movement += length(v@v);

在DOP网络里,每一帧都会加上后面设置的速度的模的值,根据后面这句话int bool_A = f@cumulative_movement > chf("cumulative_threshold") ? 1 : 0;是表明一定要有速度之后,才会进行下面的if语句,使碎块进入睡眠状态,避免了刚开始因为碎块都没有动,所以碎块的速度和角速度都为零,小于我们自己设置的阈值,那么所有的碎块就永远都会是睡眠状态

 

@bullet_sleeping是houdini识别的属性,1代表碎块进入睡眠状态,0代表碎块没有进入睡眠状态

[展开全文]

 

dopimport节点 DOPnetwork表示要导入哪一个DOP网络节点,object mask表示导入该DOP网络节点中的哪一个object对象。可以填写数字,在DOP网络中,每一个object对象都有相对应的objectID编号,数字几就代表导入相对应objectID编号的object对象,如果有多个object对象就用空格隔开数字。相应的表达式则是‘dopobjscreatedby("要导入的object对象的路径")’,同理如果是多个,用空格键隔开

import style要选择 create point to represent object 选项,创建点来表达来代理对象,一个是因为在刚体模拟中,刚体本来就是被当做点来计算,选别的会报错,二个是因为后期要读取这些点的矩阵信息来使静态的碎块动起来

[展开全文]

在SOPsolve节点里面,第四个节点objectmerge节点是导入约束线,  第一个节点dop import是导入在DOP网络中进行模拟的碎块,每一个作为碰撞的节点都会有一个objid的编号,在geometry spreadsheet面板进行查看,如果创建了地面,那么地面编号为零号,剩下RBDpackedobject节点按照merge的左右顺序进行编号 

objectmask这个参数表示按照编号选择导入哪一个RBDpackedobject节点

约束是不参与动力学模拟的,是永远不动的,如果希望约束跟随碎块的运动而运动,那么需要借助参与刚体模拟中的碎块所产生的一个属性packedfulltransform,这是一个3*3的矩阵,包含参与刚体模拟中的碎块的scale transform rotation信息,可以利用这个信息使约束线随着碎块的运动而运动,而约束线获取碎块的运动依赖的则是name属性 name属性是字符串形式的属性,用s来表示

nametopoint函数是获取点序号,第一空是查找的对象,第二空是具体查找哪些点,在这里,哪一些点有name属性,那么就被查找到,并且把该点所对应的点序号存储起来   

primintrinsic函数是获取参与刚体模拟中的碎块信息,第一空是查找的对象,第二空是查找对象上哪一个属性,第三空是具体哪一些点

因为packedfulltransform是一个矩阵信息,所以需要用一个matrix的变量储存起来

约束线在DOP里边是作为primtive来进行识别的,所以要把@break_me属性从点级别推送到面级别上

 

removeprim函数是删除prim,第一空是要删除的对象,第二空是具体删除哪些面,第三空是如果说这个prim上连接有点,这些点是否删除,1代表删除,0代表不删除

[展开全文]

当进行约束的时候不能使用packed物体进行约束,这样会导致约束不够精确,所以需要解包packed物体。 约束是给点与点之间进行连接,依据的是点上的name属性的名称,所以需要保留name属性,这样面层级上的name属性就会相应的转移到点层级上,面层级上的name属性就没用了,为了防止后边计算出错,删掉面层级上的name属性

constraint属性是字符串类型属性,所以需要用单引号引起来,并且是运行在面层级上的属性,在DOP里,glue constraint raletionship节点以及其他约束类型节点都是根据我们设置的constraint_name属性的名称来进行识别的

 

f@strength属性是作为胶水强度的倍增器来使用 

i@break_me属性是后期用来给是否删除约束线做判断条件的,设置的初始数值是0,当这个数值为1的时候,就删除掉这些约束线

 

[展开全文]

在18的版本里面,当碎块做了簇之后,assemble节点不需要勾选create name attribute选项,不然packed物体数量会计算出错  packed的name属性的名称在rbdcluster节点的cluster name prefix选项里面定

[展开全文]

float ramp = fit(found_distance, 0, radius, 1, 0));

这句话是说把零号输入端的点找到的一号输入端的距离重新fit成1到0,然后init_v属性再乘以这个值,会使越接近一号输入端的点的零号输入端上的点上init_v属性的值越高,         但是我认为如果只是想单纯的给init_v属性做扰乱的话,让它的大小不一致,不如直接在下面接一个pointVOP节点来做大小的扰乱,如果是说需要一个由大到小的渐变,才使用这种方法

[展开全文]

在while点云循环里边point.distance是houdini里边默认的一个值,代表零号输入端的点找到的一号输入端的点的距离,如果说零号输入端和一号输入端的点有重合,那么最小值就是0,最大值是我们设定的搜索半径的值

point.distance这个值通过pcimport这个vex语言被储存到我们设定的临时变量found_distance里面,再把这个值重新fit成我们需要的值,并且把这个值作为一个属性,应用到别的节点上

chramp()括号里边第一空是我们要创建的ramp的名称,需要使用引号引起来,第二空必须是一个零到一的值,因为ramp贴图横轴和纵轴的值都是零到一,然后把ramp贴图进行fit,横轴和纵轴零到一的值全部fit成我们需要的值,并且把这个值作为一个属性,应用到别的节点上

[展开全文]

vector center = point(1, "P", @id);

vector center_N = point(1, "N", @id);

v@N = normalize(@P - (center- center_N * chf("chenter_offset")));

 

这几行vex语言其实就是拿点的位置减去中心点的位置得到一个矢量,然后那这个矢量和一个向前的矢量进行mix

 

 

i@has_been_activated 这个自己设置的属性是用来限制速度的,如果没有这个属性,那么被激活的碎块的速度,每一帧都会加上之前设置的init_v属性的值,这样就会让碎块无限远的飞出去

 

@w属性表示的是角速度(在视图中表现的即是碎块的自转),角速度的单位是弧度,弧度有正负,逆时针为正,顺时针为负,1弧度约等于57角度,一个圆360度,大概要6个弧度来表示

[展开全文]

connectivity是把碎块给区分出来,polysoup实际上就是把每一个碎块变成一个面(polysoup使用前提是面上不能有组)然后方便后面测量周长或者面积

 

findattribval(1, "prim", "prim_fragment", i@prim_fragment); 这个是来查找序号的。     第一空是查找的对象,第二空是要查找的属性的层级,第三空是要查找的属性的名称,第四空是要查找的属性的某一个数值。  比如说第四空是5,那么该属性的值为5对应的序号就被找到了

 

f@pscale = prim(1, "area", num);  prim和point函数的作用是一样的,分别对应不同的层级而已,即是把被找到的点或者面的属性的值,放入零号输入端设定的属性上。      第一空是查找的对象,第二空是要查找的属性,第三空是具体要查找的是哪一些点或者面

 

 

[展开全文]

插补技术,ramp插补技术,

lerp(@P,pos

[展开全文]

tetrahedralize节点:四面体化, 可以让空心几何体填充四面体

[展开全文]

在缓存写出前,由于vel场储存信息太大,而只是单纯的被用来渲染运动模糊., 所以可以使用volume resample来重新采样vel场, 使用一半的分辨率

 

使用volume compress压缩, 使用volume blur模糊density, 使blur以外的场都被压缩成0, 可以再次大大减少大小  mask minimum,设置为0.01, 即density低于0.01的也被视为0

[展开全文]