本文主要是介绍第093封“情书”:三生万物Vellum Cell ReplicationPart3 <Entagma>Houdini 2019,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
▉ 一生二,二生三,三生万物。— 每天翻译一篇教程,这就是我写给houdini的情书。【首发于同名公众号:“致houdini的情书”】
█ “无生有,有生于无,自始自终,无始无终。 ”
前言不搭后语
xx。
❖设置glue组中的约束20帧分离❖
//--1 在20帧处打破glue约束
float glue_remove_age=20;
if(@age_f>glue_remove_age){
//设置的如果是胶水组的prim情况下
if(i@group_con_dyn_glue_stretch){
//--2 移除胶水里的约束prim;
removeprim(0,@primnum,1);
}
}
❖沿y轴增加最小最大age变量❖
/--3 设置最小最大age:
float glue_remove_age_min=chf("glue_remove_age_min");
float glue_remove_age_max=chf("glue_remove_age_max");
float glue_remove_age=fit01(dyn_glue_ramp,glue_remove_age_min,glue_remove_age_max);
//--4 钳制在80%的细胞分裂前,glue约束完全移除
glue_remove_age =clamp(glue_remove_age,0,@split_age_f*0.8);
❖增加避免行为❖
float search_rad = chf("search_rad");
int max_pnts = ch("max_pnts");
float inner_rad = chf("inner_rad"); //半径范围内
//--1 寻找附近点:
int pc= pcopen(0,"P",@P,search_rad,max_pnts);
//--2 创建循环
int ext_cell_id ;
vector ext_pos;
while(pciterat(pc)){
pcimport(pc,"cell_id", ext_cell_id );
ext_pos= pcfilter(pc,"P");
//--3 如果当前处理的点不是原始点;
if (i@cell_id != ext_cell_id)
//--4 计算相邻cell的方向.
vector avoid_dir = @P - ext_pos;
float avoid_amp = fit(length(avoid_dir),inner_rad,search_rad/2,1,0);
v@avoid_vec = normalize(avoid_dir)*avoid_amp;
}
}
❖设置停止分裂❖
float search_rad = chf("search_rad");
int max_pnts = ch("max_pnts");
//--1 寻找附近点:
int pc= pcopen(0,"P",@P,search_rad,max_pnts);
//--2 创建循环
int ext_cell_id ;
vector ext_pos;
while(pciterat(pc)){
pcimport(pc,"cell_id", ext_cell_id );
ext_pos= pcfilter(pc,"P");
//--3 如果当前处理的点不是原始点;
if (i@cell_id != ext_cell_id){
//--4 计算相邻cell的方向. //--5 与邻居距离
f@nb_dist = length(@P - ext_pos);
//--6 一旦距离低于这个阈值
i@split_stop = 1;
}
}
❖ ❖
首先
制作步骤
小节提要
01
设置glue胶水约束
02
手动glue约束的分离:
1.设定约束在glue组中20帧分离
2.沿y轴增加最小最大age变量
3.增加age随机性
03
增加避免行为:
1.找到中心点
2.细胞间矢量
3 把点属性复制到prim
4.创建细胞间推力
5.转换开关
04
设置停止分裂
1 当cell距离太近,没有足够空间之前,停止分裂
2 视觉化“停止分裂
05
高模映射到低模
1. foreach循环
2.合并‘高低模”
3.高模映射至低模
4.清理所有cloth属性
5.低模传递给高模属性
06
创建细胞核
正式制作
○ 节点 ○
○ 具体操作 ○
进入cell_setup里设置约束,比dopnet里设置更安全;
1)vellumglue:这个只是vellum约束,而没有初始化。
a)“约束接口”连接“merge_CON输出”
b)“几何接口”连接‘merge_GEO输出’
2)null:
a)连接“vellumglue”的“约束输出”
❖ 小目标 ❖
设置glue约束
stretch选项
a)自定义“胶水组”输出名称:勾选 Output Group=con_dyn_glue_stretch(约束动力学胶水伸展)
b)让连接更加坚固:stiffness=3000;
c)阻尼高些:Damping Ratio=0.1;
Breaking选项
a)设置断开的阀值:Threshold=0.005;
测试glue
3)blast:提取出glue约束
Glue Search选项
a)降低搜索最大值Max Search Dist=0.06
(没有连接更远的点)
❖ 小问题 ❖
现在丢失了很多点属性
❖ 解决方案 ❖
1)拷贝前面的groupcopy_pnts这三个节点
2)连接vellumglue的约束输出
3)groupcopy和attribcopy点“接口2”连接merge_GEO
回到AutoDopNet运行模拟
❖ 小目标 ❖
a)手动控制“从底部沿特定轴”慢慢上移进行约束的分离
b)这样漂移的细胞可以产生旋转。
○ 具体操作 ○
○取消“勾选Breaking”约束阈值;
B02)sopsolver_CON约束解算设置内部
○output1之前加入attribwrangle:命名_remove_glue_con
a)Run over选择primitives。
//--1 在20帧处打破glue约束
float glue_remove_age=20;
if(@age_f>glue_remove_age){
//设置的如果是胶水组的prim情况下
if(i@group_con_dyn_glue_stretch){
//--2 移除胶水里的约束prim;
removeprim(0,@primnum,1);
}
}
❖ 小目标1❖
沿着细胞裂底部到顶部增加“最小&最大age”变量
○attribwrangle_remove_glue_con:
a)...min=20; b)...max=80;
//--3 设置最小最大age:
float glue_remove_age_min=chf("glue_remove_age_min");
float glue_remove_age_max=chf("glue_remove_age_max");
❖ 小目标❖
增加特定轴
?解决方案?
prim属性:前面建立cell时的bbox边界框属性
? 操作 ?
○attribvop:命名glue_ramp:
a)bind:name=bbox;Type=vector。
b)vectortofloat:输出Y轴。
c)bind export:name=dyn_glue_ramp。
float glue_remove_age=fit01(dyn_glue_ramp,glue_remove_age_min,glue_remove_age_max);
//--4 钳制在80%的细胞分裂前,glue约束完全移除
glue_remove_age =clamp(glue_remove_age,0,@split_age_f*0.8);
❖ 小目标❖
对每个细胞随机化
❖解决方案❖
○attribvop_glue_ramp:运行在prim上
a)bind: name=cell_id; (导入cell_id) Type=整数
b)random;输出
c)mix:1)input1=y轴;2)input2=z轴;3)bias=随机输出
作为特定的随机
d)complement 求出轴,创造出两种方式;
e)twoway :
f)compare:Test=Less Than;Compare to Float=0.5
vop流程图
随机化相当多的方向
○ 节点 ○
❖ 小目标 ❖
a)运行一段时间,非常拥挤之后,会给vellum带来很多问题,所以创造一种力,把细胞彼此分开。临近cell上寻找方向,在每个细胞上形成均匀的推力。
b)如果临近cell太近,太拥挤,应该停止分裂.
❖ 具体操作 ❖
1)创建一个sopsolver:命名sopsolver_avoidance
a)连接给popdrag:
❖ 小目标 ❖
1)创建一个简单的提取-cell的中心速率信息
2)创建方向
?解决方案?
○extract centroid节点:
(另一种方法○ pack节点+ add节点=中心点)
? 阶段目标 ?
有了中心→就能找到临近cell→根据P→分析方向
→创造假的“矢量+振幅”分开它们。
振幅取决于细胞之间间距,距离越远,推力越弱。
2) attribwrangle:命名avoid_vec
a) search_rad = 2;
b) max_pnts= 5;
float search_rad = chf("search_rad");
int max_pnts = ch("max_pnts");
float inner_rad = chf("inner_rad"); //半径范围内
//--1 寻找附近点:
int pc= pcopen(0,"P",@P,search_rad,max_pnts);
//--2 创建循环
int ext_cell_id ;
vector ext_pos;
while(pciterat(pc)){
pcimport(pc,"cell_id", ext_cell_id );
ext_pos= pcfilter(pc,"P");
//--3 如果当前处理的点不是原始点;
if (i@cell_id != ext_cell_id)
//--4 计算相邻cell的方向.
vector avoid_dir = @P - ext_pos;
float avoid_amp = fit(length(avoid_dir),inner_rad,search_rad/2,1,0);
v@avoid_vec = normalize(avoid_dir)*avoid_amp;
}
}
3)attribcopy:命名“copy_from_centroid”
4)attribwrangle:命名“_avoid_force”
↑v@force += v@avoid_vec*chf("avoid_force_strength")
5)switch:命名_use_avoid_force;
selcet_Input:1
6) output:
○ dopnet内部节点 ○
❖ 小目标 ❖
当cell距离太近,没有足够空间之前,停止分裂
? 解决方案 ?
7) attribwrangle:<复制3>命名split_stop
a)不需要inner_rad ;b)Search Rad=0.79
float search_rad = chf("search_rad");
int max_pnts = ch("max_pnts");
//--1 寻找附近点:
int pc= pcopen(0,"P",@P,search_rad,max_pnts);
//--2 创建循环
int ext_cell_id ;
vector ext_pos;
while(pciterat(pc)){
pcimport(pc,"cell_id", ext_cell_id );
ext_pos= pcfilter(pc,"P");
//--3 如果当前处理的点不是原始点;
if (i@cell_id != ext_cell_id){
//--4 计算相邻cell的方向. //--5 与邻居距离
f@nb_dist = length(@P - ext_pos);
//--6 一旦距离低于这个阈值
i@split_stop = 1;
}
}
❖ 小目标 ❖
视觉化“停止分裂”
3)attribcopy_copy_from_centroid:
a)增加aplit_stop属性
8) visualize
a)红色禁止分裂,当达到一定的距离为止。
现在只剩下“分割停止属性”放入解算器
○ attribwrangle_split_age_group
//--检查年龄到达split_age//--到达不停止分裂时间
else{
if (@age_f>=@split_age_f && i@split_stop !=1)@group_split =1;
}
○ 节点 ○
○ 具体操作 ○
❖ 小目标 ❖
每一个循环再做一次.
? 解决方案 ?
○ For-each Named Primitive:
a)Piece Attribute:cell_id
cell_setup层级高模“OUT_cell_hires_geo”合并进来
○ object merge:命名“_hires_geo”高模
○ object merge:命名“_init_geo”低模
○ clothcapture:Radius=0.1;
○ clothdeform:
○ clothdeform:
:
○ attribtranfer。
○ null:命名OUT_cell_surface.
○ 节点 ○
? 解决方案 ?
使用VDB
○ null:连接vellumpostprocess输出
❖小目标❖
分裂的细胞共享一个细胞核,然后缓慢的分裂
○ For-each Named Primitive:
a)对cell_id进行循环。
b)循环中
1)vdbfrompolygon :○ VoxelSize=0.02
2)vdbreshapesdf1 :扩展一下
3)vdbsmoothsdf :平滑
4)vdbreshapesdf2 : 收缩
5)vdbsmoothsdf 2 : 平滑
6)convert VDB:convert to=polygons
○ null2:OUT_cell_core_surface
○ 节点 ○
○ 具体操作 ○
1)复制OUT_cell_core_surface
1)为OUT_cell_core_surface创建一个单独容器
○ geo命名“cell_cores”
1)object_merge:引进OUT_cell_core_surface
2)复制cell_cores命名“cell_surface”
1)object_merge:引进OUT_cell_surface
公众号:微信号
这篇关于第093封“情书”:三生万物Vellum Cell ReplicationPart3 <Entagma>Houdini 2019的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!