Skip to content

F)Perlinノイズ

この文書では、Perlinノイズの生成方法について述べるとともに、Perlinノイズのフラクタル合成について述べる。 Perlinノイズをフラクタル合成することにより、さらに自然なノイズを発生させることができる。

  • N次元空間のセルの間で滑らかに補間されるノイズを生成する手法
  • 滑らかさの観点では一般に5次のスプライン関数fade(t)=6t515t4+10t3fade(t)=6t^5-15t^4+10t^3を用いる
    • 改良版では、異なる補間方法を用いる場合もある
  • セルをつなぐグリッド点では、傾きを生成するためにハッシュ関数hi=h(i)h_i=h(i)を用いる
    • hi=h(i)h_i=h(i)はパフォーマンスとランダム性の特性に依拠しユーザが個別に定義する必要がある
  • グリッド点の傾きをハッシュ値を用いて生成する。これをgi=grad(hi)g_i=grad(h_i)と定義する
    • gi=grad(hi)g_i=grad(h_i)はノイズの性質を左右するためユーザが目的の応じて定義する必要がある

以下の5ステップでノイズ関数が作成できる。

  1. N次元の領域を想定し、そこに属する任意の点xxのノイズを求めることを目標とする
  2. 領域を整数倍のN次元のグリッドに区切る
  3. 任意の点はその点を囲うN次元のグリッド点によって囲まれている
  4. 各グリッド点でランダムな値をユーザが定義したN次元のハッシュ関数で割り当てる
  5. グリッド点に設定されたベクトル値に応じて点の値は影響を受けると想定し、lerpするのだが、直接の値でlerpせずにfade関数を用いて中間点を補正しlerpするのがポイントである。イメージとしては、各次元ごとに任意の点xxの小数部を用いて次元をひとつづつ落としながら集約して計算する。
    • 2次元の例

      • 各グリッド点での勾配ベクトルの内積をdot00,dot01,dot10,dot11dot_{00}, dot_{01}, dot_{10}, dot_{11}とする。
      • x方向に補間すると、4つのグリッド点から2つの中間値が得られる
      x1=lerp(dot00,dot10,fade(trunc(x)))x2=lerp(dot01,dot11,fade(trunc(x))) x_1 =lerp(dot_{00},dot_{10},fade( trunc(x) ))\\ x_2 =lerp(dot_{01},dot_{11},fade( trunc(x) ))\\

      なお、lerp(a,b,t)はa,bの線形補間であり、 trunc(x)はx の小数部分を切り捨て、最も近い小さい整数を返す関数である

