Perlinノイズ(Perlin Noise)

原文(Original text):http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

翻訳者(Translator):Kei, technotype@gmail.com

この文書は上記の 原文 を日本語に訳したものです。 翻訳者は翻訳内容の正確性を保証しません。 また、利用に起因する被害、損失に対し一切の責任を負いません。


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.

自然界にあるものを注意深く観察すると、それらがフラクタルであることに気づくでしょう。 そういったものはよりミクロなレベルで見ることができます。 一般的な例を上げるなら山脈の輪郭などがそうです。 山の高さは大きな変化(山)、中位の変化(丘)、小さな変化(巨石)、とても小さな変化(石)を含んでいます。 フィールド上の草、海の波、蟻の動き、木の枝の動き、大理石のパターン、風の動きなどいろいろなものを観察してみてください。 これらの現象は大きい変化と小さい変化が同じパターンで含まれています。 Perlinノイズ関数は異なる範囲を取るノイズ関数を加算していくことでパターンを再現します。

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

Perlinノイズ関数を作成するにはノイズ関数と補完関数の2つが必要です。

ノイズ関数入門(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.

ノイズ関数は乱数ジェネレータです。 パラメタとして整数を取り、そのパラメタに基づいた乱数を返します。 同じパラメタを2度渡すと同じ数を2度返します。 このように動作することは大変重要です。 もし、同じ数を返さないのであればPerlin関数は意味のないものになります。

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

例となるノイズ関数をグラフで示します。 0から1までの乱数をx軸上の全てのポイントに割り当てます。


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.

値間を滑らかに補間することによって、パラメタとして非整数を取る連続関数(continuous function)を定義することができます。 この記事の後のほうでは値の補完法を話題にしています。


定義(Definitions)

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.

先に進む前に、振幅(amplitude)周波数(frequency)が何を意味しているのか説明します。 物理を習っていたなら、サイン波における振幅(amplitude)や周波数(frequency)の概念に触れたことがあるでしょう。

サイン波(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)とは山から山、または谷から谷の距離のことです。 振幅(amplitude)は波の高さのことです。 周波数(frequency)は 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.

この例のノイズ関数のグラフでは、赤いスポットは関数の次元に沿って定義される任意の値を示します。 この場合、振幅は関数が取ることのできる最小値と最大値の差です。 波長は特定のスポットから次のスポットまでの距離です。 また、周波数は 1/wavelength として定義されています。


Perlinノイズ関数を作成する(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.

高品質なノイズ関数を作成するために多様な周波数や振幅で平滑化し、それらを全て加算します。 これがPerlinノイズ関数です。

以下のような値をとるノイズ関数を実行する(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.

この関数の実行結果は大きな変化、中位の変化、小さな変化を含むため、 山脈のように見えます。 実際、コンピュータによって生成された景観の多くはこの方法を使用しています。 もちろん、このような場合は2Dノイズを使用します。

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

もちろん、2次元でも同様です。

2次元で生成したノイズ関数(Some noise functions are created in 2D)

Adding all these functions together produces a noisy pattern.

これら全ての関数を合計してノイズパターンを生成します。

パーシステンス(Persistence)

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.

ノイズ関数を加算するとき、それぞれの関数でどのような振幅と周波数を使うべきか悩むかもしれません。 上記の1次元の例ではノイズ関数を加算するたびに、周波数を2倍にし、振幅を半分にしています。 この設定は非常によく見かけます。 事実、ありふれたものであり、ほとんどの人は他の設定を使うことすら考えていないでしょう。 しかしながら、各ステップで周波数と振幅に異なる値を使うことで異なる特徴を持つPerlinノイズ関数を作成できます。 例えば、なだらかに隆起する丘を作成するには低い周波数用と大きな振幅(large amplitudes)、 高い周波数と小さな振幅を組み合わせます。 また、岩石の多い平たんな土地を作成するには低い周波数と低い振幅を選択します。

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:

AmplitudeとFrequencyの繰り返しを避けてより扱いやすくするために、 各周波数の振幅を指定するのに1つの数値が使われます。 この値はパーシステンス(Persistence)として知られています。 この用語はフラクタル発見の後、マンデルブローによって作られました。 彼は、多くの高周波は低いPersistenceを持つと定義しました。 私の友人のマット(Matt)もPersistenceの概念を提案しました。 それはマンデルブローが定義しましたものと正反対です。 正直、私はマットの定義のほうが好みです。 ごめんよマンデルブロー。 私たちが定義した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回目ということです。 Perlinノイズの出力結果とPersistenceの影響を示す下記の図を見てください。 図にはノイズ関数で使用しているコンポーネントの値を表示しています。

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)

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.

あなたが加えた連続した各ノイズ関数はオクターブ(octave)として知られています。 その理由は各ノイズ関数が1つ前のノイズ関数の2倍の周波数を持つからです。 音楽においてもオクターブはこのような性質を持ちます。

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.

何回オクターブを加算するかはあなた次第です。 あなたが欲しいだけ、またはそれ以上加えることができます。 ですが、いくつか助言させてください。 Perlinノイズ関数を使用してスクリーン上にイメージを描画する場合、 オクターブの周波数があまりに高く表示できない可能性があります。 また、単にスクリーンに高周波数ノイズの細部まで再現するだけの十分なピクセルがないだけかもしれません。 Perlinノイズの一部の実装ではスクリーンの端(または他の媒体)に達するまでノイズ関数を自動的に加算します。

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).

振幅が再現するにはあまりに小さくなるとき、ノイズ関数を加えるのをやめるのも賢い選択です。 そういった現象の有無はPersistenceのレベルやPerlin関数全体にわたる振幅、スクリーンの解像度に依存します。

ノイズ関数の作成(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.

私たちはノイズ関数に何を求めているのでしょうか。 ノイズ関数は一般的には乱数ジェネレータを指します。 しかし、呼び出すといつも異なる乱数を返す乱数ジェネレータとは異なり、 これらのノイズ関数は1つ以上のパラメタから計算された乱数を返します。 つまり、ノイズ関数に同じ値を渡すと同じ値を返し、 異なる値を渡すと異なる値を返します。

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 and 1.0.

私は乱数ジェネレータについてあまり詳しくないため、 いくつか探してみました。 そして、私が見つけたものの1つがここにあります。 なかな使えるようです。 これは、-1.0から1.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

異なる乱数ジェネレータを求めているなら、 私は上記のコードをコピーし、数値だけ別のものに変えることを推奨します。 桁数の大きな数は全て素数です。 同程度のサイズの異なる素数に置き換えることができます。 乱数を探し出すのを容易にするため、素数をリストするプログラムを書きました。 プログラムは開始数と終了数を指定することで、2つの数値間の全ての素数を見つけ出します。 ソースコードも添付しているのでプログラムに組み込むこともできます。 Primes.zip

補間(Interpolation)

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 and 1. 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 and 1, it returns some value between a and b.

作成したノイズ関数が返す値を補間により、滑らかに(smooth)する必要があります。 好きな方法を選んでかまいませんが、いくつか他の補間方法より、よさそうなものがあります。 一般的な補間関数は3つの引数を取ります。 a, と b、そしてその間を補間するための0から1の値を取る x です。 補間関数は値 x に基づく a から b の間の値を返します。 x が0と等しいとき a を返し、 x が1と等しいとき b を返します。 x が0と1の間なら ab の間の値を返します。

線形補間(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.

ランドスケープ(landscape)を生成する際に使用する安っぽいプラズマのようにひどいものです。 しかし、単純なアルゴリズムなので初めてPerlinノイズに挑戦しているなら許容できます。

  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
3次元補間(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. These are:

この方法は非常に滑らかな結果を返します。 しかし、速度でその分の対価を払うことになります。 正直に言うと、この方法がコサイン補間より良い結果を返すかは分かりません。 しかし、いずれにしろこの方法を望むのならここに置いておくので使用してください。 この方法は少し難しくなるので注意してください。 以前、補間関数は3つの引数を取るといいました。 しかし、3次元補間は5つの引数を取ります。 この方法では x は以前のまま、 ab の代わりに v0, v1, v2, v3 を使用します。 これらは以下の通りです。

  • 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.

補間とは別に平滑化を行うことで、ノイズ関数の出力が乱数に見えないようにします。 2Dや3Dバージョンでも同様に平滑化し、正方形に見えないようにします。 画像平滑化フィルタや炎アルゴリズム(fire algorithm)を書いたことがあるなら既にプロセスに詳しいはずです。

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.

単純に1つの座標のノイズ関数の値を取るより、近傍座標を合わせた平均値を取るほうがいいでしょう。 この意味が分からないのなら、以下のコードに目を通してください。

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次元ノイズには平滑化する点はほとんどありません。 平滑化はノイズの正方形を減らす効果があり、2次元、3次元で効果を発揮します。 ただし、コントラストが低下します。 滑らかにすればするほどノイズは水平に近づきます。


1次元平滑化ノイズ(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次元平滑化ノイズ(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.

全てのプロセスを知った今、学んだ全てを一まとめにし、Perlinノイズ関数を作成します。 この関数では、InterpolatedNoise(補間したノイズ)関数の戻り値をたし合わせます。 この関数には1つ以上のパラメタを渡すことができます。 関数はそのパラメタの影響を受けます。 単純な1次元Perlinノイズ関数を以下に示します。

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.

Perlinノイズ関数のメインはループです。 ループによる繰り返しでは周波数(frequency)を2倍にしたオクターブを加えます。 各繰り返しはNoiseiによって示される異なる(different)ノイズ関数を呼び出します。 別に複数ノイズ関数を記述する必要はありません。 擬似コードが示すように各オクターブのための関数を1つ用意するだけです。 全てのノイズ関数は3つの素数を除いて基本的に同じ仕様です。 そのため同じコードを流用し、それぞれ異なる素数セットを使用することもできます。

1次元Perlinノイズの擬似コード(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次元以上のPerlinノイズに適用できます。

2次元Perlinノイズの擬似コード(2-dimensional Perlin Noise Pseudo 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


Perlinノイズを使ったアプリケーション(Applications of Perlin Noise)

Now that you have this fantastic function, what can you do with it? Well, as the cliche goes, you're limited only by your imagination. Perlin Noise has so many applications that I can't think of them all, but I'll have a go.

このようなファンタスティックな機能を手に入れた今、あなたはどんなことに使いますか。 さて、ことわざにもあるように、後はあなたの想像力次第です。 Perlinノイズは思いもよらないさまざまなアプリケーションで実装されています。 さて、私も挑戦してみようと思います。

1 dimensional

Controlling virtual beings:
Living objects rarely stay still for very long (except students). Use perlin noise to constantly adjust the joint positions of a virtual human player, in a game for example, to make it look like it's more alive.
Drawing sketched lines:
Computer drawn lines are always totally straight, which can make them look unnatural and unfriendly. You can use Perlin Noise to introduce a wobblyness to a line drawing algorithm to make it appear as if it's been drawn by hand. You can also draw wobbly circles and boxes. Some research has been done on making a Sketchy User Interface.
See: Creating Informal Looking Interfaces.


2 dimensional

Landscapes:
These are a perfect application for 2D Perlin Noise. Unlike the subdivision method, you do not have to store the landscape anywhere in memory, the height of any point on the landscape can be calculated easily. What's more, the land stretches indefinitely (almost), and can be calculated to minute detail, so it's perfect of variable level of detail rendering. The properties of the landscape can be defined easily too.
Clouds:
Again, cloud rendering is well suited to Perlin Noise.
Generating Textures:
All sorts of textures can be generated using Perlin Noise. See the table below for some examples. The textures generated can go on for ages before repeating (if ever), which makes them much more pleasant to look at than a repeating tiled texture map.


3 dimensional

3D Clouds:
You can, of course, produce volumetric clouds. You'll probably have to use some sort of ray tracing to visualise them.
Animated Clouds:
You can produce animated 2 dimensional clouds with 3D Perlin Noise, if you consider one dimension to be time.
Solid Textures:
Some rendering / raytracing programs, like POVray, apply texture to objects by literally carving them from a 3-dimensional texture. This was, the textures do not suffer from the warping usually associated with mapping 2D textures onto (non-flat) 3D objects.


4 dimensional

Animated 3D Textures and Clouds:
Moving into higher dimensions, you can easily produce animated clouds and solid textures. Just consider the extra dimension to be time.



Copyright Matt Fairclough 1998
The land, clouds and water in this picture were all mathematically generated with Perlin Noise, and rendered with Terragen.
The clouds in this demo are animated with 3D perlin Noise. The algorithm had to be modified slightly to be able to produce Perlin Noise in real time. See the Clouds Article for more info on how this was done.


Generating Textures with Perlin Noise
Perlin is fantastic for generating textures. You can produce textures that are (for all practical purposes) infinitely large, but take up almost no memory. You can create marble, wood, swirly patterns, probably anything if you try hard. You can also define a 3D texture. You can think of this as a solid block of material, from which you can 'carve' an object. This allows you to produce textures which can be applied to any shaped object without distortion. It can take a lot of imagination, thought and experimentation to get a texture to look really good, but the results can be very impressive indeed.

Play around as much as you like. Use several Perlin functions to create a texture, try different persistences and different frequencies in different dimensions. You can use one Perlin function to affect the properties of another. Apply functions to their output. Do whatever you want, there's almost certainally a way to produce almost any texture you can dream up.

The following textures were made with 3D Perlin Noise

Standard 3 dimensional perlin noise. 4 octaves, persistence 0.25 and 0.5
Low persistence. You can create harder edges to the perlin noise by applying a function to the output.
To create more interesting and complicated textures, you should try mixing several Perlin functions. This texture was created in two parts. Firstly a Perlin function with low persistence was used to define the shape of the blobs. The value of this function was used to select from two other functions, one of which defined the stripes, the other defined the blotchy pattern. A high value chose more of the former, a low value more of the latter. The stripes were defined by multiplying the first Perlin Function by some number (about 20) then taking the cosine.
A marbly texture can be made by using a Perlin function as an offset to a cosine function.


    texture = cosine( x + perlin(x,y,z) )

Very nice wood textures can be defined. The grain is defined with a low persistence function like this:

    g = perlin(x,y,z) * 20
    grain = g - int(g)
The very fine bumps you can see on the wood are high frequency noise that has been stretched in one dimension.

    bumps = perlin(x*50, y*50, z*20)
    if bumps < .5 then bumps = 0  else bumps = 1t


References

Procedural textures: http://developer.intel.com/drg/mmx/appnotes/proctex.htm

Intel Developer Site article about using the new MMX technology to render Perlin Noise in real time.

Ken Perlin's Homepage: http://mrl.nyu.edu/perlin/

I assume the person responsable for Perlin Noise. He has an interesting page with lots of useful links to texturing and modeling stuff.

Texturing And Modeling A Procedural Approach: http://www.cs.umbc.edu/~ebert/book/book.html

Ken Perlin's book which goes in depth on using Perlin Noise, among other algorithms to generate textures and model various natural phenomena.

Procedural Texture Page: http://www.threedgraphics.com/pixelloom/tex_synth.html

This page is an attempt to collect any and all information and WWW links related to Procedural Texture Synthesis.


Return to the Good Looking Textured Light Sourced Bouncy Fun Smart and Stretchy Page.