houdinivex语言教学 vex中的p指什么

各位的vex都是怎么学的,我想专注学一下houdini内置的vex,各位有什么好的推荐吗_houdini吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:11,865贴子:
各位的vex都是怎么学的,我想专注学一下houdini内置的收藏
各位的vex都是怎么学的,我想专注学一下houdini内置的vex,各位有什么好的推荐吗
b站有讲一些讲vex的视频。外语好也可以直接啃外文视频。有个湖边小屋的就挺刺激的……
math in houdini vol 1math in houdini vol 2vex in houdini 这两个
应该是目前最好的vex教程了
能用vex都用慢慢就好了
乐琢网站上有一些,跟着一个做一遍,想多了解些常用的就多跟着做几个。或者看help,浏览一遍,大致功能心里有个数。
b站有讲一些讲vex的视频。用户id:
登录百度帐号【Houdini/Vex教程】JoyOfVex中文翻译教程plus版-第17章
TA的更多文章
【Houdini/Vex教程】JoyOfVex中文翻译教程plus版-第17章
原英文系列教程地址:http://www.tokeru.com/cgwiki/index.php?title=JoyOfVex翻译人:PB_zz原英文教程与本人的翻译教程都是免费分享的,请勿进行盗用贩卖等行为。Day 17AOrient(原始朝向/姿态角)在上节课我们学习了用@N和@up两个向量属性能定义一个确定的旋转方向。这节课我教你另外一个新的方法,但这个方法,涉及到了令人头大的四元数领域,一种四维数据,比较抽象的概念。所以四元数是个嘛玩意儿?遥想当年,当我第一次听说四元数(quaternion)这玩意的时候,我还没开始学习houdini,我兴致勃勃地试着去学习并理解相关的数学知识,但是我最后还是不得不承认,我终究还是条咸鱼......当我在houdini中再次接触到它,也就是需要使用实例属性(instance attributes)时,我从Matt Ebb那里得到了一些建议。他告诉我,你不必去理解四元数背后的数学原理,你只需要关心结果,懂得用就行了。所以对我今天所讲的东西你也要有信心,不必畏惧。&Orient basics(姿态方位基础)在实例属性介绍页面的列表上,你会看到orient在列表的最上方。这说明它的优先级(priority)是最高的。因为它是定义旋转的最明确的一种方式。Orient是一个4值向量,它便于存储而且紧凑。在大多数情况下,这些数字本身就是天书,它们是通过一系列复杂运算得到的。惟一一次我看懂orient的值是啥作用的时候是物体不进行旋转的情况,每个复制体的xyz轴都和世界坐标轴对齐:&@orient =&{0,0,0,1};给gird定义这样一个orient属性,但是在wrangle节点之前连接一个transform属性。你现在可以随意旋转你的grid了,并且复制的boxes也会跟随运动。&Defining orients from other things(通过其它玩意来定义orient)这个“没有旋转”的orient可能是你能手动书写orient值的唯一一种情况了。大多数时候像你我这样的咸鱼是搞不懂orient的值到底代表怎样的旋转运动的。我们一般通过vex的一些函数来给orient间接赋值。Vex提供了好几种方式,你可以根据你想要解决的问题来选择适合你的方式。而很多情况下,我们会用到quaternion函数。让我们从角度(angle)和轴向(axis)开始:&float&angle =&ch('angle');&vector&axis =&chv('axis');&&@orient =&quaternion(angle,&axis);把axis设置为0,1,0,并且调节angle值,看看boxes是怎样绕着它们自身y轴旋转的。这种旋转方法比昨天用两个向量来旋转好理解多了。Angle可以设置为@Time:&float&angle =&@T&vector&axis =&chv('axis');&&@orient =&quaternion(angle,&axis);使用orient也使每个复制体偏移(offset)旋转更容易实现。我们将@ptnum乘以一个自定义参数offset,再把它加给angle就行了。滑竿值为0时复制体统一旋转,增大offset值它们就会错开一定角度:&float&&vector&&&angle =&ch('angle');&angle +=&@ptnum*ch('offset');&angle +=&@Time*ch('speed');&&axis =&chv('axis');&&@orient =&quaternion(angle,&axis);我把axis设置为1,0,0,然后调教speed和offset滑竿,就能得到下面的动画:Axes改为(1,1,0)试试,也就是45°斜向轴:Wow,看起来还是挺cooooooooool~的,但是...等下...这旋转动画怎么看起来好像不是线性变化的,它们的旋转速度好像会突然加快一下,然后又慢下来。如果你把axis的值调的更大,这个问题就更明显了,甚至是调单个方向的值也会这样(例如(0,0,2)):嗯?为啥值调大了就会这样?你有没有想到什么啊?对啊,这里我们也需要将向量归一化(normalized):&float&&vector&&&angle =&ch('angle');&angle +=&@ptnum*ch('offset');&angle +=&@Time*ch('speed');&&axis =&chv('axis');&axis =&normalize(axis);&&@orient =&quaternion(angle,&axis);&Orient via vector length(通过向量,与向量长度来定义orient)由这个忽快忽慢的错误特性我们引出quaternion的另一种定义方式,是的,quaternion函数可以只用轴向做参数,不需要角度。在这种情况下,旋转角度由向量长度决定。例如,你设置一个轴向量,再把它乘以0,就不会出现旋转:&vector&&axis =&chv('axis');&axis =&normalize(axis);&axis *=&0;&&@orient =&quaternion(axis);或者你将向量乘以@Time,你就会得到一个平稳变化的旋转动画:&vector&&axis =&chv('axis');&axis =&normalize(axis);&axis *=&@T&&@orient =&quaternion(axis);看起来好像有一点奇怪,但是你仔细想想,这是一种紧凑简洁优雅的写法来定义旋转。{1,0,0}和{5,0,0}都是指向x轴正方向的向量,唯一的区别就是向量的长度。通常情况下我们可能用不到向量的长度,但是在这里为啥不用呢?噢,还有一点我忘了讲了,这里我们使用的旋转单位是啥捏?如果我们想要精确的90°或者45°旋转怎么办呐?你可能会说,应该用的是弧度(radian)吧,因为所有大人都是用弧度的,只有小孩子才用角度(degree)!是的,看来你也是个大人了。所以我们想要旋转90°的话,我们需要知道就是旋转1.570795 rad:&vector&&axis =&chv('axis');&axis =&normalize(axis);&axis *=&1.570795;&&@orient =&quaternion(axis);译者注:2π rad = 360°,1 π rad = 180°,1°=π/180 rad,1 rad = 180°/π(约57.°)。&哈?你说你不知道90°就是1.570795 rad?emmmmmm...其实我也不知道。不过大多数编程语言中都有转换函数,vex也不例外:&vector&&axis =&chv('axis');&axis =&normalize(axis);&axis *=&radians(90);&&@orient =&quaternion(axis);当然啦,你直接使用π/2也可以。不过在代码中不能直接写π。Vex/hscript混用的一个方便的地方是,wrangle节点中的vex代码编辑器可以被当成是类似于文件路径的文本区(file path text fields)或类似的东西。如果你输入$O或者$HIP之类的东西,在被vex处理之前,它们会自动被节点名称和hip路径替换。所以你输入$PI,也会自动被识别并替换为Pi(精确到小数点后10位)。所以我们可以这样写:&vector&&axis =&chv('axis');&axis =&normalize(axis);&axis *=&$PI/2;&&@orient =&quaternion(axis);“那我们能用这东东玩些什么花样呢?”你一脸懵逼地问我。emmmmmm...比如说,我们能以90°或90°的倍数随机旋转物体。我们先用rand(@ptnum)来得到一个0~1(译者注:应该是可取0,取不了1。[0,1)之间)之间的随机数。然后将它乘以4,这个随机数就变为0~4之间(注意它最大只到3.999999...,无法到达4。届不到,届不到)。然后我们用trunc函数去掉小数,就能得到0,1,2,3其中的一个数。将它乘以$PI/2,你就能让所有复制体以0°或90°或180°或270°旋转:&vector&&axis =&chv('axis');&axis =&normalize(axis);&axis *=&trunc(rand(@ptnum)*4)*$PI/2;&&@orient =&quaternion(axis);或者用noise代替rand:&vector&&axis =&chv('axis');&axis =&normalize(axis);&axis *=&trunc(noise(@P+@Time)*4)*$PI/2;&&@orient =&quaternion(axis);Emmmmm...起作用了,但是效果不如random来得随机。不过这是一个好机会,来讲讲碰到这种情况该怎么debug。&Day 17BMake this rotation thing do what we want(让这旋转如你所愿)用noise的时候应该没有大错误,但是有一些小问题,搞的它表现得有点不正常。在这种情况下,我一般会把最重要的地方改成一个自定义属性,好在spreadsheet面板里检查它的值。在这里,我就把noise(@p)改成’@a’。并且我觉得最好在它被去掉小数之前看到它的值,所以我这么写:&vector&&axis =&chv('axis');&axis =&normalize(axis);&@a =&noise(@P+@Time);&axis *=&trunc(@a*4)*$PI/2;&&@orient =&quaternion(axis);我们来看下spreadsheet面板里’a’那列的值,把它从小到大排列和从大到小排列看看,这下我们就能比较明显地看出问题所在了。Rand()函数是随机的,所以它对于区间内的每个数的出现概率都是一样的,而noise是平滑变化的一系列值,所以很多值都处于0.5附近。因此它很少得到0.1或0.9这样比较靠近极端的值,同样乘以4并去除小数后,得到的大多数值就是1和2,很少得到0和3。那么我们怎么解决这个问题呢?想想我们学过的东西,对啦!Fit函数可以用,只要把中间部分,也就是差不多0.4~0.6这个区间的值给转换到0~1就行了:&vector&&axis =&chv('axis');&axis =&normalize(axis);&@a =&noise(@P+@Time);&@a =&fit(@a,&0.4,&0.6,&0,&1);&axis *=&trunc(@a*4)*$PI/2;&&@orient =&quaternion(axis);对我个人而言,我更喜欢用chramp,这样我能更自由地调节想要的变换范围:&vector&&axis =&chv('axis');&axis =&normalize(axis);&@a =&noise(@P+@Time);&@a =&chramp('noise_rerange',@a);&axis *=&trunc(@a*4)*$PI/2;&&@orient =&quaternion(axis);你可以把移动ramp样条上的点想象成在调节噪波图像的亮度和对比度。把起始点和结束点一起往中间靠,图像的对比度就被增强。把点都往左移,图像就变暗,往右则相反。所以,我不仅能靠看spreadsheet中的属性值来检测,还能通过设置颜色等其他方式来做测试,另外,我还能让@a直接影响@P.y,通过模型升降来观察效果:&vector&&axis =&chv('axis');&axis =&normalize(axis);&@a =&noise(@P+@Time);&@a =&chramp('noise_rerange',@a);&axis *=&trunc(@a*4)*$PI/2;&@P.y&=&@a;&&@orient =&quaternion(axis);这也是houdini的一个牛逼的地方,你可以通过各种方式来感受观测你的数据。&Orient via N and up(通过N和up来定义orient)现在我们能通过角度和轴,以及只通过轴向量和它的长度来定义@orient。那么上节课的@N和@up呢?当然,我们可以把它们移植给quaternion:&@N =&{0,1,0};&float&s =&sin(@Time);&float&c =&cos(@Time);&@up =&set(s,0,c);&&@orient =&quaternion(maketransform(@N,&@up));所以其实(至少据我所知)并没有方法能把N和up直接一步转化为四元数,但是有种间接的方法,我们可以将N和up,转换为一个矩阵matrix,再把矩阵变为四元数。Maketransform函数就是生成矩阵用的,然后这个矩阵被当成参数传递给quaternion函数。&Orient via matrix(通过矩阵定义orient)所以,在不知不觉中,我们开始接触矩阵(matrix)了。毫无疑问,我们可以将矩阵直接传入quaternion函数。这里你可以当作我已经直接给出一个矩阵了,在之后的学习中我们会更多地介绍到矩阵:&matrix3 m =&ident();&@orient =&quaternion(m);常用矩阵有两种,一种是全能的四阶方阵(a 4x4 array of numbers),能对物体进行旋转/缩放/移动/倾斜/透视调整这些操作,在vex中被称为matrix。还有一种少一行一列的三阶方阵,只能用于处理旋转和缩放,在vex中写做matrix3。第一行代码创建了一个叫做m的matrix3变量,并且用ident()函数进行初始化,这个函数意味着“一个啥也不做的矩阵”。也就是不带旋转,缩放为1,1,1的矩阵。我们把矩阵m传给quaternion函数,quaternion会读取矩阵的旋转操作,并且改变我们的orient。在这个例子中,这两行代码等同于:&@orient =&{0,0,0,1};也就是保持朝向不变。&Orient via euler values(通过欧拉角定义orient)你可能还想过以这种方式定义orient,比如“先绕x轴旋转30°,再绕y轴旋转10°,最后绕z轴旋转-23°”,就好像平时用transform节点操作一样。Vex中给你提供了eulertoquaternion函数来把欧拉角转换为四元数:&vector&rot =&radians(chv('euler'));&@orient =&eulertoquaternion(&rot,&0);欧拉旋转也能用弧度来描述,而且这就是eulertoquaternion函数想要的欧拉角单位(一开始为师还没想到是这样,感觉不按套路出牌)。所以我们先设置一个向量UI控制chv,然后用radians函数把这个角度转换成弧度。再把这个转换后的向量rot传给eulertoquaternion函数。Eulertoquaternion函数的第二个参数(也就是我们写的0)用于告诉houdini按怎样的顺序进行旋转操作,比如按XYZ顺序,或YZX,ZXY...写0的话则是用XYZ顺序,也是我们一般习惯的操作顺序。Blending orients(orients转换)所以我们现在介绍了所有的旋转方式,并且都能将它们转换为四元数了。你的小脑瓜里可能还会在想:“emmmmmmmm...是这样,但是又能怎样呢?...我们能从中得到啥好处吗?”好处之一就是我们现在有了一个标准的旋转格式了,这样当你使用@N,而你的同事使用欧拉旋转时,照样能把数据转换合并到一起,而不会卡住。还有一个好处是,四元数有一些其它旋转所没有的好用的函数。假设你有2个四元数,你想从其中一个转换到另外一个,你可以使用slerp函数:&vector4 a =&{0,0,0,1};&vector4 b =&quaternion({0,1,0}*$PI/2);&@orient =&slerp(a,&b,&ch('blend')&);调节blend滑竿,你会发现orient会进行平滑插值变化。或者你可以不用滑竿,用@Time%1,这样角度会从a变到b,然后突然调回啊,再慢慢变到b,如此循环往复:&vector4 a =&{0,0,0,1};&vector4 b =&quaternion({0,1,0}*$PI/2);&float&blend =&@Time%1;&@orient =&slerp(a,&b,&blend );slerp最厉害的一点是,它的过渡动画总是采取最短的旋转路径,并且旋转过程很稳定。你并不会遇到诸如万向节死锁(gimble lock),欧拉反转(euler flips)或者其它旋转方式中奇奇怪怪的胡乱旋转问题。这里我同样使用之前的随机90°倍数旋转,并且拓展完善了一下,让旋转动画不会突然跳回某个位置(通过chramp改变值),而是平滑插值变化。&vector4 target,&&vector&&float&seed,&&&axis =&chv('axis');&axis =&normalize(axis);&seed =&noise(@P+@Time);&seed =&chramp('noise_rerange',seed);&axis *=&trunc(seed*4)*$PI/2;&&target =&quaternion(axis);&&base =&{0,0,0,1};&blend =&chramp('anim',@Time%1);&&@orient =&slerp(base,&target,&blend);&Orient followed by transform sop(orient与transform节点)之前我们在wrangle节点前还连了一个transform节点,这时你调节transform节点的旋转,你会发现复制的boxes都保持了自身的局部旋转(local rotation)不变。也就是orient不变,这很好理解,因为wrangle节点在transform节点之后运行,而我们在wrangle节点中改变了orient。如果你改变一下节点的连接顺序,把transform节点放到后面,你会发现它连着orient一起影响了(译者注:注意查看下spreadsheet面板中orient属性的变化,养成经常查看spreadsheet面板的好习惯)。这时候请你查看一下transform节点,你会发现在'Move centroid to origin' 按钮下有一栏'Attributes'参数。这栏写了个*,意味着transform节点会影响所有它所知的能影响的属性,包括@P,@N等,当然也包括@orient。而如果你不想让transform节点影响到它,你可以像下面这样写,将orient属性排除在外:* ^orient这是一个非常方便的玩意,而且你会在很多节点中见到它。&Transform operations and attribute types(transform节点和属性类型)另一个方面,为毛transform节点不影响@Cd呢?我前面也说了,它只会影响能影响的类型,而不是影响所有类型,houdini自身知道哪些属性是与transforms链接到一起,能被其影响的。所以P,N,orient等节点可以被影响,而Cd明显不该被影响,所以它不在transform节点的调教对象列表上。但实际上,houdini并不是根据属性名来决定哪些属性该被影响的,而是通过属性类型(attribute type)。如果你用中间点击查看一个节点信息,你会发现有关属性的一个列表,上面写了它们的类型(float,vector,vector4等等)。当你创建或修改公共属性时,houdini将会自动把它们设置为正确的类型。但是属性也可能被你手动覆盖掉(override this manually)(或者说只是我无意中发现过一次这种情况),然后出现奇怪的情况。我的一个同事,有次发现渲染出来的模型颜色不对。我们一起检查了所有设置,发现他不小心把颜色和@N给关联到了一起,然后之后又连接了几个transform节点修改数据,最后发现@Cd被改变了,这意味着颜色也被不合理地“旋转”了。不过那次是他做了一个非常复杂的设置,所以这种情况可能一般不会出现。&Combine orients with qmultiply(用qmultiply函数结合旋转)另一个四元数方便的地方。这里我们新建一个polygon sphere,uniform scale设置为5,frequency为2,给它连个wrangle节点,@N设置为normalize(@P),@up设置为{0,1,0},然后克隆一些pigs到上面。和正常情况下一下,它将pig的Z轴与@N对齐,所以所有pigs都是背朝圆心。如果我不想要这种情况呢?我想要pig的脖子底对着圆心,头顶远离圆心,那我可以给pig连一个transform节点并且旋转它。那我想要旋转每只pig,让它朝左转或朝右转呢?或者在Z轴上再旋转20°呢?或者做来回摇头(head bob)运动呢?你可能会开始在pig和copy节点之间连接多个transform节点,然后开始搞stamp表达式之类的,但是我们有一种更简洁的方法。如果你有2个四元数,qmultiply函数会给你返回这两者的结合。这听起来略含糊,我们通过练习来有趣地解释它,在wrangle节点中敲入如下代码:&@N =&normalize(@P);&@up =&{0,1,0};&@orient =&quaternion(maketransform(@N,@up));现在我们构造另一个四元数,用于旋转模型。它是一个使物体绕x轴旋转90°的四元数:&vector4 extrarot =&quaternion($PI/2,&{1,0,0});我们用qmultiply结合这两个四元数,新的旋转将会使每个复制体pig绕自身X轴旋转90°。&@orient =&qmultiply(@orient,&extrarot);把角度改为用一个滑竿控制。注意我现在将N和up作为变量,它们与@N,@up不同且无关。一旦我们完成@orient的初始化这两个变量就没用了:&vector&N,&&N =&normalize(@P);&up =&{0,1,0};&@orient =&quaternion(maketransform(N,up));&vector4 extrarot =&quaternion(radians(ch('angle')),{1,0,0});&&@orient =&qmultiply(@orient,&extrarot);Wow!牛比!我们现在能给每个复制体的Y轴添加旋转了,这样pigs们看起来像在摇头反对一样:&vector&N,&&vector4 extrarot,&&&N =&normalize(@P);&up =&{0,1,0};&@orient =&quaternion(maketransform(N,up));&extrarot =&quaternion(radians(90),{1,0,0});&headshake =&quaternion(radians(20)*sin(@Time*3),&{0,1,0});&&@orient =&qmultiply(@orient,&extrarot);&@orient =&qmultiply(@orient,&headshake);然后绕Z轴一点随机旋转:&vector&N,&&vector4 extrarot,&talktalk,&&&N =&normalize(@P);&up =&{0,1,0};&@orient =&quaternion(maketransform(N,up));&extrarot =&quaternion(radians(90),{1,0,0});&talktalk =&quaternion(radians(20)*sin(@Time*3),&{0,1,0});&wobble =&quaternion({0,0,1}*curlnoise(@P+@Time*0.2));&&@orient =&qmultiply(@orient,&extrarot);&@orient =&qmultiply(@orient,&talktalk);&@orient =&qmultiply(@orient,&wobble);你可能觉得这没什么,但实际能像这样,将已知的分开的小旋转结合到一起做出复杂旋转动画是一种很牛逼的概念设想。Convert back to matrix(转换回矩阵)希望现在你明白了,只要把四元数这个概念当成一个能操作旋转的黑箱就行了,你不用去理会箱子里的东西,只看给出的最终结果就行了,没必要绞尽脑汁去理解它。当然,当你有天牛逼哄哄了,到了不得不面对直接debug你的orients的情况时,你依旧没必要去了解四元数的具体知识,因为我们可以通过vex中的qconvert函数来把四元数转换为更加友好可读的玩意:&matrix m =&qconvert(@orient);是哒,就是转换为矩阵。emmmmmmmm...矩阵你也看不懂吗...你还想要更简单的玩意,比如@N和@up?简单来说,你可以通过给矩阵乘一个Z轴向量{0,0,1}来得到@N,乘一个Y轴向量来得到@up:&matrix3 m =&qconvert(@orient);&@N =&{0,0,1}*m;&@up =&{0,1,0}*m;希望这节课没把你搞懵逼:)Exercises(一课多练)1.&克隆一堆眼球到grid上,让它们全都注视同一个点。2.&在1的基础上,给眼球加点微小的随机旋转。3.&给个滑竿,让值为0时每个眼球看向不同方向,值为1时,都转向同一个点。【Houdini研发】Houdini中Expressions, HScript, Python, VEX区别-翼狐网
【Houdini研发】Houdini中Expressions, HScript, Python, VEX区别
expressions:所谓的表达式,是控制通道(参数)很有用的代码。例如$f返回当前帧数给某一些参数或这npoint("..")返回点数,用于指定对象的某些参数或通道(就像maya的表达式)。hscript:旧的houdini脚本语言,它非常适合操作系统中的shell scripting,我们可以使用hscript访问houdini,例如我们可以添加新节点或者删除节点,更改显示状态等,我们可以通过houdini菜单windows&hscript textport来编写hscript命令(就像maya的mel)python:是houdini9版本之后新增的脚本语言,用于访问houdini,可以添加新节点,删除节点,编辑节点,访问或编写gui等,也可以使用python创建自定义节点。vex:是一种用于编写新的shader或者自定义节点的强大语言,它非常适合c/c++语言,它比python和hscript更快,有时候在某一些特殊情况下甚至比c/c++都快。我们可以用两种方式写vex代码:1.编写vex代码段(就像python,expressions,hscript一样)2.用visual nodes编写vex代码!在第二种方法中,我们可以用视觉节点编写我们的程序!例如对于写a * b = c,我们应该为a和b添加两个节点,然后添加乘法节点并将a和b连接到其输入,最后将乘法节点的输出连接到c节点。我们称这个方法(visual)vop。不同网络(shop,pop,obj,chop,cop,...)的vop节点是相同的,但每个网络的导入参数不同。例如在几何网络中,我们有p参数用于导入点的位置,但在cop网络中,我们应该有r,g,b参数,用于将red,green和blue导入vop网络。所以我们有不同的vop网络为不同的网络,如:vop sop,vop cop,vop chop,vop pop等注1:我们可以将python代码编写为通道和参数的表达式,但标准houdini表达式比python表达式更快。注2:我们可以用许多语言(python - vex - hscript)做一些特殊的事情,例如我们可以创建一个自定义节点,用python和vex对几何进行变形,但是vex比其他脚本快得多!【Houdini/Vex教程】JoyOfVex中文翻译教程plus版-第02章
TA的更多文章
【Houdini/Vex教程】JoyOfVex中文翻译教程plus版-第02章
原英文系列教程地址:http://www.tokeru.com/cgwiki/index.php?title=JoyOfVex&翻译人:PB_zz&原英文教程与本人的翻译教程都是免费分享的,请勿进行盗用贩卖等行为。Day 2Vex自身有许多函数可以使用,下面这个网页有一份vex可用的函数列表,把他存为书签,你将长期使用它进行查阅。记住,多看多练,熟能生巧。https://www.sidefx.com/docs/houdini/vex/functions/index.html译者注:这里我贴的是houdini16.5版本的vex fuctions,要找对应版本的各种文档,可到http://www.sidefx.com/docs/上自己查找。其实这就是帮助文档啦,直接在houdini中Help-Contents打开就行。&Length(长度)接下来,我们接着上一节课来讲,还是打开上次的工程,switch选择grid。当我们想要测量一个vector(向量数据类型)的长度时,该使用哪个函数呢?对啦!就是length(可在帮助文档搜索length,点开,查看函数介绍)。写法如下:&float&d =&length(@P);这样我们就得到了点的位置P(包含x, y, z三个值的向量)属性的长度值。并把这个值赋予了我们自己定义的一个变量d。接下来我们把d的值给颜色Cd:&float&d =&length(@P);&@Cd =&d;好像效果挺无聊的,哦,那么来搞点有意思的事情,上节课说过三角函数sin了,我们把两者结合一下。&float&d =&length(@P);&@Cd =&sin(d);然后再设置一个滑竿,让变量d乘上这个滑竿的值。&float&d =&length(@P);&d *=&ch('scale');&&@Cd =&sin(d);译者注:d&*= ch(‘scale’)等同于d = d*ch(‘scale’),也就是d乘上scale的数值后重新赋予自身,下文还会讲到。调节滑竿,看看grid上的颜色变化,哇,是不是有点因缺思听(interesting)了,我们仅仅用三行简短的代码就得到了这个效果。此时,如果你瞄一眼spreadsheet,你会发现@Cd的属性值会有负数,那是因为sin的值在-1到1之间变化,而@Cd的属性值范围只有在0~1之间有效,所以我们来修正一下他,在sin后面加1使它的范围变为0~2,然后把整体除以2,数值范围就变为了0~1。&float&d =&length(@P);&d *=&ch('scale');&&@Cd =&(sin(d)+1)/2;你以为这样就perfect了吗?不,还没完,出于一些编程上的原因,建议将除法改为乘法,也就是/2改为*0.5,而d在定义后乘以scale的这一步,也可以直接在定义时就完成。所以我们的代码变为:&float&d =&length(@P)&*&ch('scale');&@Cd =&(sin(d)+1)*0.5;甚至说,你可以直接不要这个中间变量d啊,整个式子能一气呵成:&@Cd =&(sin(length(@P)&*&ch('scale'))+1)*0.5;然而我并不建议你这样写,因为这样降低了代码的可读性。有点难受哦。译者注:关于代码的可读性等可自行查找相关知识,其实就是你要保证自己写的代码自己或别人能更好地看懂吧,别下次打开工程要修改了,自己看了都一脸懵逼。Distance(距离)和长度相关的还有距离。当你使用length(@P)的时候,你实际上实在测量当前点到{0, 0, 0}原点的距离。而distance函数允许你测量任何两个数据间的距离。如:&float&d =&distance(@P,&{1,0,3}&);&d *=&ch('scale');&&@Cd =&(sin(d)+1)*0.5;你会发现,视窗中grid上的黑白圆环图像中心点从原点{0, 0, 0}跑到了{1, 0, 3}这个点。接下来我们介绍一个新的UI参数创建函数,chv(ch是chanel的缩写,v是vector的缩写),用它来在界面上创建一个向量参数center:&vector&center =&chv('center');&float&d =&distance(@P,&center );&d *=&ch('scale');&&@Cd =&(sin(d)+1)*0.5;这样你就能使用参数随时手动调整黑白圆环的中心点位置了。这里再教给你一个小技巧好了,将@P乘以{0.5, 1, 1},你就能让@P.x的值缩小一半。此时,我的强迫症逼我把这些代码整理一下,让你们这些小朋友能一眼就看明白。&vector&pos =&@P *&chv('fancyscale');//模型上的点位置值缩放后的结果&vector&center =&chv('center');//中心点位置&float&d =&distance(pos,&center );//计算两点距离&d *=&ch('scale');//将距离缩放&@Cd =&(sin(d)+1)*0.5;//距离作为sin函数自变量,整个式子把结果值映射到0~1之间敲黑板!注意了!你的UI创建函数ch和chv里使用的名称不能是相同的,否则只会生成一个UI参数,例如已经写了chv(‘scale’),下面又写ch(‘scale’),这样houdini会根据优先级只生成一个参数,同样的,变量名也不要定义相同的,而且最好这些名称看起来是有意义的,比如是一些单词或者该单词的缩写,而不是随便取个名叫a,b,c,x之类的。另外你会发现对代码进行修改,但UI界面却不会实时更新,或者说旧的参数它不会自动消失,这时你可以右键点击该参数,选择More-Delete Spare Parameter,这样该参数就被你删除了。或者有一种一刀切的懒方法,你可以点击wrangle节点菜单栏上那个齿轮按钮,在下拉菜单中选择Delete All Spare Parameter,这样所有生成的UI参数就都消失了,然后你再点击代码编辑器右侧的那个创建参数按钮(图标是滑竿和一个加号的那个,上节课讲过),重新生成代码里的参数,当然,图方便的代价就是你之前调好的数值都没啦,全变成了默认值。接下来我们介绍一个新函数fit,这个函数是专门来做值范围映射的。之前我们是手动将sin的值通过计算映射到0~1之间( @Cd = (sin(d)+1)*0.5;),现在有了fit函数,我们就不用每次都想算法来计算了,这个函数会自动帮你搞定。用法如下:&vector&pos =&@P *&chv('fancyscale');&vector&center =&chv('center');&float&d =&distance(pos,&center );&d *=&ch('scale');&&@Cd =&fit(sin(d),-1,1,0,1); /* fit(value, omin, omax, nmin, nmax) &同样可在帮助文档查询,简单来说fit括号里填的就是要修改的数据,以及旧范围的最小最大,新范围的最小最大。*/一般来说,三角函数都伴随时间使用的,sin(wt)。houdini里时间的属性是@time,我们把它作为sin的变量的话,点击时间轴的播放按钮,你会发现,sin的数值随时间变化而变化,我们的图像也有了自动交替的黑白变化动画。&vector&pos =&@P *&chv('fancyscale');&vector&center =&chv('center');&float&d =&distance(pos,&center );&d *=&ch('scale');&&@Cd =&fit(sin(d+@Time),-1,1,0,1);&More on code style(更多关于代码风格的知识)如果你要将一个变量乘以5,你可以这样写:foo =&foo *&5;也可以使用运算符(又译操作符,英文operator)*=:foo *=&5;同样的,类似的有+=, &-=, &/=。另外你可以在一行代码上进行非常多的运算:foo =&(foo *&3&+1)&/&@Cd.x&+&@N.y;不过不建议写太长,分开一步步写更容易理解:foo *=3;&// set rangefoo +=1;&// make sure values never get below 0foo /=&@Cd.x;&// reduce range to within red valuefoo +=&@N.y;&// addition normal on y&Exercises(一课多练)1.&改变代码,让波形动画,从向中间收缩运动,变为向外部扩大运动。2.&改变波形速度(译者提示:三角函数的周期)。3.&让波形颜色不再是黑白,而是蓝或者黄或者绿。4.&让代码影响点的y值,而不是影响颜色试试。}

我要回帖

更多关于 houdini中vex与cpp 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信