{lerp(a,b,t)=(1t)a+tbtrunc(x)=x=max{nZnx} \left\{ \, \begin{aligned} & lerp(a,b,t) &=& (1-t) \cdot a+t \cdot b\\ & \text{trunc}(x)& =& \lfloor x \rfloor\\ & &=& \max \{ n \in \mathbb{Z} \mid n \leq x \} \end{aligned} \right.

この2 つのx 方向の補間点はy 方向に異なる位置にあるため、 最後に y 方向で補間することで目的の関数が得られる。すなわち

P(x)=lerp(x1,x2,fade(trunc(y))) P(x)=lerp(x_1,x_2,fade( trunc(y) ))

y方向で補間してから最後にx方向で補間しても同じ結果が得られる(そうである)。

グリッド点のハッシュ値h=h(i)h=h(i)の値を使って勾配を求める

  • 符号のみ。単純さを優先
grad(h)=(1)(hmod2) grad(h)=(-1)^{(h \mod 2)}
  • 符号とスケール
grad(h)=(1)(hmod2)((hmod8)+1) grad(h)=(-1)^{(h \mod 2)} \cdot ( (h \mod 8) +1)
  • 符号と別のスケール、ランダム性が増し細かい調整が可能。勾配の大きさを0.25,0.5,0.75,1.0 にスケール
grad(h)=(1)(hmod2)(hmod4)+14 grad(h)=(-1)^{(h \mod 2)} \cdot \frac{ (h \mod 4) +1}{4}
  • 三角関数。なめらかで連続的な変動(例: 波状のパターン)
grad(h)=sin(hπ8) grad(h)=sin(h \cdot \frac{\pi}{8} )
  • 三角関数の組み合わせ、より複雑で連続的
grad(h)=cos(hπ4)+sin(hπ8) grad(h)=cos(h \cdot \frac{\pi}{4} ) + sin( h \cdot \frac{\pi}{8})
  • 三角関数で位相を持つ。なめらかでランダム。
grad(h)=cos(hπ8)(1)(hmod2) grad(h)=cos(h \cdot \frac{\pi}{8} ) \cdot (-1)^{(h \mod 2)}
  • フラクタル性、小さいhで細かい変動、大きいhで緩やかな高スケールの変動
grad(h)=sin(h)h+1 grad(h)=\frac{sin(h)}{h+1}
  • 他のフラクタル性のある例、指数的減衰
grad(h)=sin(h)eh grad(h)=sin(h) \cdot e^{-h}
  • 他のフラクタル性のある例、フラクタルブラウン運動を模倣
grad(h)=sin(h)h+1 grad(h)=\frac{sin(h)}{\sqrt{h+1}}
  • 他のフラクタル性のある例、異なる成分
grad(h)=sin(h)+sin(2h)2+sin(4h)4 grad(h)=sin(h)+\frac{sin(2h)}{2}+\frac{sin(4h)}{4}
  • 他のPerlinノイズを使う
grad(h)=PerlinNoise(h)1h+1 grad(h)=PerlinNoise(h) \cdot \frac{1}{h+1}
  • ロジスティック曲線を使う
grad(h)=sin(h)1+eh grad(h)=\frac{sin(h)}{1+e^h}
  • ハッシュ値を直接スケールとして使用
grad(h)=(hmod16)16 grad(h)=\frac{(h \mod 16)}{16}
  • シンプルで高速なハッシュ関数
hash(i)=(i57+13)mod256 hash(i) = (i\cdot57+13) \mod 256
  • xorでランダム性を強める,再現性を保つ
hash(i)=((i12345)57+13)mod256 hash(i) = ((i \oplus 12345) \cdot 57 + 13 ) \mod 256
  • 計算が高速
hash(i)=((i31)3)mod256 hash(i) = ((i \cdot 31) \gg 3 ) \mod 256
  • 三角関数
    • fracは小数部分を取得する関数
hash(i)=floor(256frac(sin(i)12345)) hash(i) = floor(256 \cdot frac(sin(i) \cdot 12345 ))
  • 乱数テーブルを事前に作る
hash(i)=perm[imodN] hash(i) = perm[i \mod N]
  • ポリノミアル関数
hash(i)=(i3+31i+7)mod256 hash(i) = (i^3+31i+7) \mod 256

重要)Perlinノイズとそのフラクタル合成

Section titled “重要)Perlinノイズとそのフラクタル合成”

フラクタル合成(fBM: Fractional Brownian Motion)を利用した Perlin Noise の原理について説明する

フラクタル合成された Perlin Noise は次のように定義される:

h(x,y)=i=0n12iP(ωix,ωiy)h(x,y) = \sum_{i=0}^{n} \frac{1}{2^i} P(\omega^i x, \omega^i y)

ここで:

  • P(x,y)P(x,y) は 2D Perlin Noise
  • nn はオクターブ数(加算するノイズの層の数)
  • ω\omega は周波数スケールファクター
  • ii はオクターブのインデックス

この項は 振幅の減衰(Amplitude Scaling) を目的とする。フラクタル合成では、異なるスケールのノイズを重ねるが、高周波成分を過度に強調しないために各オクターブの振幅を 12i\frac{1}{2^i} で抑える。これにより、よりスムーズなノイズが生成される。

ii はオクターブ番号(Octave Index)を表す。具体的には、i=0i=0 から始まり、ii が増えるごとに高周波成分のノイズを追加する。

例えば:

  • i=0i=0 は基本の低周波ノイズ
  • i=1i=1ω\omega 倍の周波数を持つノイズを追加
  • i=2i=2ω2\omega^2 倍の周波数を持つノイズを追加
  • これを nn 回繰り返す

