Perlin Noise
参考文献:
1 http://en.wikipedia.org/wiki/Perlin_noise
2 http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html
3 http://www.mrl.nyu.edu/~perlin/doc/oscar.html#noise
目的:Generate a perlin noise image
图一 perlin noise 图像
对于如何获得一个periin noise,wiki上说大体上分为三个部分:
1Grid definition
2 Dot product
3Interpolation
前提:计算整张noise图像的问题可以转化为求取一点(x,y)的noise输出结果
第一个部分:Define an n-dimensional grid,实际上就是创建一个grid,并给每一个node随机一个梯度。
第二个部分:计算点积,“to determine which grid cell a particular point falls” 通过计算点积确定这个点该怎样变化。但是如何变化了,文献2中有详细介绍。这里抽出典型图做一下说明。
假如我们要计算noise(x,y)的结果
图二 noise(x,y)这一点和他周围的4个节点
图三 4个节点的梯度向量(在第一步中计算出来) 这里是第一类向量(4个)
图四 计算矢量距离,这里是第二类向量(4个)
计算=========点积==============
s = g(x0, y0) * ((x, y) - (x0, y0)) ,
t = g(x1, y0) * ((x, y) - (x1, y0)) ,
u = g(x0, y1) * ((x, y) - (x0, y1)) ,
v = g(x1, y1) * ((x, y) - (x1, y1)) .
结果如下:
图五 点积的意义
这样我们就得到了4个结果。但是我输入的只是一个点,也只需要一个值。所以就来到了第三步:Interpolation
一个很自然的插值想法是均值,(s+t+u+v)/4就不结束了???但是为了更平滑的结果(我猜的)。perlin noise使用如下的插值方式。
图六 插值方式
左边的曲线为:
S = 3X^2-2x^3;[指数参数不清楚,网页显示错误就给了一个框,我查了perlin自己的代码,就填入了2,3]
这个是一种插值方式:但是怎么看了?
他的作用是:让靠近1的值变得更靠近1,靠近0的更靠近0(废话)。加入了权重,使得输入点的结果更加接近最靠近的节点的点积(就是加入了一个权重的作用)。
根据位置(x-x0)判断实际插值的比例Sx在使用这个比例去插值同一维度(这里是x方向)上两个结果
现在我们有四个值s,u,v,t。经过变换只有两个了。
图七 这里使用y方向的距离来计算另外一个插值比例,将a,b插值
这样就得到了最终的结果。
Sy=3(y-y0)^2-2(y-y0)^3;
z=a+Sy(b-a)
这里的z就是noise(x,y)的结果。这样我们就获得了noise结果。
perlin noise至此结束。