柏林噪声 perlin noise

转载 2007年10月15日 15:19:00
Perlin Noise  在wikipia上,可以查到定义,这里不多说了,http://freespace.virgin.net/hugo.elias/models/m_perlin.htm 上有完整的英文,http://www.azure.com.cn/article.asp?id=291 是带有翻译的英文, 看来这篇文章是原始作者的大作了。转帖过来

柏林噪声(Perlin Noise)(译)


Many people have used random number generators in their programs to create unpredictability, make the motion and behavior of objects appear more natural, or generate textures. Random number generators certainly have their uses, but at times their output can be too harsh to appear natural. This article will present a function which has a very wide range of uses, more than I can think of, but basically anywhere where you need something to look natural in origin. What's more it's output can easily be tailored to suit your needs.

If you look at many things in nature, you will notice that they are fractal. They have various levels of detail. A common example is the outline of a mountain range. It contains large variations in height (the mountains), medium variations (hills), small variations (boulders), tiny variations (stones) . . . you could go on. Look at almost anything: the distribution of patchy grass on a field, waves in the sea, the movements of an ant, the movement of branches of a tree, patterns in marble, winds. All these phenomena exhibit the same pattern of large and small variations. The Perlin Noise function recreates this by simply adding up noisy functions at a range of different scales.

To create a Perlin noise function, you will need two things, a Noise Function, and an Interpolation Function.

Introduction To Noise Functions

A noise function is essentially a seeded random number generator. It takes an integer as a parameter, and returns a random number based on that parameter. If you pass it the same parameter twice, it produces the same number twice. It is very important that it behaves in this way, otherwise the Perlin function will simply produce nonsense.


Here is a graph showing an example noise function. A random value between 0 and1 is assigned to every
point on the X axis.


By smoothly interpolating between the values, we can define a continuous function that takes a non-integer as a parameter. I will discuss various ways of interpolating the values later in this article.


Before I go any further, let me define what I mean by amplitude and frequency. If you have studied physics, you may well have come across the concept of amplitude and frequency applied to a sin wave.


Sin Wave
The wavelength of a sin wave is the distance from one peak to another. The amplitude is the height of the wave. The frequency is defined to be 1/wavelength.
正玄波的波长(wavelength)是两个波峰只间的距离。振幅是此波的高度。频率我们定义为 1/波长(wavelength)。


Noise Wave
In the graph of this example noise function, the red spots indicate the random values defined along the dimension of the function. In this case, the amplitude is the difference between the minimum and maximum values the function could have. The wavelength is the distance from one red spot to the next. Again frequency is defined to be 1/wavelength.

Creating the Perlin Noise Function

Now, if you take lots of such smooth functions, with various frequencies and amplitudes, you can add them all together to create a nice noisy function. This is the Perlin Noise Function.

Take the following Noise Functions


Add them together, and this is what you get.

You can see that this function has large, medium and small variations. You may even imagine that it looks a little like a mountain range. In fact many computer generated landscapes are made using this method. Of course they use 2D noise, which I shall get onto in a moment.

You can, of course, do the same in 2 dimensions.

Some noise functions are created in 2D



Adding all these functions together produces a noisy pattern.



When you're adding together these noise functions, you may wonder exactly what amplitude and frequency to use for each one. The one dimensional example above used twice the frequency and half the amplitude for each successive noise function added. This is quite common. So common in fact, that many people don't even consider using anything else. However, you can create Perlin Noise functions with different characteristics by using other frequencies and amplitudes at each step. For example, to create smooth rolling hills, you could use Perlin noise function with large amplitudes for the low frequencies , and very small amplitudes for the higher frequencies. Or you could make a flat, but very rocky plane choosing low amplitudes for low frequencies.

