houdini中不得不掌握的技术集锦(4) Vex编程入门I
—— 微资讯 · 微课程 ——
利用零碎时间,走上超神之路!
原文地址:http://www.tokeru.com/cgwiki/index.php?title=HoudiniVex
由CG猎人独家翻译,转载请注明
昨天文章里面介绍了vops使用,也解释了为什么不使用hscript和其他节点进行操作的原因,现在我们就来学习强大的VEX语言,虽然说是编程语言,但是是我见过最简单的的了。
所以你已经放弃了hscript,忽略python了,法线了vops的强大的之处。你也应该开始好奇为什么houdini会有至少4种方法来定义点的属性,都带有各自的偏好。是时候开始学习Vex,特指使用wrangle sop。
wrangle sop节点让你可以写一小段vex代码。同时附带UI提示让它更加快速和高效地使用。他支持多种层级 (point, prim, detail, attribute),其实都是一样的东西。只是在我在操作哪个层级上切换point/prim/detail。
入门学习wrangle最好方法就是添加一个40*40的grid,添加一个pointwrangle节点,然后按着下面操作:
1创建一个新的属性
2获得已有的属性
3隐式和现式属性类型
4创建UI控制
5自定义UI元素
6常用函数
7内置属性
8案例,基于阈值随机删除点
9案例,波浪变形器
10属性VS变量
1创建一个新的属性
如果你想定义一个新的浮点属性 foo?直接输入就可以了
@foo;
点击ctrl+enter,在geometry spreadsheet中查看,你就获得了这个foo属性。@符号代表你想要一个属性,默认类型是浮点,如果你想初始化赋值
@foo=1;
如果你想创建也该适量?在@前面添加一个v标识符。初始化数值的需要使用大括号{}进行三个元素的赋值或者使用set()函数进行赋值
v@myvector={1,0,3};v@other=set(0,@P.x,1);
你可以设置属性类型使用类似的方法
// 常用类型f@foo =12.234// 浮点i@foo =5// int 整形v@myvector={1,0,3};// 矢量// 没那么常用p@george;// 四元素vector3@transform;//3*3的矩阵还有更多,可以直接查看官网地址http://www.sidefx.com/docs/houdini15.0/vex/snippets#attributes
2获得已有的属性
如果你想定义一个名字为myvector的适量变量来存储点的位置 v@myvector=@P;
@符号不仅仅用来设置变量,也可以用来获取变量。所以你在geometry spreadsheet中看到的属性都可以通过在名字前面添加一个@活动它,比如N与1.5相乘v@myvector=@N*1.5;
要获得矢量或者颜色中某个通道的值,可以使用@name.格式活动。比如活动每个点y轴的位置并且除以2@foo=@P.y/2;
可以让某个通道之更小,比如设置红色通道的值为点位置x的2倍然后求正弦@Cd.r= sin(@P.x*2);
矢量属性比如颜色和位置有多种方法获得子元素,使用哪个你觉得方便的: r/g/b, x/y/z, [0]/[1]/[2].下面这三个其实代表一样的意思@Cd.r=1;@Cd.x=1;@Cd[0]=1;还有下面这个,都是设置位置的第三个元素
@P.z=6;@P.b=6;@P[2]=6;
3隐式和现式属性类型
主要到houdiniwrangle中默认会识别一些常用的属性的数据类型 (@P, @Cd, @N, @v, @orient)。但是,如果你自定义自己的属性,houdini会默认假设它是一个浮点类型除非你制定了他的数据类型,这个容易犯错
确保houdini运行正确,在属性前面添加属性类型符号,比如,你定义一个矢量@mycolor,在wrangle中使用
错误方法BAD@Cd =@mycolour;默认mycolor会认为是浮点,所有只有红色通道被赋予了值
正确方法GOOD@Cd = v@mycolour; 精确告诉houdini myvector是一个矢量值。
我经常忘记写前面的数据类型,然后做不出效果就埋怨wrangle节点,最后发现是自己的我问题。
4创建UI控制
如果你想wragnle会自动创建一个滑竿让你控制一个效果的缩放?@Cd.r= sin(@P.x* chf('scale'));点击wrangle节点文本框输入中右上角的按钮,houdini会自动扫描代码,查找你需要的scale通道。意识到你引用的通道scale不存在的时候,会自动在wranle节点底部创建一个滑竿通道名字是scale。滑动滑竿,你会看到颜色在变化有很多通道类型你可以使用那个。ch()和chf()都是创建一个浮点通道,还有其他:// 整形通道创建 chii@myint = chi('myint'); // 矢量通道创建chvv@myvector = chv('awesome');// 渐变通道创建chrampf@foo = chramp('myramp',@P.x);最后一个相当的方便,只用了一行代码,你就可以基于@P.x位置x轴使用ramp ui渐变控制,把结果赋予给foo。我经常使用这个设置,但是要确保 @p.x的值范围似乎0-1.如果不是可以使用fit函数(输入的最小值,输入的最大值,输出的最小值,输出的最大值)float tmp = fit(@P.x,-0.5,6,0,1);@Cd.r= chramp('myramp',tmp);还可以更进一部,使用UI定义最大最小值float min = ch('min');float max = ch('max');float tmp = fit(@P.x, min,max,0,1);@Cd =0;
5自定义UI元素
那个右上角的plug按钮是个方便的功能,自定扫描你通道参考数值,然后创建默认类型,并且设置一个默认值。一旦这个值设定好,那么你可以在wrangle节点上右击然后选择 'edit parameter interface' 编辑参数面板命令(也可以使用参数面板右上角的次轮下拉选项)可以修改默认的范围,默认值和标签名字,任何你想改的东西。
一个很方便的事情是我经常把默认的适量通道修改为颜色通道,我会在vex中做我想要矢量。根据个人偏好,把show color修改为hsv slider,很方便。
v@colour1 = chv('col1');v@colour2 = chv('col2');v@colour3 = chv('col3');v@colour4 = chv('col4');
然后我点击plug按钮,编辑参数面板,shift点选我需要修改的通道,改变数据类型为color,然后
6常用函数
下面这些基本上是我99%会用到的 的vex 代码
- fit() - 适配范围
- rand() - 生成一个随机数值
- sin(), cos() - 正弦函数和余弦函数
- radians() -把角度转弧度
- length() - 测量一个矢量的长度
- distance() - 测量连个矢量的距离,比如 dist = distance(@P, v@mypoint);
7内置属性
下面是一些内置属性,默认可以使用,如果要快速查看直接创建一个point节点,看里面的参数面板
- @ptnum - 点序号
- @numpt - 点总数量
- @Time - 时间,单位是s
- @Frame - 帧
- @primnum - 面序号
- @numprim -总的面数
8案例,基于阈值随机删除点
自从 Matt Ebb 给我展示了这个技巧,我基本上每天都用到无数次,撒点,然后连接一个wrangle节点
if( rand(@ptnum)> ch('threshold')){ removepoint(0,@ptnum);}
使用plug 按钮来创建 threshold滑竿,0-1的滑动,你可以看到点被随机删除,发生了什么事情?
rand(@ptnum) 每个点基于id获得一个随机的值,这个值范围是0-1;
ch('threshold'),把随机值和threshold进行对比,如果这个值更大,那么执行后面的命令
removepoint(0,@ptnum) 删除这个点,0的意思是第一个输入端口的物体,@ptnum就是满足条件的点。
9案例,波浪变形器
回到最开始让大家创建的一个40*40的grid
我们需要从中心向四周组波浪渐变效果,我们需要测量每个点和中心的距离
@d = length(@P);
我们把这个结果赋予给sin值,然后用来控制没有p位置中y的值
@P.y= sin(@d);
然后我们需要一个滑竿来控制
@P.y= sin(@d*ch('scale'));
点击plug按钮,调整滑竿,你而已看到波浪移动,如果要想波浪动画,引入时间
@P.y= sin(@d*ch('scale')+@Time);
现在波浪是向中心移动的,要制作向外移动
@P.y= sin(@d*ch('scale')-@Time);
然后又添加多一个滑竿控制速度
@P.y= sin(@d*ch('scale')+(ch('speed')*@Time));
感觉有点混乱了,不过好处是wrangle可以让你重新整理,让我们分成几行。
让我们增加两个属性,一个是最大高度值,一个是基于衰减的距离控制
高度值很好控制,只需要在最后三角函数乘以一个倍增的值就可以,如果是1保持不变,如果是0则为平面,其他数值可以控制不同的缩放
@P.y*= ch('height');
最后面使用一个ramp来控制衰减。ramp 控制需要一个0-1的范围取值,所以第一步我们获得juice变量,使用fit函数适配到1,0(这里需要注意的是我们需要的是1-0而不是0-1,因为我们希望中间高度是最大,)开始和结束的点可以通过channel控制
@falloff = fit(@d, ch('start'), ch('end'),1,0);
一个ramp函数需要一个名字和一个变量,这个变量会被重新适配到ramp curve,我们会得到结果然后直接和P.y想成
@P.y*= chramp('falloff',@falloff);
一个让人恼火的问题是我希望这个开始和结束的位置是以世界坐标为单位,但是结尾通道是个很大的数值。我意识到这是应为我们之前已经相乘一个通道来控制波浪的数量,快速调整代码如下
@d = length(@P);@speed =@Time * ch('speed');@falloff = fit(@d, ch('start'), ch('end'),1,0); @P.y= sin(@d*ch('scale')+@speed);@P.y*= ch('height');@P.y*= chramp('falloff',@falloff);
10属性VS变量
上面这个案例是使用@语法来获得和设置一个点的属性。如果你有多个wrangle节点,或者你不需要这些属性在wrangle之外被访问到,因为会让geometry spreadsheet很多属性,所有额外的属性都需要占用内存,特别是你有一个很复杂的场景的时候。
所以,你可以创建仅仅在wrangle中的变量。语法类似于其他C的语言,使用全称定义,不需要在变量前添加@符号
float foo;vector bar ={0,0,0};matrix m;
foo =8;bar.x+= foo;
点属性和vex变量是不同世界的东西,所以你可以在两套系统中使用相同的名字,他们是共存的。但是在实际工作中我尽量避免的,因为很容易搞混
float dist = length(@P);// 只有在这个wrangle节点中才存在的变量 @dist = dist;// 这个创建了一个新的 点属性,赋予了一个局部变量,其他节点都可以使用。
把上面波浪的案例重新写一遍,要先定义变量然后查看后面的代码
float d;float speed;float falloff;
d = length(@P);speed =@Time * ch('speed');falloff = fit(d, ch('start'), ch('end'),1,0); @P.y= sin(d*ch('scale')+speed);@P.y*= ch('height');@P.y*= chramp('falloff', falloff);
—— CG猎人——
微信号:Hunter_CG
QQ-540710114
为您提供最具前景的咨询与最适合的分类技术与学习教程