このようにして、異なるスケールのノイズを重ね、リアルなパターンを作り出す。

nn は オクターブ数(Octave Count) であり、何回ノイズを合成するかを決めるパラメータ。nn が大きいほど、より細かいディテールが追加され、リアルな質感になるが、計算コストも増える。

例えば:

  • n=1n=1 なら基本的なノイズのみ
  • n=4n=4 なら 4 回異なるスケールのノイズを重ねる
  • n=8n=8 ならより高精細なノイズになる

パーリンノイズの基本処理との違い

Section titled “パーリンノイズの基本処理との違い”

通常の Perlin Noise は、以下のように生成される:

  1. グリッド点にランダムな勾配ベクトルを設定
  2. 補間関数(エルミート補間や 5 次補間)でスムーズに補間
  3. 1 つのノイズマップを生成

しかし、上記のフラクタル合成の式では 異なるスケールのノイズを合成することで、より自然でリアルなノイズパターンを得ることができる。

フラクショナル・ブラウン運動

Section titled “フラクショナル・ブラウン運動”

フラクショナル・ブラウン運動(fBM)は、通常のブラウン運動を一般化した確率過程であり、自己相似性と長距離依存性を持つ特徴的なランダム過程である。

fBMは、HH をハースト指数(Hurst exponent)とすると、次の性質を持つ確率過程 BH(t)B_H(t) として定義される。

BH(t)=1Γ(H+1/2)((ts)+H1/2(s)+H1/2)dB(s)B_H(t) = \frac{1}{\Gamma(H+1/2)} \int_{-\infty}^{\infty} \left( (t-s)_+^{H-1/2} - (-s)_+^{H-1/2} \right) dB(s)

ここで:

  • H(0,1)H \in (0,1) はハースト指数であり、自己相関の強さを決定する。
  • B(s)B(s) は通常のブラウン運動(Wiener過程)。
  • (x)+(x)_+x>0x > 0 の場合に xx、それ以外は 00 を取る関数。

ハースト指数 HH によって fBM の特性は大きく変化する。

  • H=1/2H = 1/2 のとき、通常のブラウン運動となる(無相関)。
  • H>1/2H > 1/2 のとき、正の相関を持ち、過去の増加・減少が維持されやすい(持続性)。
  • H<1/2H < 1/2 のとき、負の相関を持ち、増加・減少が反転しやすい(反持続性)。

特に、HH が大きいほど長期記憶効果が強くなる。

fBM のパワースペクトル密度(PSD)は周波数 ff に対して次のようにスケールする。

S(f)f(2H+1)S(f) \propto f^{-(2H+1)}

これは、HH が大きいほど低周波成分が強調されることを意味する。

離散時間で fBM を生成する方法の一つに リーマン・リウヴィル積分 を用いる方法がある。

XH(n)=k=0nckWkX_H(n) = \sum_{k=0}^{n} c_k W_k

ここで:

  • WkW_k は独立なガウス変数(ホワイトノイズ)。
  • ckc_k はハースト指数に依存する係数であり、以下のように与えられる。
ck=(k+1)HkHΓ(H+1/2)c_k = \frac{(k+1)^{H} - k^H}{\Gamma(H+1/2)}

この方法により、自己相似性を持つフラクタル時系列を構築できる。

fBM は多くの自然現象やシミュレーションに応用される。

  • 地形生成: 地形や雲のノイズ生成(例: Perlinノイズの拡張)。
  • 金融モデリング: 資産価格の変動における長期依存性のモデリング。
  • ネットワークトラフィック: 通信ネットワークのトラフィックの自己相関の表現。
  • 医療データ: 心拍や神経信号などの時系列データ解析。
  • fBM は通常のブラウン運動の一般化であり、自己相似性と長期依存性を持つ確率過程 である。
  • ハースト指数 HH によって自己相関の性質が変わる。
  • 周波数特性は S(f)f(2H+1)S(f) \propto f^{-(2H+1)} に従い、HH が大きいほど低周波が強調される。
  • 離散的な fBM の生成にはリーマン・リウヴィル積分を用いる方法がある。
  • 地形生成、金融モデリング、ネットワーク解析など広範な分野で応用されている。