感受了一下Houdini VEX,语法比较像C。但如果要说相似度的话,我觉得它更像Shading Language比如GLSL。可以逐个操作Point, Vertex, Primitive。像极了GLSL的Vertex Shader/Fragment Shader。区别在于Point Vertex Primitive是Houdini内置的数据结构,而且VEX不是GPU片段。但是思路和写Shader无比相似。由于操作数据直接就是几何信息,而不是渲染使用,所以VEX也可以用来建模,效率很高。当然VEX也可以用来写shader,它有很多Context,Surface就是Surface Shader,建模用的SOP contex,还有粒子POP Context等等。
尤其是粒子系统,写VEX会比OpenGL,RhinoPython之类方便快捷的多。
和OpenGL对比:
+ 自带attribute数据结构,不用整VAO,VBO那些复杂玩意
+ 自带一些算法,半边结构、点云查找、OpenVDB等,不用重写
+ 有Mantra渲染啊,ray-tracing, pbr应用尽有,还能写用vex shader
+/- VEX SOP似乎是多线程的,但毕竟不是GPU,比shader还是慢。但大部分情况下还是比OpenGL用单线程快的,而且不用处理并行。
– 可扩展性不强,总不能写个软件然后带着Houdini吧,所以Houdini还是做工具链用。
和RhinoPython / MEL对比:
+ 快,毕竟原生多线程,所以做粒子特效什么的还是用Houdini
+ 节点式,有很多已经写好的基础功能不用重写,这点比较像Grasshopper。虽然Maya也是节点式的,但节点系统藏得好深啊。相比之下Rhino几乎没有参数化功能,因为操作不是节点/树状组织的,好在有Grasshopper。
– Debug比较费劲,毕竟类似GPU编程,print不出来东西,只能搞debug attribute显示出来,好在显示自定义attrib还比较强。
毕竟原生多线程啊。这样很多基于粒子系统的图案可以方便生成。本文列举以下几种:Flocking,Space Colonization,Reaction Diffusion(Grey Scott),Diffusion Limited Aggregation, Pyroplastic Noise, Physarum。这几个算法都有很多相似的地方,也有各自独特之处。最后一个是之前根据Jeff Jones研究Physarum提出的一种算法
1. Flocking (Reynolds, 1987) (Reynolds, 1999)
还有一篇论文扩展了一下,用了模态逻辑(Bajec, 2003)。
简单来说,这个粒子系统中,粒子是有相互作用的。三种:
- Alignment,粒子跟附近例子速度方向趋同。
- Cohesion,粒子朝向附近例子平均位置运动。
- Seperation,粒子离得太近又会互相原理。
这个算是Agent-based modelling的先驱了。之后又有很多改进版本。这个例子非常之经典以至于讲Computational Art, Emergence, Complexity Theory必会涉及,另一个是Game of Life元胞自动机。
2. Space Colonization
这个一般用来模拟树的生长,(Prusinkiewicz, 2004) (Runions, 2005), (Runions, 2007)。
有这么几步:
a. 空间中随机分布一些食物点和一些生长点
b. 检查生长点一定范围内有没有食物点
c. 如果有食物点,将食物点与生长点对应(n对1),每一个生长点向近处食物点的平均方向生长一步
d. 检查食物点一定范围内有没有生长点,如果有,剔除这个食物点。
要说模拟树,直接有一个University of Calgary的组做这个,还出过一本书。算法植物学。
其实模拟树还有一些别的方法,L-System是一种,是规则驱动的算法。还有一种似乎是按层级分形建模的方法,比如SpeedTree感觉上是用这种方法。最后一个比较自顶向下,而前两个更偏涌现一些。
以下是笔者糊的图。
3. Gray Scott Diffusion Reaction
最经典的扩散反应方程,
这个方程可以搞出丰富的图形:
参考资料也非常之多,Processing的、RhinoPython/Grasshopper的,太经典以至于肯定能找到。
上图是笔者用扩散反应方程糊的一个模型,把时间按Z方向挤出。具体来说,每一帧二维模拟先按照浓度blast掉小的一部分,然后上面scatter点。用solver把这些点按时间往Z移动,最后VDB from particle做出体素。转成polygon太慢了,就没搞。
4. Diffusion Limited Aggregation (Witten, 1981)
这个其实和Space Colonization很像的,但又有不少区别。DLA中所有粒子都在做布朗运动,但是有的碰到凝结核就会被吸附上去停止运动。规则真是非常之简单。DLA用来模拟无机物的生长比较常见,晶体积聚之类。
toxiclibs是有例子的。Houdini VEX里很容易用pcopen就能开个点云,方便。笔者用Grasshopper C#写过,Rhino里有个RTree类可做点云查询,稍费劲一点。
5. Pyroplastic Noise
一般就是爆炸烟雾会用这个。也算是一种粒子系统,不过Houdini中用体素表达更容易,一个density场的VDB就可以了。这个效果的核心思想是:density转移的方向是浓度梯度+一个perlin noise。这样既有向外扩散的效果(梯度方向运动),又有随机性(perlin noise是随体积分布比较连续的,不像纯随机那样随机)。
当然,这里就是简单用VEX做了一个实现了。实际上完全没有必要如此,在DOP里用PyroSolver解算density场可以做出很复杂的效果。
Houdini非常好的一点是对体素的支持比较好,虽然传统的volume比较慢,但是咱有OpenVDB啊!而且Mantra渲染体积也挺不错。从这方面来讲,比rhino真是强了不止一点半点。
笔者小小练习了一下。
6. Physarum (Jones, 2007)
应该叫一个Stigmergic算法,A粒子向B高浓度处运动,并释放B。B引导A,并且会扩散蒸发。比较像一个Ant Colonization的连续版本。
发了一篇CAADRIA,过几天就知道有没有被接收了。具体可参考我另一篇文章Physarealm。
7. 其他的
Houdini里还有大量粒子系统啊。POP我就不说了。布料也是一个粒子系统,粒子+弹簧的模型。液体模拟目测也是,FLIP好像就是有一个粒子+体素相互作用的系统。
8. 总结一下:
这其中又可以分成两组对比:
Space Colonization vs DLA. ,区别在于Space Colonization是主动生长,DLA是被动生长。具体来说,SC中A粒子是向B粒子生长侵蚀的,A主动出击,B是静止不动的。
Flocking vs Physarum,区别是Physarum是stigmergic的,也就是粒子不是与附近的其它粒子交流,而是通过释放第二种粒子——信息素互相交流。
9. Houdini中实现
一些诡异的地方
?:二元运算符似乎返回值有些问题,不知我做错了还是如何,需要注意。
创建的函数不能引用传递,只能传值?这样就只能靠返回值返回了。很奇怪,pcimport是传引用的呀,但是为什么不能自己写?
参数类型
v@attrib是vector类型(vector3),p@attrib是vector4类型。调用时不显式声明,编译器会以为你用的float类型似乎。
从channel调参数近来也要显式声明类型,比如chi()是int,chf()之类。还有个常用的chramp(),可以用UI上的remap函数图像来映射vex里的参量,非常好用。
一些常用函数
点云操作(找最近点)是很容易的,不用自己创建个RTree之类。一般结构如下:
1 2 3 4 5 |
int handler = pcopen(geoself(), "P", @P, distance, count);//handler相当于一个迭代器 while(pciterate(handler)){ pcimport(hander, attribname, attrib)//attrib是引用传递进来的,要事先声明。 } |
获取参数的方法
对于当前point/vertex/primitive的参数,直接@attrib就能得到参数。
获取同级元素的其它参数,要用point(), vertex(), prim(), detail()获取相应参数,这里参数表省略了,可以参考houdini文档。其中是要提供对应的序号的,比如ptnum
设定同级元素的其它参数,用setattrib()就可以啦
迭代
一般来说粒子系统都是要迭代的,用point wrangler/attribute wrangler写一个step就可以了,后面的交给Solver/Loop
Solver的用法,一般都要在最后加一个switch,因为第2帧以第1帧为输入,而第一帧在imput_1中。Prev_Frame和switch中间就是自己定义的每个step操作了
。
循环虽然有很多,但是教程里就用了For-Each Subnetwork,然后把每一步放进subnetwork连起来,subnetwork的UI里第一个参数选For Each Number.
后记
很多截图都是来自于VEX in Houdini这门课,讲的非常棒,推荐听。
参考
//VEX in Houdini课程,主讲者Shawn Lipowski
http://www.cgsociety.org/training/course/vex-in-houdini
//有关Boid Flocking
Reynolds, Craig W. “Flocks, herds and schools: A distributed behavioral model.” ACM SIGGRAPH computer graphics 21.4 (1987): 25-34.
Reynolds, Craig W. “Steering behaviors for autonomous characters.” Game developers conference. Vol. 1999. 1999.
Bajec, I. Lebar, Miha Mraz, and Nikolaj Zimic. Boids with a fuzzy way of thinking. Anaheim: ACTA Press, 2003.
//有关扩散反应
http://www.karlsims.com/rd.html
//有关Space Colonization
http://algorithmicbotany.org
Prusinkiewicz, Przemyslaw, and Aristid Lindenmayer. The algorithmic beauty of plants. Springer Science & Business Media, 2012.
Runions, Adam, et al. “Modeling and visualization of leaf venation patterns.” ACM Transactions on Graphics (TOG) 24.3 (2005): 702-711.
Runions, Adam, Brendan Lane, and Przemyslaw Prusinkiewicz. “Modeling Trees with a Space Colonization Algorithm.” NPH 7 (2007): 63-70.
//有关DLA
Witten Jr, T. A., and Leonard M. Sander. “Diffusion-limited aggregation, a kinetic critical phenomenon.” Physical review letters 47.19 (1981): 1400.
http://n-e-r-v-o-u-s.com/education/simulation/index.php
http://formandcode.com/code-examples/simulate-dla