パーリンノイズ


title: "パーリンノイズ" description: "勾配ベクトルを使ったパーリンノイズを学びます。バリューノイズとの違いを理解し、より自然なノイズを生成します。" chapter: "07-noise" order: 3 challenge: description: "パーリンノイズを使って波を作りましょう。uv.yにノイズ値を加算して、波打つ横縞パターンを作ってください。sin関数とノイズを組み合わせると効果的です。" hints:

  • "まずは横縞のベースを作ります: float stripe = sin(uv.y * 20.0);"
  • "ノイズでuv.xを歪ませます: float n = perlinNoise(uv * 3.0) * 0.5;"
  • "完成形: float stripe = sin((uv.y + perlinNoise(uv * 3.0) * 0.3) * 20.0); vec3 color = vec3(stripe * 0.5 + 0.5); とすると、ノイズで波打つ縞模様が作れます。"

パーリンノイズ

パーリンノイズとは

パーリンノイズは、1983年にKen Perlinが映画「トロン」の制作のために開発したノイズ関数です。この功績により、Perlinはアカデミー賞(技術部門)を受賞しました。

バリューノイズが格子点にランダムな値を置くのに対し、パーリンノイズは格子点にランダムな勾配(方向)ベクトルを置きます。

バリューノイズとの違い

| 特徴 | バリューノイズ | パーリンノイズ | |------|--------------|--------------| | 格子点に置くもの | スカラー値 | 勾配ベクトル | | 見た目 | ブロック状のアーティファクト | より自然で滑らか | | 計算コスト | 低い | やや高い | | 格子の目立ちやすさ | やや目立つ | 目立ちにくい |

勾配ベクトルの概念

各格子点にランダムな2Dベクトル(方向)を割り当てます。そして、格子点からピクセルへの変位ベクトルとの内積をとります。

  ↗(勾配)     ↖(勾配)
  ●-----------●
  |           |
  |     ×(ピクセル)  |
  |           |
  ●-----------●
  ↘(勾配)     →(勾配)

内積は「2つのベクトルがどれだけ同じ方向を向いているか」を表すので、ピクセルが勾配方向に近いほど大きな値、逆方向だと小さな値になります。

実装

vec2 randomGradient(vec2 p) {
    float angle = random(p) * 6.2831853;
    return vec2(cos(angle), sin(angle));
}

float perlinNoise(vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);

    // 四隅の勾配ベクトルと内積
    float a = dot(randomGradient(i), f);
    float b = dot(randomGradient(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0));
    float c = dot(randomGradient(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0));
    float d = dot(randomGradient(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0));

    // 滑らかな補間
    vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);

    return mix(
        mix(a, b, u.x),
        mix(c, d, u.x),
        u.y
    );
}

ポイントは:

  • randomGradient — 格子点ごとにランダムな方向ベクトルを生成
  • f - vec2(...) — 各格子点からピクセルへの変位ベクトル
  • dot(勾配, 変位) — 勾配方向への影響度
  • quintic補間 f * f * f * (f * (f * 6.0 - 15.0) + 10.0) — smoothstepよりさらに滑らか

quintic補間

パーリンノイズでは、smoothstep の代わりにquintic補間がよく使われます:

vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);

この5次多項式は、1次微分だけでなく2次微分も連続になります。ライティングなどでノイズの法線を使う場合に、より滑らかな結果が得られます。

パーリンノイズの特徴

  • 値の範囲は約 -0.7 〜 0.7(正規化されていない)
  • 表示するときは noise * 0.5 + 0.5 で 0〜1 にマッピング
  • バリューノイズよりも格子の構造が見えにくい
  • 自然現象のシミュレーションに広く使われる

まとめ

  • パーリンノイズは勾配ベクトルの内積で計算される
  • バリューノイズより自然で格子感が少ない
  • quintic補間でさらに滑らかな結果が得られる
  • 雲、地形、水面など自然物の表現に最適