Houdini学习笔记020_VEX使用思路
VEX在Houdini中可用于多个模块中,包括材质渲染相关、合成、建模、粒子、毛发等等。不管用在哪里,我们应当知道,使用VEX肯定是为了解决某个具体的问题。而这种以问题为导向的学习能够帮助我们快速领会VEX的思路,锤炼我们解决问题的能力。

所以这一篇我打算用一个具体的例子来讲解VEX的用法。例子很简单,就是线条的弯曲。正常情况下,我们肯定会使用Bend节点来做。设置好Capture Direction和Capture Length分别与线条的方向和长度一致,改变Bend参数的值就可以得到线条弯曲的效果。

但假设现在我们遇到一个极端情况,Bend节点用不了了,或者有人拿刀架在你脖子上说用Bend节点者死,弯不了也得死。那我们该怎么办呢?
这时候,VEX节点就可以派上用场了。我们分析可知,线条的弯曲实际上是每个点的坐标发生了变化。当这种变化满足某种关系时,看上去刚好符合弯曲的效果。所以这里可以用Point Wrangle节点,目的是重新定义点的坐标。
至于弯曲效果中点坐标如何变化,属于几何计算的范畴。这里直接给出结果如下图所示。在弯曲的过程中线条总长度保持不变(这里L=1),弯曲角度即弧线所对的圆心角,据此可求出特定弯曲角度下弧线对应的圆周半径。而线上每个点的坐标可根据角度α求出,角度值跟其点序号有关。假设线上的点序号为从0到N,那么第n个点对应的α角为θ×n/N。

有了以上数学关系后,剩下的就好办了。这里我们先定义最主要的变量:bend_angle(弯曲角度),即θ,写法如下(变量类型为浮点型)——

Bend作为一个可调节的参数,可点击属性面板右上角的齿轮,选择Edit Parameter Interface选项。然后设置取值范围Range为0~360度。

最后的计算中都用到了R和α,为了不用重复书写,可以先单独定义这两个变量的值。变量类型均为浮点型。n和N分别为@ptnum(点的序号)和@numpt-1(@numpt为点的总数,减去1是因为序号是从0开始的)。$PI就是π,radians()函数是将角度值转为弧度值,后面的正余弦计算都要用到。如果不用radians函数,也可以先乘以π再除以180度。

有一点要注意的是,在除法计算中,如果是两个整数相除,得到的结果仍取整数(直接省去小数部分),如3/5 = 0。而3.0/5 = 0.6。所以上面的@ptnum/(@numpt-1)最好写成@ptnum/(@numpt-1.0)。
接下来分别计算@P.x和@P.y的值即可,也可以写作@P[0]和@P[1](x、y、z分别对应于第0、1、2位的数值)。

滑动Bend参数的滑块,就可以看到弯曲效果了。

现在还有一个问题是当弯曲角度为0时,按上式计算出的半径R值为无穷大,其实就是保持原来直线的形状不变。实际运行过程中,我们会看到所有点都归到了原点,这显然是不对的。

所以我们可以给点坐标计算加一个条件,当弯曲角不为0时才执行上述计算。使用的是if语句,if后的小括号 ( ) 内是判断条件,!=是数学中的不等于;再后面执行的计算过程由于是多行语句,要用花括号 { } 括起来。如下图所示——

然后整个弯曲的效果就实现了——

折腾了半天,我们又实现了一个Houdini中本来已有的节点效果。这个例子帮助我们梳理了一遍用VEX写表达式的流程,实际的Bend节点功能当然不止这些,还涉及到弯曲对象的体积外框范围,弯曲的轴向等。我们可以猜想,这些功能也是能在VEX中实现的。
末尾再补充点变量的命名规则吧,主要注意以下几点:
变量名称只能包含字母、数字和下划线,如newpos、offset1、rand_number;
不能以数字开头,也不能是纯数字,反例如123、4connect都是不行的;
不要使用关键字和函数名作为变量,如float、rand等;
区分大小写。
建议使用简短且有一定描述性的词组作为变量名,连接处可采用下划线或首字母大写的方式,如new_class、myName等。
今天的笔记就写到这里,感谢大家的阅读,下回见~