To make it simpler, and to avoid repeating the words Amplitude and Frequency all the time, a single number is used to specify the amplitude of each frequency. This value is known as Persistence. There is some ambiguity as to it's exact meaning. The term was originally coined by Mandelbrot, one of the people behind the discovery of fractals. He defined noise with a lot of high frequency as having a low persistence. My friend Matt also came up with the concept of persistence, but defined it the other way round. To be honest, I prefer Matt's definition. Sorry Mandelbrot. So our definition of persistence is this:
为了让这些更简单易懂,同时为了避免重复振幅和频率这两个词,我们用一个数来表示每个频率下的振幅,这个数就是持续度(Persistence)。这里的词和它的真实意义有些歧异。这个术语原本是Mandelbrot提出的,他是发现分形现象的人中的一个。他定义噪声拥有大量的高频率将体现出低的持续度。我的朋友Matt也想出了持续度的概念,但是是通过另外一种方式定义它的。诚然,我更喜欢Matt的定义方式。对不起了,Mandelbrot. 所以我们这样定义持续度(persistence):
frequency = 2i
amplitude = persistencei
Where i is the ith noise function being added. To illustrate the effect of persistence on the output of the Perlin Noise, take a look at the diagrams below. They show the component noise functions that are added, the effect of the persistence value, and the resultant Perlin noise function.
i 是表示第i个被叠加的噪声函数。为了展示柏林函数在输出上持续度的表现效果,请看下下面的图表。他们展示了叠加的每个组成部分,持续度的效果和最终的柏林函数。



Each successive noise function you add is known as an octave. The reason for this is that each noise function is twice the frequency of the previous one. In music, octaves also have this property.

Exactly how many octaves you add together is entirely up to you. You may add as many or as few as you want. However, let me give you some suggestions. If you are using the perlin noise function to render an image to the screen, there will come a point when an octave has too high a frequency to be displayable. There simply may not be enough pixels on the screen to reproduce all the little details of a very high frequency noise function. Some implementations of Perlin Noise automatically add up as many noise functions they can until the limits of the screen (or other medium) are reached.

It is also wise to stop adding noise functions when their amplitude becomes too small to reproduce. Exactly when that happens depends on the level of persistence, the overall amplitude of the Perlin function and the bit resolution of your screen (or whatever).

Making your noise functions

What do we look for in a noise function? Well, it's essentially a random number generator. However, unlike other random number generators you may have come across in your programs which give you a different random number every time you call them, these noise functions supply a random number calculated from one or more parameters. I.e. every time you pass the same number to the noise function, it will respond with the same number. But pass it a different number, and it will return a different number.

Well, I don't know a lot about random number generators, so I went looking for some, and here's one I found. It seems to be pretty good. It returns floating point numbers between -1.0 and1.0.
function IntNoise(32-bit integer: x)      

x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end IntNoise function
Now, you'll want several different random number generators, so I suggest making several copies of the above code, but use slightly different numbers. Those big scarey looking numbers are all prime numbers, so you could just use some other prime numbers of a similar size. So, to make it easy for you to find random numbers, I have written a little program to list prime numbers for you. You can give it a start number and an end number, and it will find all the primes between the two. Source code is also included, so you can easily include it into your own programs to produce a random prime number. Primes.zip
现在,你将要需要几个不同的随机数生成器,所以我建议把上面的代码复制几个拷贝,然后稍微修改下里面的参数。那些可怕的数字都是质数,所以你可以改成其他差不多大小的质数(让我想起了 hash key生成),为了让你轻松的找的随机数,我已经写了一个小程序来为你列出质数。你只用输入一个起始值和一个结束值,它找到所有在两值之间的质数。源代码也提供,所以你可以轻松的包含到你自己的程序中来生成随机的质数.Primes.zip


