噪声算法如何避免成为白噪声的
能直接看懂下面代码块中的博客是最好的。
本文中的代码是对这篇博客中引用的官方C++代码在Unity中的实现,本文最后会贴出来。
我对噪声的理解原理就是“一个顶点延伸出去一条向量,对这条向量做插值。”
我这里解释一下噪声的“规律”:
噪声代码中的Fade平滑是用一个计算数学函数f(x)的方法,这个函数的要求是对受限的传入值,返回[0,1]的结果。
因为lerp插值需要的只有[0,1]这个区间。
在官方算法中,表现为: 对参数取小数部分,使用一个定义域为[0,1]时,值域为[0,1]的函数。
对于函数的选取有三个要求:f(0)=0、f(0.5)=0.5、f(1)=1,官方使用的是第三个公式:

以上解释的是平滑参数部分。

接下来说明梯度与顶点组。
博客代码使用Vextor3[]记录备选梯度,使用随机从备选梯度中抽取梯度为顶点赋值梯度,由此,其噪声图实现了随机。
上方代码中的顶点是一个三维数组记录的,顶点组可以认为是一个取样样本,或者通俗的说是Minecraft一个种子会得到相同的地图一样,只要是相同的顶点组,使用相同的算法就能得出一样的结果。
这是官方给出的遍历,i、j受限于Hash梯度表的Lenght、i、j+=?则取决于你希望生成噪声的像素大小,官方这个就是生成一个400*400像素的噪声图。
而官方噪声的随机就来自于梯度,之后你们运行代码,如果不随机梯度或修改取样间隔,那么噪声图是一模一样的。
也就是说,通过随机参数构建了一个三维n*n*n空间,世界的顶点都具有一定的“力量”,对非顶点区域有,总的来说越远越弱的掌控力。
而二维噪声就是对这个空间的部分区域的切片取样。

说明一些细节:
为什么要与255?因为在下面的算法中有
在极限状态下,会有
index = 255 + 255 + 1 = 511,正好是Length为512的数组的最大索引。
各种算法都要或多或少的比 按像素生成噪声图的main语句中的i、j的结束值 多一些顶点。
又比如博客中的教学程序,声明了25的顶点,但for循环应该截止在24。
Length为512的数组。

这里对插值的参数们进行代入法。
我们采用for循环到16的顶点,期望像素为512x512。
纹素就是16/512=0.03125

选取像素点115,115,对应x,y值是3.59375。
由于是2维图对3维采样,因此z定值即可,这里采用7.8

选取像素点118,115,对应x值是3.6875,y值是3.59375。
由于是2维图对3维采样,因此z定值即可,这里采用7.8
对于在同一顶点区间的两个像素点,他们的插值参数u、v、w差不多,取用的梯度Hash也是相同的,这样就能很大程度上保证两个像素获得的灰度值差不多,就是非白噪声了。
对噪声(n+1)/2能更好的将值限制在(0,1),小于零黑大于1白,少量的极大值也是噪声的一部分。