Houdini学习笔记027_VEX和梯度

今天我们来学习下梯度的用法。梯度属于一个比较宽泛的概念,本质上是数值按照某种趋势变化的过程。比如高度梯度、颜色梯度、密度梯度等。这里我们用最简单的高度梯度为例进行讲解。

VEX代码如下——

首先,给grid对象添加mountain节点,调节Height和Element Size参数得到起伏。

用Attribute Wrangle节点为其添加梯度属性,VEX写法很简单:@grad = @P.y;
(可在Geometry Spreadsheet窗口中查看点属性)

如果想在视图中显示,可用measure节点进行查看。选择measure节点,Measure方式选择Gradient,Source Attribute输入grad,在视图中按【Enter】键查看。

下面我们这样操作,对于平面上的每个点,找到其相邻点并比较grad属性大小(这里其实就是P.y)。找到grad最小的那个邻点,并与之连线。如果周围点的grad属性都比中心点大,则不连线。使用的是Point Wrangle节点,首先用neighbours函数获取相邻点的编号,返回值用整型数组pts[ ]接收。
int pts[] = neighbours(0, @ptnum);

比较所有邻点的grad属性,找到最小值。这里可使用for循环,写法如下:
for(int i = 0; i < len(pts); i++){
}
比较大小需要有一个参照值,直接用当前点的grad值作为初始最小值:
float mingrad = @grad;
邻点的grad属性值则可用point函数获取:
float val = point(0, "grad", pts[i]);
如果邻点的grad属性小于当前点,则取代当前的最小grad值。使用的是if函数,VEX代码如下:

同时我们要获得grad值最小点的编号,可以先定义
int num = @ptnum;
找到满足条件的邻点后,再用pts[i](邻点编号)取代num的值:
num = pts[i];、
最后对当前点和满足条件的邻点进行连线,因为有些点本身就是局部最低点(grad值局部最小),没有满足条件的邻点,所以不必进行连线。如果有满足条件的邻点,那么num的值肯定和初始的@ptnum不同,因此可作为if语句的判断条件:
if(num != @ptnum){
addprim(0,"polyline",num,@ptnum);
}
最后移除原来的grid面,VEX代码为:
removeprim(0,@primnum,1);
最终得到如下图所示的结果——

后面的颜色添加可以用grad属性来着色,Color Type选择Ramp from Attribute即可。Range范围即从grad的最小值到最大值。

你也可以将梯度设为其他的值,如
@grad = @P.x + @P.y + @P.z;
结果如下所示——

今日分享到此为止,感谢阅读,下回见~