Having created your noise function, you will need to smooth out the values it returns. Again, you can choose any method you like, but some look better than others. A standard interpolation function takes three inputs, a and b, the values to be interpolated between, and x which takes a value between 0 and1. The Interpolation function returns a value between a and b based on the value x. When x equals 0, it returns a, and when x is 1, it returns b. When x is between 0 and1, it returns some value between a and b.
当创建了你的噪声函数,你将需要平滑下他的返回值。再次,你可以选择任何你喜欢的方式,但是有一些效果更好。一个标准的插值函数需要三个输入,a 和 b, 需要在a和b之间进行插值,还有x,它取值范围是0到1。插值函数返回a到b之间取决与x的一个值。当x等于0,它返回a,当x等于1时,它返回b。当x 是0到1之间时,它将返回a到b之间的某值。

Linear Interpolation:

Looks awful, like those cheap 'plasmas' that everyone uses to generate landscapes. It's a simple algorithm though, and I suppose would be excusable if you were trying to do perlin noise in realtime.
function Linear_Interpolate(a, b, x)
  return a*(1-x) + b*x
end of function
Cosine Interpolation:

This method gives a much smother curve than Linear Interpolation. It's clearly better and worth the effort if you can afford the very slight loss in speed.
function Cosine_Interpolate(a, b, x)
  ft = x * 3.1415927
  f = (1 - cos(ft)) * .5

  return a*(1-f) + b*f
end of function
Cubic Interpolation:

This method gives very smooth results indeed, but you pay for it in speed. To be quite honest, I'm not sure if it would give noticeably better results than Cosine Interpolation, but here it is anyway if you want it. It's a little more complicated, so pay attention. Whereas before, the interpolation functions took three inputs, the cubic interpolation takes five. Instead of just a and b, you now need v0, v1, v2 and v3, along with x as before.


v0 = a 前面一点
v1 = a 点
v2 = b 点
v3 = b 后面一点

function Cubic_Interpolate(v0, v1, v2, v3,x)
  P = (v3 - v2) - (v0 - v1)
  Q = (v0 - v1) - P
  R = v2 - v0
  S = v1

  return Px3 + Qx2 + Rx + S
end of function
Smoothed Noise

Aside from Interplolation, you can also smooth the output of the noise function to make it less random looking, and also less square in the 2D and 3D versions. Smoothing is done much as you would expect, and anyone who has written an image smoothing filter, or fire algorithm should already be familiar with the process.
Rather than simply taking the value of the noise function at a single coordinate, you can take the average of that value, and it's neighbouring values. If this is unclear, take a look at the pseudo code below.

On the right, you can see a little diagram illustrating the difference between smoothed noise, and the same noise function without smoothing. You can see that the smooth noise is flatter, never reaching the extremes of unsmoothed noise, and the frequency appears to be roughly half. There is little point smoothing 1 dimensional noise, since these are really the only effects. Smoothing becomes more useful in 2 or three dimensions, where the effect is to reduce the squareness of the noise. Unfortunately it also reduces the contrast a little. The smoother you make it, obviously, the flatterthe noise will be.


1-dimensional Smooth Noise
function Noise(x)
end function

function SmoothNoise_1D(x)

return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4

end function
2-dimensional Smooth Noise
function Noise(x, y)
end function

