【Houdini/Vex教程】JoyOfVex中文翻译教程plus版-第01章
一套关于houdini中vex语言的系列教程
原英文系列教程地址:http://www.tokeru.com/cgwiki/index.php?title=JoyOfVex
翻译人:PB_zz
原英文教程与本人的翻译教程都是免费分享的,请勿进行盗用贩卖等行为。
本系列教程一共20篇,加上一篇关于point,vertex,primitive的番外篇。另外在原文基础上我会增加一些自己的补充内容。本套教程比较适合有一点houdini基础以及编程基础的同学。不过直接看也没有多大问题,相信大部分houdini玩家多多少少都接触过一点vex,本教程会通过案例来带你入门并熟悉vex。有些内容暂时看不懂没关系,后面的章节可能会讲到。
在站酷只发第一篇,剩下的懒得搬过来了,可以去我的B站专栏查看剩下的教程。
译者注:关于houdini中使用的vex语言,它是一种类似于C语言/C++的强类型语言,并且是SIMD(Single Instruction Multiple Data),执行效率高。具体介绍可见帮助文档,在你安装完houdini时帮助文档一般就自动安装好了,点击houdini菜单栏的Help-Contents打开。
Day 1
原作者提供了一个工程下载,这里我传到了百度网盘:
链接:https://pan.baidu.com/s/1bfjd1eu_7H8llvblQBP6fw 密码:m9f7
你也可以看图自己连下,就那几个节点,连线很简单。把四个模型连接到switch上,通过 switch进行切换来查看不同模型上的效果,switch下面按顺序连接transform,normal(Add Normals to改为Points),point wrangle三个节点。

在使用vex时,能实时看到你的模型属性受到影响改变是很重要的。有一个快捷的方法来查看这些属性变化,按住键盘上的alt+]键,来使视窗分为上下两个,然后按住alt+8键来使其中一个窗口变为spreadsheet窗口。之后,点击菜单栏上的Build,在下拉菜单中选择Save Current Desktop,这样就将当前视图设置存储为默认视图了。
Colour(颜色)
你能用vex来实现的最简单的事情之一就是基于一些属性来改变模型的颜色。在point wrangle节点的文本编辑器里,输入下面的一行代码,然后按下CTRL+回车键来执行代码。
@Cd = @N;
或者
@Cd = @P;

通过transform节点的参数来旋转/平移/缩放你的模型来查看效果变化。
译者注:Cd指对象的颜色属性,N则是法线信息,P是位置。属性之前加@号来调用。
Attribute components(属性成员)
@Cd是一个vector(向量类型),@P和@N也是,因为数据类型相同,所以他们可以相互赋值。实际上,你也可以指向sub-components(子属性),就比如用@P.x来调用位置中的x信息:
@Cd = @P.x;
N的子属性调用也是同理:
@Cd = @N.y;
译者注:还可以用rgb和数组的写法,比如@Cd.r,@Cd[0]。
此时,vex会为你做一些隐藏工作,把@P.x或@N.y的float(浮点类型)数值(比如0.2)转换为一个vector,来使=等号左右两边的数据类型对应。(译者注:隐式强制数据类型转换)

Basic maths(基础数学运算)
Vex是基于C语言开发的,意味着同样可以进行一些简单直接的数学计算。
例如,先将switch切换到grid,point wrangle里的代码为@Cd = @P.x,如果你查看spreadsheet,你会发现,模型有半面的数据都是负值,另一半则为正值,中心线为0(如果有点刚好在中心线上的话)。你可以试试下列代码来改变这些值查看一下效果。
@Cd = @P.x + 3;
@Cd = @P.x - 6;
@Cd = @P.x -6 * 0.1;
@Cd = (@P.x-6) * 0.3;
Assigning to components(子属性相互赋值)
我们还可以对每个子属性单独进行赋值:
@Cd.x = @P.x-3 * 1.2;
@Cd.y = @P.z+2;
@Cd.z = @P.y;

