perlin噪声函数

1649 篇文章 12 订阅
1623 篇文章 23 订阅
  http://www.cnblogs.com/mikewolf2009/articles/1608087.html

http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

许多人在他们的程序中使用“随机数产生器”,以使得物体的运动行为更加自然,或者用来生成纹理。随机数产生器在一些情况下很有用,但是它们生成的结果和自然结果相比,往往显得比较粗糙和生硬。这篇文章介绍使用广泛的Perlin函数,它常用在模拟自然物体的地方,比如地形,海水等。

自然物体通常是分形的,有各种各样的层次细节,比如山的轮廓,通过高度区分就有高山(mountain,高度变化大)、山丘(hill,高度变化适中)、巨石(高度变化小、石头(高度变化很小)等。另外,比如草地、海浪、跑动的蚂蚁、摇晃的树枝、风、大理石的花纹等等,这些都呈现出了或大或小的细节变化。Perlin噪声函数通过噪声函数来模拟这些自然景观。

要构造一个Perlin函数,你首先需要一个噪声函数和一个插值函数

 

1、 噪声函数

噪声函数本质上就是一个基于种子的随机数产生器。输入参数为一个整数,输出结果为基于输入参数的随机数。如果你两次输入同样的参数,则结果都是一样的。

左上图是一个噪声函数例子,它的输出值范围是[0,1],分布范围在x轴上。右上图是通过光滑插值函数处理后的结果。

在进一步学习Perlin函数之前,我们先看一些定义,其实这些都是高中物理的概念,很简单。比如上图的正弦波,波长(Wavelength)就是两个波谷指尖的距离,频率就是1/Wavelength,波幅(Amplitude)就是波的高度。

 

2、 创建Perlin噪音函数

假如现在你有各种各样不同频率和幅度的光滑函数(smooth function),把他们组合在一起,就能产生一个比较好的Perlin噪声函数。

          

 

 

组合在一起后的效果如下图,是不是很类似山的形状,确实很多3d程序中的地形就是利用2维的噪声函数。

 

下面我们看看单个2维光滑函数,组合在一起形成的2维噪声函数:

 

   

  

下面是各个函数组合在一起的效果:

我们现在比较关注,把这些噪声函数叠加在一起时候,如何选择他们的频率和幅度?在上面一维的例子中,后面的每个函数的频率是前面的2倍,幅度是前面1/2,通常是这样来做,你也可以自己尝试其它的频率和幅度的组合,看看效果如何,比如对于小山丘,你可以使用大幅度低频率以及小幅度高频率,看看生成的山丘又何不同,甚至你可以用地频率低幅度生成岩石表面。

通常定义Persistence为幅度/频率,这是分形几何的发明人Mandelbrot创造的。Matt也定义Persistence的概念,而且更加直观,它的定义如下:

frequency = 2i
amplitude = persistencei

 

i表示增加的第i个噪声函数,下面的图很好的解释了这个概念:

 

Frequency

1

 

2

 

4

 

8

 

16

 

32

 

 

 

Persistence = 1/4

 

+

 

+

 

+

 

+

 

+

 

=

 

 

Amplitude:

1

 

1/4

 

1/16

 

1/64

 

1/256

 

1/1024

 

result

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Persistence = 1/2

 

+

 

+

 

+

 

+

 

+

 

=

 

 

Amplitude:

1

 

1/2

 

1/4

 

1/8

 

1/16

 

1/32

 

result

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Persistence = 1 / root2

 

+

 

+

 

+

 

+

 

+

 

=

 

 

Amplitude:

1

 

1/1.414

 

1/2

 

1/2.828

 

1/4

 

1/5.656

 

result

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Persistence = 1

 

+

 

+

 

+

 

+

 

+

 

=

 

 

Amplitude:

1

 

1

 

1

 

1

 

1

 

1

 

result

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Octaves(倍频函数):

我们增加的函数称作octave函数.,主要是因为后面的每个函数都是前面函数频率的2倍。增加octave函数的数量取决于你。这儿我给的建议是:如果你用Perlin函数渲染图形图像,记住太高的频率可能不能显示,因为屏幕像素已经不能表示这些细节。一些Perlin噪音函数的实现可以根据屏幕限制,自动调节octave函数的数量。另外,当幅度太小时,也要停止增加octave函数。

 

下面我们看一个简单的噪音函数(一个随机数产生器)的代码,它返回浮点数[-1,1]



Code
function Noise1(integer x, integer y)    n = x + y * 57    n = (n<<13) ^ n;    return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);      end function  function SmoothNoise_1(float x, float y)    corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16    sides   = ( Noise(x-1, y)  +Noise(x+1, y)  +Noise(x, y-1)  +Noise(x, y+1) ) /  8    center  =  Noise(x, y) / 4    return corners + sides + center  end function  function InterpolatedNoise_1(float x, float y)      integer_X    = int(x)      fractional_X = x - integer_X      integer_Y    = int(y)      fractional_Y = y - integer_Y      v1 = SmoothedNoise1(integer_X,     integer_Y)      v2 = SmoothedNoise1(integer_X + 1, integer_Y)      v3 = SmoothedNoise1(integer_X,     integer_Y + 1)      v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1)      i1 = Interpolate(v1 , v2 , fractional_X)      i2 = Interpolate(v3 , v4 , fractional_X)      return Interpolate(i1 , i2 , fractional_Y)  end function  function PerlinNoise_2D(float x, float y)      total = 0      p = persistence      n = Number_Of_Octaves - 1      loop i from 0 to n          frequency = 2i          amplitude = pi          total = total + InterpolatedNoisei(x * frequency, y * frequency) * amplitude      end of i loop      return total  end function
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值