HoudiniVex笔记_P19_NoiseBasics噪波

原视频: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的回答,

[Houdini] Curl Noise - 哔哩哔哩

 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

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值