到目前为止,我们使用过了@P,@N,@Cd。接下来我们来认识一个新属性@ptnum (point number)点序号,模型上每个point点都有自己的id,也就是他们的序号值。(译者注:序号从0开始,第一个点的@ptnum是0,第二个点的是1):
@Cd = @ptnum;
从视图中可以看到,第一个点是黑色的,剩下的全为白色的。因为@Cd颜色的属性值是从{0,0,0}到{1,1,1},R,G,B每个分量的值都是从0~1(而不是0~255),如{0.2 , 0 ,0.5}。而第一个点的@ptnum值为0(int整数类型),自动转换数据之后为{0,0,0},剩下点的序号值都大于0,自动转换之后颜色值都等于或超出{1,1,1}(可自行查看spreadsheet),可以说是相当亮眼了(原文'superwhite'),所以只有第一个点黑色,剩下的全白。
这时候我要给你介绍另一个新的属性了,它常与@ptnum一起使用,它就是@numpt(the total number of points),顾名思义,就是模型总的点数。
译者注:是不是两个属性意思容易弄混,个人提供一种区分方法,我们来按顺序直译,@ptnum是pt开头,也就是point点在前,那么它翻译过来就是“点序号”,@numpt是num数量在前,也就是number数量,按顺序翻译过来就是“数量of所有点”。好吧我瞎绉的,你要是觉得好记就这么记吧。
这时候,你可能就高兴了,那我把@ptnum除以@numpt岂不美哉?得到的都是0~1之间的小数哦,这样平面颜色不就呈现一种渐变的样子了吗?例如有10个点,那么@ptnum/@numpt的结果不就是0/10=0, 1/10=0.1, 2/10=0.2, 3/10=0.3...9/10=0.9。(嘻嘻,那是你以为,接着往下看吧):
@Cd = @ptnum/@numpt;
但是!你发现上面这行代码执行完,呈现的结果并不对,平面整个是黑的,这是为啥捏?让我来告诉你吧,前面有稍微提到,@ptnum的数据类型为int整数,而@numpt的数据类型也是int,所以他们是不带小数的,所以计算结果其实为0/10=0, 1/10=0, 2/10=0, 3/10=0...9/10=0。这它丫的全是0,难怪都是黑的。
译者注:整形数据直接计算得到小数并不是四舍五入来得到最终结果的,而是直接把小数点后的数字给剔除了,只剩小数左边的数字。
那么这种情况该怎么办呢?这时候,我们使用强制类型转换大法(原文casting)!把属性括号括起来,前面加个数据类型,例如float浮点型,就能把它转换为浮点型(带小数的数据类型):
@Cd = float(@ptnum)/@numpt;
在@ptnum前加float即可,@numpt前不必再加来进行转换,当然你要加也可以。因为浮点型除以整形得到的最终结果是浮点型。
实际上,你也可以除以任何数(当然不能是0),而不必拘泥于@numpt:
@Cd = float(@ptnum)/100;
Channels(通道/UI参数)
当使用wrangle节点进行vex编程时,你发现我们之前打的代码得到的都是一个个自动计算得到确定的值。这个交互上来讲不友好啊,要是你想用滑竿之类的进行调节测试呢?大丈夫!Houdini提供了ch函数来实现这个功能。你只要在代码中输入ch(‘*’),(*为你想要的参数名称),点击右边那个图标为滑竿与加号的按钮后,在UI界面上就会出现你想要的参数控制:
@Cd = float(@ptnum)/ch('scale');
滑竿的默认值为0~1之间,但你可以自己调整输出超过1或小于0。
译者注:可以点开wrangle节点面板上的齿轮按钮,在下拉菜单点击Edit Parameter Interface来调整创建的UI,比如设置滑竿min和max值为0和1以外的数。另外,你也可以在Edit Parameter Interface中先创建UI参数,然后用ch等函数调用。

Sine(三角函数sin)
好了,又到了教小朋友们基础数学知识的时间了,sin:
@Cd = sin(@ptnum);
这个函数提供了一个使数值产生波形变化的功能,其计算结果数值在-1~1之间徘徊改变,变化周期为2*pi(相信看到这里的朋友们都是能看的懂这玩意的,不过多介绍这个数学知识了)。
你应该还记得之前讲的@ptnum是int整形数据,他是0,1,2...这样进行增加变化的,不带有小数,所以这个sin变化看起来也不是那么连续的(看视窗中平面的渐变效果)。所以我们进行以下叽里呱啦的各种操作变化,你可以看到不同的效果,自己思考一下。
@Cd = sin(float(@ptnum)/100);
@Cd = sin(float(@ptnum)/ch('scale'));
float foo = float(@ptnum)/ch('scale');/*译者注,定义一个局部变量foo,它的值由后面的式子得到,下文详细解释*/
@Cd = sin(foo);
译者注:vex里的注释写法有两种,和C/C++语言一样,一种是单行注释//,一种是多行自由注释/**/,注释只是额外说明,并不参与代码运行。自行查找注释相关知识解释。
Variables(变量)
思考再三还是决定把变量这个概念放到第一天讲,相信你们是个大孩子了,能够搞定它!
在名称左边由@符号修饰的是attributes(属性),他的数据是实实在在存在于模型对象上的,你可以随时读取(read)它也可以向它输入(write)数据。
如果你要创造或者计算一些数据,并且暂时存储在某个东东里,你就可以使用variables(变量)了,在使用wrangle节点写vex代码时,你自己创建的变量只存在于当前节点中,它只是一个临时工,只存在于wrangle这代码编辑器里,家里蹲死宅一个,外面其他节点没人认得它,毫无存在感,只有家里人能知道它。如果你要使用一个变量,首先你要定义它的数据类型(int, float, vector等等)和名称,然后一个=等号,右边的式子给他赋值。如:
float foo = @P.x/ch('scale');
@Cd = sin(foo);
译者注:关于属性和变量。
属性是物体本身带有并一直存在的东西,houdini本身有许多默认的常用属性(COMMON ATTRIBUTES,包括P,N,Cd等),你也可以自定义新属性。属性可在spreadsheet面板中查看。打个比方就是,一个苹果,它的颜色,气味,硬度等是本身就有的东西,这些是它的属性,只要这属性已经是设定好的,就一直客观存在并且可以在houdini各个节点被调用(当然也可以通过Attribute Delete节点等方式删除)。更多与属性相关知识可以去查帮助文档。
而变量只是你自己在wrangle节点等地方临时设置来方便写代码用的而已,纯粹为你当前编程服务。你写代码总得让人看懂吧,不能写一大堆数字和符号扔那,所以才用变量这么个东西,你可以简单认为就是个有名字的虚拟容器,把数据往里丢,等下写代码用名字写,让人读起来才有意义能看懂,实际上计算还是用的那些数据。到了wrangle节点之外,上面和下面的节点是不认识你写的这些变量的。
Exercises(一课多练)
sin函数作用在z位置上有什么效果?y上呢?
Cos呢?(和sin差不多,波形图像有偏移而已)
三角函数括号里基于@N变化又会呈现什么效果呢?
试着将不同属性放在sin,cos函数里来分别改变颜色的RGB值试试。
Background bonus material(额外背景知识)
大意就是吹了一波vex,比其他语言写起来简洁,高效,牛比!但是不宜在wrangle节点里写太长的vex代码,今后我们可能还会教教怎么debug(排除代码错误)。






































