Skip to main content

来自Entagma的教程:https://www.youtube.com/watch?v=YiAtM4EpQ4U

上周末看了这个教程,做出了一个小作品。其实做的时候对这个原理还没完全掌握,做完之后才有时间来梳理下。不得不感叹这帮人确实聪明,用的vex课上老师都讲过,但是让我自己想这个做法是永远想不出来的…

作品可以点击上方菜单栏中的项目找到,叫做EgytianEra。不过这篇笔记不是梳理作品的制作方式,主要是先梳理下上面的教程中的内容,属于作品中效果的简单版。

简单版工程链接如下,里面的黄色标识了研究工程时查看的属性,淡黄色节点都是为了查看属性额外添加的节点。一些注释是英文不是为了秀优越…只是一半英文一半中文看起来很不和谐。

链接:https://pan.baidu.com/s/19jGYBrSKN_Toj8FJrxK0TQ
提取码:g1kr

效果中核心的节点是用高度场的高度方向与曲线的tangentu方向的点乘,两个向量方向相同,点乘结果为1,相反为-1,相垂直为0。

假设高度场的高度是沙丘的高度,曲线的tangentu方向是风的方向。利用点乘结果,用高度场的高度减去点乘的结果,那么表现出来的效果就是:沙丘中低处向高处的方向与风力方向相同,那么高度就-1,类似于被风吹散了,越来越低。反之与风力方向相反,那么高度就+1,类似于逆风方向的沙里会越堆积越高。

而因为进入到了SOP solver中去解算,所以这个计算结果会一直积累,从而最终形成了一个沙丘动起来的感觉。妙啊~

对于刚才说的点乘,可以用上面这三个节点来查看。

首先用add节点创建了两个点,然后用vex分别给这两个点给一个法线方向,便于观察,然后点乘这两个法线方向,查看最终的结果。其实结果和最上面的那张图是一样的。

下面来解析下教程中给的简单版文件。

外部的简单还是挺简单明了的,左边创建了一个高度场,其实我还是头一次知道还能这样创建高度场。右侧则是花了一个曲线,这个曲线的走向其实就是定义了风的方向了。

主要还是再内部的solver中。

连接Prev_Frame节点的方式也很有启发,因为在第1帧的时候是没有上一帧的,所以SOP solver就会报错,这样连接一个switch后就保证了在第一帧时还是读取第一帧本身,就不会产生报错了。

然后来看看这段核心vex代码是什么意义。注意这个vex是写在volume wrangle中的,所以这里面的@P,可以看作是每个体素的位置。

最开始定义了一个amp,是为了之后的全局控制影响的强度。

nearpoint函数获取了高度场中每个体素距离曲线上最近的点,并且把曲线上这个点的ptnum储存在npt变量中。

接着用曲线上被获取的点的tangentu属性,给到dir上。这里使用npt限制了获取的点是之前nearpoint取到的点,这样就能保证我们的得到的方向,是距离每个体素最近的曲线上点的tangentu,而不是任意什么点。这样我们就获取了“风力”的方向。

接着的npos和d,是求出体素位置和曲线上点位置的距离,根据距离去限制太远的体素就不受这个“风力”影响了。

接下来的volumegradient在上一篇笔记中有详细说过,返回的是体素低数值到高数值的指向,一个带有方向性的vector类型。有了这个方向,我们才能定义当前的体素位置是与风力逆向还是顺向。

然后的angle就是使用了点乘,其实曲线的dir很好查看,就是曲线的tangentu方向,但是grad就不太容易查看了,尤其是这个volume还是高度场,不是普通的Fog。

但是带着上面的解释,其实不管grad的指向是哪里,只要满足我们的运算要求,它必然会形成动态的效果。也正如Entagma在教程中所强调的,重要的是理解一个现象的物理原因,将物理原因归纳为算法,然后在houdini中用算法来进行数学计算,就掌握了一个TD的基本能力。

(完)

Leave a Reply