简单聊聊 Perlin 噪声(下篇)

程序开发中总会用到随机方法,一般的随机方法虽然通用,但是产生的随机数又因为过于"随机",不适合用来生成平滑连续的随机数据(譬如自然地形的高度),这个时候我们便需要使用特殊的随机方法了, Perlin 噪声便是一种能够产生平滑(随机)数值的随机方法.

Perlin 噪声

理解了二维的 Value 噪声,我们就可以进一步来看 二维的 Perlin 噪声了.

二维 Perlin 噪声的生成方式和 二维 Value 噪声的生成方式大体相同,二维 Perlin 噪声也是根据给定的坐标选取对应的正方形,并将该正方形的四个顶点作为插值端点,但是在 Perlin 噪声中,端点并不是直接对应一个随机值,而是对应一个二维(梯度)向量,另外我们再取端点到给定坐标的方向(距离)向量,这两个向量的点积才是我们用来插值的随机值,说的有些抽象,我们可以看看下面的示意图(蓝色向量为梯度向量,红色向量为距离向量):

perlin_7

除此之外, 二维 Perlin 噪声的生成过程就和 二维 Value 噪声的生成过程就没有什么不同了( a r , b r , c r , d r ar, br, cr, dr 为四个端点对应的梯度向量, a v , b v , c v , d v av, bv, cv, dv 为四个端点与给定坐标形成的距离向量, u u x x 轴原始的线性插值系数, v v y y 轴原始的线性插值系数(实际上,通过 u u , v v 我们就能得到 a v , b v , c v , d v av, bv, cv, dv ) ):

u = 6 u 5 15 u 4 + 10 u 3 v = 6 v 5 15 v 4 + 10 v 3 a = d o t ( a r , a v ) b = d o t ( b r , b v ) c = d o t ( c r , c v ) d = d o t ( d r , d v ) e = ( 1 u ) a + u b f = ( 1 u ) c + u d r = ( 1 v ) e + v f u' = 6u^5 - 15u^4 + 10u^3 \\ v' = 6v^5 - 15v^4 + 10v^3 \\ a = dot(ar, av) \\ b = dot(br, bv) \\ c = dot(cr, cv) \\ d = dot(dr, dv) \\ e = (1 - u')a + u'b \\ f = (1 - u')c + u'd \\ r = (1 - v')e + v'f

下面是二维 Perlin 噪声的示意图(其中各个坐标点的明暗程度代表了相应的随机值):

perlin_8

(注:上图展示的是实际生成的二维 Perlin 噪声数据,显示上没有做额外的插值处理,所以看起来会有明显的边界)

Simplex 噪声

Simplex 噪声是 Perlin 噪声的改进版,(二维)Perlin 噪声通过选取对应的正方形(方形)来获取插值端点,(二维)Simplex 噪声则是选取对应的三角形(单形)来获取插值端点.这样做的好处是单形的顶点数是随着维度线性增长的,而方形的顶点数是随着维度指数增长的,基于此,Simplex 噪声的计算复杂度要比 Perlin 函数低不少,但另一方面,在 Perlin 噪声中,从给定坐标获取对应的方形非常简单,只需要对坐标取底(floor)即可,但在 Simplex 噪声中,从给定坐标获取对应的单形则比较复杂.

perlin_9
(二维单形示例)

Simplex 噪声中随机值的生成也和 Perlin 噪声有所不同,有兴趣进一步了解的朋友可以从这里看起~

多维 Perlin 噪声

从 二维 Perlin 噪声扩展到 多维 Perlin 噪声还是比较简单的,譬如 三维 Perlin 噪声,使用的是立方体(三维中的方形)的 8 个顶点作为插值端点,更高维度的话,则是使用 超立方体 的各个端点作为插值端点,端点个数与维度( D D )呈指数关系( 2 D 2^D )

一维 Perlin 噪声

说了多维 Perlin 噪声,那 一维 Perlin 噪声如何生成呢(毕竟一维坐标下并没有向量的概念)? 实际上,我们还是可以在一维坐标上"定义"二维向量,只需要将该二维向量的 y y 轴数值设置为 0 0 即可,同样的,我们也可以依此计算出距离向量, 这样我们就可以沿用 二维 Perlin 噪声 的生成方法来生成 一维 Perlin 噪声了.

这里有一份相关的代码实现,有兴趣的朋友可以看看~

分形噪声

很多讲解 Perlin 噪声的文章也会提到 分形噪声,不过分形噪声本质上并不是某种特定类型的噪声(自然也不是 Perlin 噪声),而更应该说是一种噪声的叠加方法,他是将很多个不同频率,不同振幅的基础噪声(譬如 Value噪声, Perlin噪声 等等)相互叠加,最后形成的一种噪声(统称为分形噪声).

更多细节可以从这里开始了解~

更多资料