function SmoothNoise_2D(x>, 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
Putting it all together

Now that you know all that, it's time to put together all you've learned and create a Perlin Noise function. Remember that it's just several Interpolated Noise functions added together. So Perlin Noise it just a function. You pass it one or more parameters, and it responds with a number. So, here's a simple 1 dimensional Perlin function.

The main part of the Perlin function is the loop. Each iteration of the loop adds another octave of twice the frequency. Each iteration calls a different noise function, denoted by Noisei. Now, you needn't actually write lots of noise functions, one for each octave, as the pseudo code seems to suggest. Since all the noise functions are essentially the same, except for the values of those three big prime numbers, you can keep the same code, but simply use a different set of prime numbers for each.

1-dimensional Perlin Noise Pseudo code
function Noise1(integer x)
x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end function

function SmoothedNoise_1(float x)
return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4
end function

function InterpolatedNoise_1(float x)

integer_X = int(x)
fractional_X = x - integer_X

v1 = SmoothedNoise1(integer_X)
v2 = SmoothedNoise1(integer_X + 1)

return Interpolate(v1 , v2 , fractional_X)

end function

function PerlinNoise_1D(float x)

total = 0
p = persistence
n = Number_Of_Octaves - 1

loop i from 0 to n

frequency = 2i
amplitude = pi

total = total + InterpolatedNoisei(x * frequency) * amplitude

end of i loop

return total

end function
Now it's easy to apply the same code to create a 2 or more dimensional Perlin Noise function:

2-dimensional Perlin Noise Pseudocode
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

柏林噪声进阶-advanced perlin noise

柏林噪声进阶 翻译:则卷大明 原文链接:http://iquilezles.org/www/articles/morenoise/morenoise.htm 原作者 i.q. 译者注:阅读此文...
  • zhangming19901120
  • zhangming19901120
  • 2017-07-13 20:18:49
  • 158


柏林噪声是一个非常强大算法,经常用于程序生成随机内容,在游戏和其他像电影等多媒体领域广泛应用。算法发明者Ken Perlin也因此算法获得奥斯卡科技成果奖(靠算法拿奥斯卡也是没谁了666)。本文将剖析...
  • gongxiaojiu
  • gongxiaojiu
  • 2017-07-21 18:25:31
  • 243

[图形学] 柏林噪声 (perlin noise)

参考论文:《An Image Synthesizer》 Ken Perlin         如果你是游戏玩家,你也许曾在游戏风景中驻足,并仔细观察草木和岩石的贴图,并感叹于它那看似杂乱而又...
  • ZJU_fish1996
  • ZJU_fish1996
  • 2017-05-03 18:54:13
  • 3658


这篇文章用于记录柏林噪声的一些实践,在开始前,先看下维斯百科里对柏林噪声的一些说明.   用随机法产生的噪声图像和显然自然界物体的随机噪声有很大差别,不够真实。1985年Ken Perlin指出[1...
  • pizi0475
  • pizi0475
  • 2015-09-28 16:46:37
  • 1303


利用柏林噪音生成随机地图 什么是柏林噪音?(请自行百度)Perlin噪声 ( Perlin noise )指由Ken Perlin发明的自然噪声生成算法 。 原理学习可以参考:http://p...
  • MaximilianLiu
  • MaximilianLiu
  • 2018-02-02 16:17:59
  • 150


主要是利用Unity的 Mathf.PerlinNoise   函数(柏林噪声)的不同寻常的功能。https://docs.unity3d.com/ScriptReference/Mathf.Perl...
  • u010019717
  • u010019717
  • 2017-05-24 09:31:41
  • 3646

Unity3D 5 官方教程:地形引擎

Unity3D 官方教程翻译 地形引擎
  • u010930289
  • u010930289
  • 2016-02-27 21:34:38
  • 7977

[算法]柏林噪声 Perlin Noise

  • Mahabharata_
  • Mahabharata_
  • 2017-01-26 12:31:23
  • 9086


柏林噪声  如果要构建复杂的表面,经常需要在纹理中加入一些可控的随机变化。比如不同的木板纹路,大理石纹路以及水面等等。   这个时候就需要引入可控的随机特征——噪声。总的来说,图形学中的噪声表示为 ...
  • qq_33274326
  • qq_33274326
  • 2017-03-29 17:34:51
  • 1248

3D数学之柏林噪声(Perlin Noise)

经过四天的努力,终于自己实现了3D柏林噪声,当第一次用它成功渲染出茶壶的时候,感觉自己跟《当幸福来敲门》的男主角chris一样,当时不由自主为自己鼓起了掌. 4天时间啊,这4天时间基本上没有背单词,白...
  • seamanj
  • seamanj
  • 2013-09-07 02:19:03
  • 8602
您举报文章:柏林噪声 perlin noise