原视频:https://www.youtube.com/playlist?list=PLzRzqTjuGIDhiXsP0hN3qBxAZ6lkVfGDI
Bili:Houdini最强VEX算法教程 - VEX for Algorithmic Design_哔哩哔哩_bilibili
Houdini版本:19.5
What is noise噪波
noise是随机相关,多作用于纹理等(云、大理石、海洋等),比rand看起来多一些规律。
noise相邻之间的数值,会比较接近,过渡比较平滑。可以理解为梯度或渐变的随机值。
1、Perlin Noise
Houdini中的noise是由Perlin发明,随机返回值0~1,值主要分布在0.3~0.7。
eg1.noise基础用法。
操作:新建一个Grid节点(50行x50列),在下面添加一个PointWrangle节点,写入代码,
float val = noise(@P);
@P.y = val;
结果:如下,把Grid变成了一个带梯度且平滑过渡的Grid,
eg2.还可以控制上面Grid的缩放。
操作:代码改写为,
float val = noise(@P * chf('scale')); //控制Grid缩放
//仅控制X轴方向的缩放,其它Y、Z轴同理
//float val = noise(@P * set(chf('scale'), 1, 1));
@P.y = val;
结果:略
eg3.还能对Grid进行位移。
操作:代码改写为,
//控制Grid在Y轴位移。其它轴向位移只需修改向量对应的值即可
vector offset = set(0, chf('shift'), 0);
float val = noise(@P + offset);
@P.y = val;
结果:略(可以对通道参数输入:$T,点击播放,即可看到Grid在摆动)
2、Simplex Nosie
即xnoise,与noise类似,只是采样不同,能够创建比noise更过渡平滑的值。
【2、Perlin Noise】的例子都可以用xnoise来替代。感兴趣可以结合clamp和颜色节点来耍。
3、Perlin Noise练习一
搞条螺旋管道,管会随机缩放。
eg.①如下图添加及连接节点,最后两个节点可以最后再进行设置,
②在类型为Points的noise_sprial_thickness中输入以下代码,
float ang = @ptnum * radians(chf('step_angle'));
float rad = chf("radius");
@P = set(cos(ang) * rad, @P.y, sin(ang) * rad);
//以上为螺旋线
float val = noise(@ptnum * chf('scale') + chf('shift'));
f@val = val;
f@pscale = fit(clamp(val, 0.25, 0.75), 0.25, 0.75, 0.0, 1.0) * chf('thickness');
③结果为:用$T输入到位移shift通道,可以让管道随时间变化,其它值看着给,
4、Perlin Noise练习二
小球颜色与Noise。
eg.①创建一个细分为10的Polygon的Sphere小球,在PointWrangle节点写入代码,
vector pos = @P * chf('scale'); //暂设为5
pos.y += chf('shift'); //范围0~10,设置为$T
vector col = noise(pos);
col = fit(clamp(col, 0.25, 0.75), 0.25, 0.75, 0.0, 1.0);
v@Cd = col;
结果为:小球表面颜色沿Y轴方向规律流动/移动。(19节视频50分04秒处)
②使用Vector4来使用Noise,看看有何变化,代码更改为,
vector pos = @P * chf('scale');
vector4 v = set(pos.x, pos.y, pos.z, chf('shift'));
vector col = noise(v);
col = fit(clamp(col, 0.25, 0.75), 0.25, 0.75, 0.0, 1.0);
v@Cd = col;
结果为:小球表面颜色流动/移动,但没有方向感。(19节视频51分10秒处)
5、Perlin Noise练习三
利用三角函数和noise特性,在圆环表面做涟漪感,先上结果,
eg.①添加一个细分300x500的Torus圆环节点。
②再添加并连接PointWrangle节点,写入代码,
vector pos = @P * chf('scale');
vector4 v = set(pos.x, pos.y, pos.z, chf('shift'));
float val = noise(v);
val = sin(val * $PI * 2.0 * chi('wave_num'));
@P += @N * val * chf('wave_height');
③上面结果在以下条件得出,
6、Peridodic Noise
pnoise,周期性噪波。如果周期参数为0,则该noise为非周期噪波。可以看看这篇文章知乎@刘鹏飞。
可以看作是在perlin noise的基础上,加了一个重复的操作,即指定周期。
下图为pnoise(大多数noise)关于周期连接方式,一个方块为一个周期,生成一个周期(单元)后,可以重复使用大概了解下就行。
eg.①添加一个细分为10*10的Grid节点,
②添加并连接PointWrangle节点,写入代码,
int tilesize = chi('tilesize'); //周期/重复块大小
float val = pnoise(@P, tilesize, tilesize, tilesize);
@P.y = val * chf('height');
f@col = val;
③结果为:高度height值随意或=5,周期(重复尺寸)tilesize设为2,则Grid结果显示为5个周期,(喜欢折腾的朋友,可以添加color颜色节点,根据val属性值上色,结果更直观),
7、Peridodic Noise练习一
eg.①先上节点图及结果,
②在VolumeWrangle节点写入代码,
int ts = chi('title_size'); //ts表示单个平铺尺寸大小
vector pos = @P * ts; //缩放吧
float val = pnoise(pos, ts, ts, ts);
f@density = val;
③结果:如上右图。喜欢折腾的朋友可以结合Vector4、位移作为参数,看看它的变化。
8、Flow Nosie
流动噪波flownoise ,可以看作是仅时间范围内重复的noise.相当于周期参数(x,y ,pz) 为0。
flow参数是默认理解为1s内循环一次!?
eg.①节点连接及设置如下,
②在VolumeWrangle节点写入如下代码,
vector pos = @P * chf('scale');
float shift = chf('shift');
// flownoise值范围:0~1,分布在(0.5,0.5,0.5)周围
//因此需要减掉(0.5,0.5,0.5),保持值在(0,0,0)附近
vector dir = flownoise(pos, shift) - set(0.5, 0.5, 0.5);
v@velocity = dir;
③结果:在下一个eg中一同展示。
9、Curl Noise
curlnoise 是基于Perlin Nosie进行计算的无散度噪波。(开始与结束能够平滑过渡)
curlnoise() 函数的参数仅需要一个向量值即可,使用更方便。
(也不是很懂Curl Noise和Flow Nosie的区别)感兴趣可以看看下面这篇文章,以及百度AI的回答,
eg.直接复制【7、Flow Nosie】的整个eg,对VolumeWrangle节点的代码修改为,
vector pos = @P * chf('scale');
vector4 val = set(pos.x, pos.y, pos.z, chf('shift'));
vector dir = curlnoise(val);
v@velocity = dir;
结果:在scale=任意值,shift = $F / $FEND 条件下,图片来自知乎@刘鹏云,
10、Worly Noise
又叫细胞噪波Cell Noise,常用来模拟细胞类有孔纹理。下图来自CSDN用户@_DavidWang_,
(利用Worly Noise,可以得到几个随机点,根据这些点进行计算,可得到一个类似‘细胞’的多边形)
wnoise 使用方式和pnoise 类似,但它的形成是类似于泰森多边形的方式。
关于wnoise函数,根据Position值采样,在一定区域内随机生成生成4个点(或者2个点),这4个点又称为种子点SeedPoint,与Position的距离记作f1、f2、f3、f4(从小到大排序)。
返回的整数参数seed,官方解释为与最近种子点关联的整数。
其它理解:seed是用作区分不同区块的整数型聚类值,wnoise的躁波特征是根据预scatter撒点进行计算的,就是说这seed相当于这些撒点的特征编号,用于标注一个mesh上哪些点归属某个scatter点。(相当于给“细胞”进行编序号)。
【此处感谢B站老哥@Houdini小鱼的解答。】
【原理可以看看这篇文章:Worley Noise(一)_worley噪声__DavidWang_的博客-CSDN博客】
把距离作为每个点的高度,可以创建出类型海洋的东西。
如果种子点的距离差(种子点的中间位置),则会创建类型边界的东西。
wnoise、mwnoise、cwnoise 计算点与种子点距离的计算方式不同:
①欧几里得距离,wnoise 就是直接求两点之间的直线距离。
②曼哈顿距离,mwnoise 就是点与种子点之间的横纵坐标距离之和.。
③切比雪夫距离,cwnoise 求点与种子间的横纵坐标距离值,并对比横纵距离大小,采用其中的最大值。
计算上,mwnoise 和 cwnoise 会比wnoise 快一些,因为wnoise 涉及开方的计算。但使用效果上,mwnoise和cwnoise多了一些块状的效果,看起来会比较粗糙。
eg.看看wnoise不同距离值及差值,对物体对象本身的作用
①创建一个Grid节点,设置300*300细分,
②添加及连接一个AttributeWrangle节点,并写入代码,
int seed;
float f1, f2;
wnoise(@P * chf('scale'), seed, f1, f2);
//@P.y = f1;
//@P.y = -f1;
//@P.y = f2;
//@P.y = -f2;
//@P.y = f1 + f2;
@P.y = f2 - f1;
i@seed = seed * 0.00001; //因为seed值太大,所以乘以0.00001
③结果为:scale= 1条件下,
③根据seed值,给“细胞”上色。添加一个Color节点,设置及结果如下,
11、Worly Nosie练习一
使用wnoise的周期值为0时,表示返回的数值为非周期。(周期第四个参数为周期时间相关)
eg.①创建一个Grid节点,设置300*300细分,
②添加及连接一个AttributeWrangle节点,并写入代码,
int seed;
float f1, f2, f3, f4;
int tsize = chi('time_size');
float shift = chf('shift') * tsize;
vector pos = @P * chf('scale');
vector4 v = set(pos.x, pos.y, pos.z, shift);
wnoise(v, seed, f1, f2, f3, f4, 0, 0, 0, tsize);
float wval = f1 + f2 + f3 + f4;
f@col = wval;
@P.y = wval * ch('height');
③观察@col值在表格中的结果,其中值范围为大概0.5~3.5。添加一个Color节点,大概设置如下,
结果大概为:通道参数值看着设,Shift = $FF / $FEND,
12、Manhattan Worley Noise
mwnoise噪波,基于曼哈顿计算种子点的距离。与wnoise相似。
eg.用法与wnoise相似。
可以直接使用【10、Worly Nosie练习一】的案例,直接改个函数名即可。
结果:略。可以根据seed值范围,重新上个色看看结果。
相比wnoise,多了一些块状的效果,看起来会比较粗糙。可以看看这篇知乎@刘鹏云。
13、Chebyshev Worle Noise
cwnoise噪波,基于切比雪夫计算种子点的距离。与wnoise相似。
eg.用法与wnoise相似。
可以直接使用【10、Worly Nosie练习一】的案例,直接改个函数名即可。
结果:略。可以根据seed值范围,重新上个色看看结果。
相比wnoise,多了一些块状的效果,看起来会比较粗糙。可以看看这篇知乎@刘鹏云。
14、Anoise
anoise生成的基础效果和wnoise 类似,但是比wnoise多了三个可控制的端口(湍流、粗糙、衰减),同时anoise只能做空间的重复。大概就是海洋/海浪的汹涌程度,感兴趣可以试试下面的案例,看看不同参数控制下的具体变化。
这三个可控制的端口,让anoise可以比wnoise 做出更多的"细节"。
eg.①节点连接及设置如下,
②在类型为Points的anoise节点写入如下代码,
int psize = chi('pos_size'); //下面用于控制缩放
int tsize = chi('time_size');
vector offset = chv('offset') * @Frame / $FEND; //位移 让水流动起来
vector pos = @P * psize + offset;
pos.y = chf('shift') * tsize; //可控制缩放
int turb = chi('turb');
float rough = chf('rough');
float atten = chf('atten');
float val = anoise(pos, tsize, tsize, tsize, turb, rough, atten); //(tsize, tsize, tsize)为单个周期大小
@P.y = -val * chf('height');
f@col = val;
③结果为:大概是下面这个样子,图来自知乎@刘鹏云,
④还可以对上面这个东西进行复制,进行平铺排列,
操作:设置如下,(当然,也可以使用代码实现同样的结果—>>可以看这个知乎@刘鹏云)
⑤结果 :略
15、Voronoi noise
vnoise() 和wnoise() 类似,但是它多了一个jitter和pos1、pos2参数。
jitter 是一个向量值,控制种子点在x/y/z(随机)抖动的参数;
pos 是读取种子点位置。
eg.来试试vnoise的基本用法,及种子点抖动对生成后的 “细胞” 有何影响。
①如下图创建节点并进行设置,
②在类型为Points的vnosie_basic节点写入如下代码,
int seed;
float f1, f2;
vector pos1, pos2;
vector jitter = chv('jitter') * chf('shake');
vnoise(@P * chf('scale'), jitter, seed, f1, f2, pos1, pos2);
@P.y = f2 - f1; //更多f值运算的结果可以看【9、Worly Noise】
f@seed = seed * 0.00001;
//对pos位置生成点,方便后面使用
int pt = addpoint(0, pos1);
setpointattrib(0, 'seed', pt, f@seed);
setpointgroup(0, 'seed', pt, 1);
③结果为:通道参数看着给,滑动抖动阐述shake,结果大概像下面这样,图片来自知乎@刘鹏云
④拓展:使用Voronoi Noise节点大概也可以实现类型的效果。
大概操作就是利用上面的种子点与Voronoi Noise节点结合,在Grid内生成不规则几何体,
a)先上结果,
b)操作如下,
16、Voronoi noise练习
eg.将 “细胞” 的边界进行可视化。
①计算volume内每个体素的seed值,(关于volume可以看这篇文章)
(完整代码最后奉上),
两个Volume的采样值设为100,暂时将jitter通道值、scale通道值都设为1,
② 通过体素索引函数volumeindex 来查询,当周围位置上的点seed值是否相同,如果不相等,那么说明这两个相邻的点不在同一区域内/细胞内,
操作:继续在下面添加节点,
③【②】的代码,仅是对单个相邻点进行比较,
下面对【②】的partition_wall节点代码进行修改,让其与周围(x/y/z方向)点进行比较,
④对结果(densityVoluem)进行模糊处理,再转成多边形,
⑤一切Ok,可以对前面vnoise函数的参数进行改变(就是滑动vnoise_voluem节点jitter、scale通道值),
最终结果大概像是下面这个样子,图片来自知乎@刘鹏云,
⑥完整代码:
a)vnoise_voluem节点:计算volume内每个体素的seed值,
int seed;
float f1, f2;
vector pos1, pos2;
vector jitter = chv('jitter');
vnoise(@P * chf('scale'), jitter, seed, f1, f2, pos1, pos2);
f@seed = seed;
b)partition_wall节点:做边界
//通过体素索引函数volumeindex 来查询,当周围位置上的点seed值是否相同,
//如果不相等,那么说明这两个相邻的点不在同一区域内/细胞内,
f@density = 0.0;
//当前体素的seed值与上下左右前后进行比较
for(int i=-1; i<1; i+=2)
for(int n=-1; n<=1; n+=2){
for(int t=-1; t<=1; t+=2){
float nseed = volumeindex(0, 'seed', set(@ix + i, @iy + n, @iz + t));
//@resx、@resy、@resz 表示当前对象各轴的分辨率(边长)的意思
//条件@resx-1、resy-1、resz-1 用于删除六个面
if(f@seed != nseed && @ix > 0 && @ix < @resx - 1 && @iy > 0 && @iy < @resy - 1 && @iz > 0 && @iz < @resz - 1){
f@density = 1.0;
}
}
}
想了解更多可以看看这篇文章知乎@刘鹏云:houdini noise 03