9.WebGL Shader 随机数

我们前面所讲的函数均为遵守秩序的函数,但我们这节课将给大家讲解随机数。在glsl中并没有提供生成随机数函数公式,如果需要实现随机数函数利用glsl现有公式模拟出随机数值。随机数在glsl中有很多应用像是噪点图就是利用随机数来实现。因此在实现噪点图之前先了解如何生成随机数函数。

一维随机数

我们在前面给大家介绍过fract函数与sin函数,在本节课中我们将利用这两个函数得到随机数字。sin函数值域范围在[-1,1]之间,在这个范围内可以将正弦函数值乘以一个比较大的值例如1000,然后使用fract函数只取小数部分的值,就能模拟打散成伪随机数。最后结果会发现相乘的数值越大sin函数获取到的结果越离散越没有规律。

float random(float x)
{
    float y = fract(sin(x)*100000.0);
    return y;
}

我们来看一下这个上述函数图像效果:

在这里插入图片描述

由图像可以清晰分辨出,fract(sin(x)*100000.0) 返回的值参差不齐,故而就形成了随机数字。

肯定有同学好奇,为什么sin函数乘那么大的数字,如果不乘又如何:
在这里插入图片描述

sin函数乘20.3,这看起来很酷,但是我们明显发现线的密集度不在像*100000.0那样高了。
在这里插入图片描述

根据上述实践我们得到sin函数倍数越大,随机数变化越明显。当我们不断的进行增大时,其实我们增大的是sin函数的幅度,但是由于fract的限制,这其实是增加fract的定义域,它会形成-1——1之间的更加密集的点。我们shader中结果如下图所示:

在这里插入图片描述

二维随机函数

了解一维随机函数之后可以将它应用到二维随机上。在glsl纹理顶点上有x轴和y轴,就需要将二维向量转化成一维浮点数。这里将二维uv向量使用dot函数将各分量分别相乘后相加,这里相乘的分量值是vec2(12.9898,78.233)(若有必要可以修改该向量值)。最后和一维随机函数一样执行sin函数和fract函数获取最终伪随机数。

float random (vec2 uv)
{
    return fract(sin(dot(uv.xy, vec2(12.9898,78.233))) * 43758.5453123);
}

我们可以加入时间变量,让随机数动态起来

float random (vec2 uv)
{
    return fract(sin(dot(uv.xy, vec2(12.9898,78.233)+time)) * 43758.5453123);
}

这个图像像极了我们童年时候的老电视机,没有信号,花屏的时候。你是不是觉得这样就完了,实际上目前的随时数不是真正的随机,他是“伪随机”。比如我们看以下的代码
在这里插入图片描述

float random (vec2 uv)
{
    return fract(sin(dot(uv.xy, vec2(1.,1.)+time)) * 43758.5453123);
}

由上述代码显示的结果我们可以发现,再等于特定值得时候,返回的结果是固定的,并且random函数返回来的数值过于随意化,而我们在日常中看到的木头斑纹、大理石等等似乎在随意化中又有一种规律性,为了解决此问题,我们引出了下一论题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值