原视频:https://www.youtube.com/playlist?list=PLzRzqTjuGIDhiXsP0hN3qBxAZ6lkVfGDI
Bili:Houdini最强VEX算法教程 - VEX for Algorithmic Design_哔哩哔哩_bilibili
Houdini版本:19.5
本节主要讲讲随机、随机分布、非确定随机、均匀随机等相关函数。
1、随机种子
随机种子(Random Seed)是一个用于生成随机数的起始值或种子值。
rand() 函数根据seed值随机返回0~1的数值。(截图仅部分,感兴趣可取官网睇)
eg.在类型为Detail的AttributeWrangle节点写入如下代码,
float seed = chf('seed');
float frand = rand(seed);
vector2 urand = rand(seed);
vector vrand = rand(seed);
vector4 prand = rand(seed);
f@frand = frand;
u@urand = urand;
v@vrand = vrand;
p@prand = prand;
结果:seed为随机值,得到的结果为 “固定” 随机值。
2、各种seed的常见用法
eg.使用随机函数改变Polygon小球的颜色,
①在小球下面,添加及连接类型为Points的AttributeWrangle节点,并写入代码,
vector cd = rand(chf('seed')); //图一
//vector cd = rand(@P + chf('seed')); //图二
v@Cd = cd;
②在小球下面,添加及连接类型为Primitives的AttributeWrangle节点,并写入代码,
//图三
vector cd = rand(@primnum); // +chf('seed')
v@Cd = cd;
③结果为:
3、Foreach循环节点内的随机函数
主要是讲如何读取Foreach循环的迭代次数。
eg.先上节点图,及结果,【foreach_begin1_metadata1】节点可从【foreach_begin1】节点处创建,
在PointWrangle节点写入代码,
int iteration = detail(1, 'iteration');
vector cd = rand(iteration + chf('seed'));
v@Cd = cd;
4、随机与Loop循环
设置点属性时,随机值须确定返回值的类型。
eg.创建随机缩放的小球。
①在类型为Detail的AttributeWrangle节点写入代码,
for(int i=0; i<10; i++){
int pt = addpoint(0, set(i, 0, 0));
//写法一
float pscale = rand(i + chf('seed'));
setpointattrib(0, 'pscale', pt, pscale);
//写法二
//setpointattrib(0, 'pscale', pt, float(rand(i + chf('seed'))));
//这可不行,须确定返回值的类型
//setpointattrib(0, 'pscale', pt, rand(i + chf('seed')));
}
②节点连接,及结果为
5、rand函数练习一
rand() 函数返回0~1,返回的值在各区间的比例大概相同。
eg.①在类型为Points的Pick_by_Percentage节点写入如下代码,
float val = rand(@P + chf('seed'));
if(val < 0.3){ //结果大概是30%的点变为红色
v@Cd = set(1, 0, 0);
setdetailattrib(0, 'redcount', 1, 'add');
}
②节点连接,及结果为,(表格里的redcount值接近总点数的30%),
6、rand函数练习二
rand函数与渐变。
eg.小球与随机+渐变色,
①创建一个类型为Polygon的Sphere,细分Frequency设为10,
②在小球下面,添加及连接类型为Points的Radom_Gradient1节点,并写入代码,
//结果一
float val = rand(@P + chf('seed'));
float threshold = fit(val, 0.0, 1.0, -1.0, 1.0);
if(@P.y < threshold){
v@Cd = set(1, 0, 0);
}
③在小球下面,添加及连接类型为Points的Radom_Gradient2节点,并写入代码,
//结果二
float val = rand(@P + chf('seed'));
val = chramp('ramp', val);
if(@P.y < val){
v@Cd = set(1, 0, 0);
}
其中,通过ramp设置为,(ramp值可以理解为,重新映射可自定义分布的值),
③节点连接,及结果为,
7、rand函数练习三
小球随着时间递增,随机缩放及改变颜色。
eg.①在类型为Points的scale_animation节点写入如下代码,
float randang = rand(@P + chf('seed')) * $PI * 2.0;
int randcycle = ceil(rand(@P + chf('seed') + 2.4) * 4); //ceil函数返回大于或等于参数的最小整数。
float f = $PI * 2.0 * @Frame / $FEND * randcycle + randang; //也可以控制播放速度
float val = sin(f); //随时间变化的随机值,val值范围-1~1
val = fit(val, -1.0, 1.0, 0.25, 1.0); //对随机值重新映射
f@pscale = val;
v@Cd = set(val, 1.0 - val, 0);
②节点连接如下图,设置:sphere7大小设为0.1;isooffset1采样值设为50;scatter2粒子数设为100,
③结果为(随机选帧截图),
8、非确定随机值
nrandom()函数 是真正的随机值,随机返回0~1。而rand() 函数的随机值具有一定的确定性。
用法与rand()函数类型。 官方文档有详细的算法介绍,感兴趣可以去瞄瞄。
eg.可在类型为Detail的AttributeWrangle观察其随机值,
float frand1 = nrandom();
float frand2 = nrandom();
float frand3 = nrandom();
f@frand1 = frand1;
f@frand2 = frand2;
f@frand3 = frand3;
//结果:略
9、nrandom练习一
小球随机颜色与随机缩放。
eg.①在类型为Detail的nrandom_scale_color节点写入如下代码,
int num = chi('num'); //参数设为6,即 6行*6列的点
for(int i=0; i<num; i++){
for(int n=0; n<num; n++){
for(int t=0; t<num; t++){
int pt = addpoint(0, set(i, n, t));
vector col = nrandom();
float sc = nrandom();
setpointattrib(0, 'Cd', pt, col);
setpointattrib(0, 'pscale', pt, sc);
}
}
}
②节点及结果(真随机),节点设置:sphere8大小暂设为0.5,
9、random函数
random() 函数根据整数的位置position值(float、vector、vector3、vector4)返回不同的随机数。它的参数会被转为整数int(比如seed为2.5、2.1、2.94,seed会被转为2、2、2)。
eg.①节点连接图往后看,
①在类型为Points的height_with_rand节点输入以下代码,
float val = rand(@P + chf('seed'));
@P.y = val * 2; //结果一
②在类型为Points的height_with_random节点输入以下代码,
float val = random(@P + chf('seed'));
@P.y = val * 2; //结果二
③节点连接如下,其中grid2设置为100行*100列,
以及结果为:seed设为0.3,)rand()函数时比较均分的随机值),
10、 随机分布
random_brj():生成均匀分布的随机数。
random_sobo():生成更均匀分布的随机数。
eg.在一根直线上创建50个随机点,看看rand函数与上面这两个函数的差别。
①(节点连接图在后面)在类型为Detail的rand_distribution节点输入以下代码,
// rand() 函数结果
vector pos = point(1, 'P', 1);
for(int i=0; i<chi('num'); i++){
float val = rand(chf('seed') + i);
vector newpos = pos * val;
int pt = addpoint(0, newpos);
}
②在类型为Detail的random_brj_distribution节点输入以下代码,
// random_brj() 函数结果
vector pos = point(1, 'P', 1);
for(int i=0; i<chi('num'); i++){
float val = random_brj(chf('seed'), i );
//第二个参数是要提取序列中的哪个条目。这应该是一个整数序列,如ptnum,以便distribution属性工作。
vector newpos = pos * val;
int pt = addpoint(0, newpos);
}
③在类型为Detail的random_sobol_distribution节点输入以下代码,
// random_sobol() 函数结果
vector pos = point(1, 'P', 1);
for(int i=0; i<chi('num'); i++){
float val = random_sobol(chf('seed'), i );
//第二个参数是要提取序列中的哪个条目。这应该是一个整数序列,如ptnum,以便distribution属性工作。
vector newpos = pos * val;
int pt = addpoint(0, newpos);
}
④节点连接图,及结果如下(num设为50,seed值随意),
11、向量随机均匀分布
sample_sphere_uniform(vector)函数:随机生成一个长度0~1的向量。拓展:参数X、Y可控制旋转,Z控制长度(0~1)。
eg.本次做一个刺猬球。
在类型为Detail的AttributeWrangle节点写入如下代码,
int cpt = addpoint(0, set(0, 0, 0));
for(int i=0; i<chi('num'); i++){
//结果一
//vector val = randl(i + chf('seed'));
//结果二
vector val = random_sobol(chf('seed'), i);
vector dir = normalize(sample_sphere_uniform(val));
int pt = addpoint(0, dir);
addprim(0, 'polyline', cpt, pt);
}
结果为:seed值随意,num=300条件下,使用函数random_sobol分布更均匀,