【GPU Gems 学习笔记】Implementing Improved Perlin Noise

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LeeXxs/article/details/89282420

柏林噪声

柏林噪声算法(Perlin Noise)是Ken Perlin在1983年提出的一种渐变噪声。和完全随机的白噪声相比,柏林噪声做到了杂乱而有序。能够更好地模拟自然界中的随机现象的复杂性和相互间的关联性,常被用于电影视觉效果。

a. 一维柏林噪声

  • 随机出一些散点;
  • 对这些点进行插值获得连续的曲线;
  • 用Unity的GL屏幕划线写了一下,这里用的插值函数是f(t) =6 t^{5} - 15 t^{4} + 10 t^{3}

b. 二维柏林噪声

  • 首先定义一个晶格结构,二维的情况下就是一个网格结构。并且为每个晶格顶点赋予一个"伪随机"的梯度向量;

   

  • 对于每个二维坐标点,找到与其相邻的4个晶格顶点,计算该点到各个晶格顶点的距离向量;

  • 四个距离向量分别与对应的梯度向量做点乘,得到点乘结果; 

  • 最后使用缓和曲线(ease curves)对点乘结果做插值求权重和;

  • 效果如下:

 

一些细节

 插值函数

  • 最原始的插值函数使用的是:f(t) =3 t^{2} - 2 t^{3};函数的二阶导数就是一阶导数的变化率,在图形上主要表现为函数图像的凹凸性,而它的二阶导数 6 - 12t 在 t = 0 和 t = 1 时均不等于0。那么相邻的晶格处的二阶导并不连续,使得在使用噪声的导数时,将导致出现失真的效果,例如制作凹凸贴图(凹凸贴图表面的光照效果随相应的高度函数的导数而变,所以二阶导数的不连续性是可以看见的)。
  • Perlin在2002发表的论文做了改进,改用5次样条做插值:f(t) =6 t^{5} - 15 t^{4} + 10 t^{3},它在 t = 0 和 t = 1 处的 12 阶导数均为 0。 


晶格顶点与坐标

以三维空间为例,设三维空间中的任意一点为 (x,y,z):空间中的晶格坐标为(i,j,k),其坐标都是整数;

  • 定义一点的坐标(x,y,z)为一个整数加上小数部分,(x,y,z) = (i+u,j+v,k+w)
  • 那么围绕该点的单位立方体晶格为:
    (i,j,k),(i+1,j,k),(i,j+1,k),(i,j,k+1),
    (i+1,j + 1,k),(i,j+1,k+1),(i+1,j,k+1),(i+1,j+1,k+1)
  • 将计算过程中的坐标范围映射到满足上述要求的范围内,比较方便计算。

伪随机梯度向量

  • 在选择晶格顶点的梯度向量的预处理阶段,我们可以借助一些随机函数,在单位正方形(二维)/单位立方体(三维)内生成梯度向量的各个分量,然后剔除那些不在单位圆(二维)/单位球(三维)内的向量,直至找到了所需数目的随机梯度向量。  将得到的梯度向量存储在一个查找表G[n]里,假设晶格的坐标(i,j,k),并且0\leq i,j,k \leq 255,那么 n = 256
  • 照常理来说,二维下需要n^{2}个梯度向量,三维下需要n^{3}个梯度向量,只有n个的情况下势必会有重复。但Perlin认为重复是可以接受的,只要它们的间距足够大就不会被察觉。
  • 除此之外,Perlin还预先生成了一个大小为n的随机排列数组P[n],里面存储的是乱序排列的0到n-1的值。
  • 对于三维空间中的某一点坐标(i,j,k),可以获取相对应的晶格:G = G[(P[(P[i] + j)_m_o_d_ \, _ n]+k)_m_o_d_ \, _ n]

  • 在后续的改进中,Perlin改用12个伪随机斜率代替256个,它们由立方体的12条棱的中点组成:(0,\pm 1,\pm 1),(\pm 1,0,\pm 1),(\pm 1,\pm 1,0),这样可以改善“污点”使其更少。 
      a.旧的噪声            b.较少污点的噪声
  • 改善的原因是,相近的梯度向量如果挤在一起,使用噪声函数实现就会出现污点的情况,而12个斜率的方向是均匀分布的,不会挤在一起。
  • 另外一点,该方法提升了运算效率,因为它可以避免乘法运算,如 \small (x,y,z) 和 \small (1,1,0) 的点积可以按照 \small x + y 做加法。

wikipedia
https://en.wikipedia.org/wiki/Perlin_noise
Perlin2002年的论文
https://mrl.nyu.edu/~perlin/paper445.pdf
前面是对Perlin Noise详细的讲解,后面是与fbm(分形噪声)的结合
http://flafla2.github.io/2014/08/09/perlinnoise.html
https://www.jianshu.com/p/987b1349c94d
可平铺的Perlin噪声 
https://www.gamedev.net/blogs/entry/2138456-seamless-noise/
http://ronvalstar.nl/creating-tileable-noise-maps
乐乐女神对噪声的整理(Perlin,Value,Simplex,Fractal(fbm))
https://blog.csdn.net/candycat1992/article/details/50346469 

猜你喜欢

转载自blog.csdn.net/LeeXxs/article/details/89282420