人气 420

[图文教程] Houdini SOP & VEX入门笔记(1) [复制链接]

ylifk 2022-4-5 21:52:57

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
引言

暑假到了,因为自己进的实验室主要做的DGP(Digital Geometry Processing,数字几何处理),借鉴自己之前通过Substance Designer入门图像处理领域,通过Unity入门图形学渲染领域的经验,打算学一下自己垂涎已久的Houdini来入门几何处理。
顺便一提,本文中所使用的Houdini版本为Houdini Apprentice 17.5.293。跟的教程是有名的湖边小屋,手头有余裕的朋友们可以到gumroad上面购买支持一下这位艺术家。
建议有意向阅读此文的读者选个有空的时候,坐在电脑前再来阅读本文。原因其一,排版是按PC来排的,手机上不好阅读;其二,内容比较硬核,干货比较多,需要坐下来慢慢读。
<hr>脚本语言

与SD一样,Houdini也是基于节点编程;比SD更强大的地方在于它也支持脚本编程(SD的脚本编程目前还处于非常原始的阶段),并且脚本编程的威力非常强大。Houdini所使用的脚本语言有好几种,就我目前了解到的有如下几种:

  • 参数脚本语言(表达式):

    • HScript Expression     传统的默认脚本语言,主要用来做控制参数的脚本;
    • Python HOM              新的脚本语言,比Hscript更强大,但是写起来很啰嗦;

OjpBW7As09jH6y7Z.jpg


  • 泛用型脚本语言:

    • Vex                             高性能的C谱系脚本语言,用来写自定义的节点或者Shader。
    • Python HOM              似乎是全能的编程语言,比较复杂所以还有待进一步探索。

W86696L98dd1w661.jpg

由于作者目前水平所限,只能谈一下自己对VEX和SOP一些粗浅的了解,有不准确或错误之处望读者指正。
<hr>几何对象的层次

Houdini中,SOP处理的是几何对象(Object)。几何对象的数据在SOP节点中得到处理,并在SOP网络中流动。那么问题来了,应该如何处理这些繁杂的数据?Houdini将几何对象(Object)中的几何数据进行了分层。理解这一部分是至关重要的。
即使读者没有系统的图形学背景,也应当能理解几何体的组成部分可以拆分为点-线-面;而Houdini中的分类要更复杂一点:
Tqu0d3znFNEftnYR.jpg


  • Detail          最高层级的数据,对应整个Object;
  • Primitive     几何对象中的组成部件,比如一个三角面片,一张NURBS曲面,或Volume;
  • Point           几何对象上面的一个点;
  • Vertex         一个Point可能同时存在于多个相邻的Primitive上,因此共享同一个Point的          多个primitive会各自存一份对Point的引用,称为Vertex。
<hr>几种变量类型

类似于图书馆的管理员一样,VEX中用到的变量也是分等级的;主要分为以下几种:

  • Attribute            属性
  • Parameter          参数
  • variable              变量
属性 Geometry Attribute

最重要的数据类型就数属性了,首先,前文提到的每个几何层级都会把属于该层的所有对象组织成一张表,比如primitive层的会组织到一张primitive表,point层的所有点会组织成一张点列表;
随后,每个层级我们都可以为所有属于该层的对象们定义一些属性,比如对于Point层,可以为每个点定义位置或者法线属性;我觉得下图可以很好地解释属性的概念。
SDqy8Tl8VOQYsvUl.jpg

rqQsn4P44p47pVdL.jpg

认真读的读者肯定会意识到,那么vex代码应该用在哪种节点里面,来帮助我们为所有点定义或者修改属性呢?Houdini有一组非常强大的节点,专门用来做这类事情;我这里介绍其中用的最多,最有代表性的Attribute Wrangle节点。""Wrangle"一词的翻译是"放牧",就像牛仔管理他们负责的牛群一样,我们对各个点或者其它对象的属性进行“放牧”。换句话说,该节点对输入数据中每一层级(就是上一小节讲到的层级概念)的所有属性进行处理。
VK6zSHXk1zSHsYw3.jpg

关于Atrribute的操作比较繁杂,但总结起来大致就是增删查改四种操作;

  • 删除属性
    找了很久,VEX中好像没有删除属性的函数,不过有一个节点可以用来做这件事:Attribute Delete。
  • 读取/修改属性   
    使用已经定义的同层级属性的方式为:@变量名。比较特殊的情况下,Attribute Wrangle节点可能有多个输入(从左到右,序号为0~3,没有编程经验的同学注意,从0开始!),比如我想要用第二个输入数据的点层级位置属性@P,那么以下3种方式都能获取到数据。
    o6g0c0924jg4Uw66.jpg

    值得注意的有2点。
    第一,SideFX官方的讲座中提到,在性能上来说,使用方法(3)是最好的,应当尽可能使用它;但(3)也是有局限的,如图:
tFGPziDIQ1BcWiCc.jpg


第二,如果你使用的属性是非浮点数类型的,比如vector型的向量,第二种方式必须记得在@之前写上属性数据类型的简写,否则编译器会默认为浮点数。具体各种变量类型和简写的对应见下图:
gwom6aZDZd3qMwd1.jpg

前面提到的是相同层级的属性读取,不同层级之间的属性读取则可以使用point(...), prim(...), detail(...)函数完成,具体用法我就写在下面了。
b1fNj5hH37hNIKhI.jpg


  • 增加属性   在VEX中定义属性的方式为:数据类型 @变量名举个例子,我想给所有定义一个叫做myval的浮点数属性,然后对这个属性加一,那么就在Attribute Wrangle中选定要处理的层次为点,
IDAXdV3R0lCXs9vK.jpg

  然后在代码编辑器中输入
kKHvmBB2o3mN5fnf.jpg

即可。值得注意的一点,在定义一个
新的属性时,等号右边(即我们赋予该属性的初始值)必须是常量,也就是说只能是具体的数值, 不能包含任何函数或运算。例如下面一段代码是有效的:
sgma6Lx3Jvgg3Z2V.jpg

但是如果写成这样就会报错:
TI33DB9Yg388M013.jpg

属性在整个节点网络中,一旦你创建了,在人为手动删除它之前,就是一直存在并且全局都可见的(就是任何时候,只有你想要就可以读取)。因此属性是非常消耗空间和性能的,应当尽可能节约使用,如果预计将来再也不需要这个属性时,就应当使用Attribute Delete删除掉。
变量 Variable

那么,一些VEX代码中的变量,如果它们只会在该节点的代码里面用到,那么就没有必要设置为属性了,我们称之为局部变量,就是它只属于所在的这个节点,节点算完之后就把它所占用的空间释放了,生不带来,死不带去。
局部变量的定义很简单,和一般的C语言定义方式一致。这里就不再累述。值得注意的是,当你想要用包含变量的一组值来定义一个局部变量时,应当使用函数set(...),比如下面这段代码
y8XwAavaIWaae8Wx.jpg

编译器会报错:“Syntax error, unexpected identifier, expecting '}'.”初学者肯定会丈二和尚摸不着头脑,错在哪了呢?原因就在于赋值的式子里包含了变量@y,而{ a, b, c }仅当a,b,c为常量(具体的数字)时才有效,我们这里应当使用函数set:
qPAeEpEeOWpZzwpS.jpg

参数 Parameter

除了前面提到的2种数据类型之外,还有一个非常重要的,就是paramteter(参数),参数一般出现在节点的paramter窗口,我们可以通过参数这些对节点进行调整。官方网站上比较有用的文档:创建参数,参数综述。
由于参数非常重要,所以这里详细讲它的几种使用方式:

  • 在窗口上,对参数进行自动链接
    右键点击源参数,选择"Copy parameter"。
    右击你要粘贴到的那个参数,选择"Paste relative reference"。
Dn7JEtdE02zd92ds.jpg


  • 在窗口上,对参数进行手动链接
    此处使用的并不是VEX,而是HScript表达式,但是由于太重要了,就也写在这里:
    在目标参数处输入函数ch("源参数路径"),源参数路径的格式有3种情况:
vDmmQ3mrR1mmMHM4.jpg


  • 在窗口上,手动创建参数
    流程见下图,注意在"Parameter Description"一栏,我们新创建的变量有2个名称:NameLabel,Name是参数“真正”的名字,我们在使用ch("参数名")或者VEX内引用该参数时,都用的是Name,注意,Name不能包含空格;
    但是Label可以包含空格,作为参数在用户界面上显示的名称。
m9QQZa973PK93arA.jpg


  • 在Wrangle节点里,用VEX代码创建窗口上的参数;
    使用chi, chf, chv, chs函数在VEX中定义,随后在界面上点击一个按钮即可,如图。或者还可以用chramp来定义一个ramp,非常方便。
StlU2XS6ha26aU5z.jpg


  • 在Wrangle节点里,用VEX代码读取窗口上的参数;
    同上,使用chi, chf, chv, chs即可。
  • 在窗口上,读取VEX代码创建的属性作为参数使用;
    这个话题比较复杂,因为是不能直接用@属性名的,现在我还不是很确定,所以以后再来补上吧。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|小黑屋|九艺游戏动画论坛 ( 津ICP备2022000452号-1 )

GMT+8, 2024-4-26 23:59 , Processed in 0.163699 second(s), 26 queries .

Powered by Discuz! X3.4  © 2001-2017 Discuz Team.