This explanation is currently available in Japanese.
ひとことで
整数格子の各点にランダムな向きの勾配ベクトルを置き、その間を滑らかに補間して作る「連続した乱数」です。Ken Perlin が映画『トロン』(1982)の質感づくりのために考案し、後にアカデミー科学技術賞を受賞しました。値が急に飛ばないので、地形・雲・炎・揺れなど「自然な不規則さ」の土台として今もあらゆるゲームエンジンで使われています。
ゲームでの使いどころ
- 地形の高さ:座標を入れると高さが返る関数なので、プレイヤーが進んだ先の地形をその場で生成できます。Minecraft のような無限に続くワールド生成の基本部品です。
- カメラや武器の揺れ:時間を入力にした 1 次元のパーリンノイズは、ランダムなのに滑らかな手ぶれになります。
- テクスチャの変化:岩肌の色ムラ、雲の濃淡、水面のゆらぎ、草の揺れの位相など。
- AI の気まぐれ:巡回する敵の速度や向きに少しだけ混ぜると、機械的な動きが和らぎます。
しくみ
2 次元の場合、点 を含む格子セルの 4 隅それぞれについて次を計算します。
- 隅 に割り当てた単位ベクトル (格子座標のハッシュから決める)
- 隅から点へのベクトル との内積
この 4 つの値を、セル内の位置 に応じて補間します。
補間の重み は、両端で 1 階微分も 2 階微分も 0 になる 5 次式です(改良版パーリンノイズ、2002)。これによりセルの境目でも傾きや曲率が途切れず、ライティングしたときに格子の模様が浮かびません。
大事な性質は、格子点では値が必ず 0 になることです。点が格子点に一致すると なので内積も 0 です。山や谷は格子点のあいだに生まれ、その向きは勾配ベクトルが決めます。デモの矢印がちょうど「上り坂の向き」を指していることを確認してください。
実装のポイント
- ハッシュは決定的に:同じ座標なら何度呼んでも同じ値が返る必要があります。オリジナル実装は 256 要素の順列表を使い、シェーダーでは数式ハッシュを使うのが一般的です。
- 周波数と振幅:
noise(x * frequency) * amplitudeで起伏の細かさと高さを決めます。1 層だけだと単調なので、実用では fBm として何層も重ねます。 - 出力範囲:2D では理論上 付近が上限です。0〜1 に使うなら
n * 0.5 + 0.5のあとclampしておきます。
つまずきやすい点
- 格子に沿った癖:軸方向の勾配が多いと、模様が縦横に揃って見えることがあります。勾配の方向を増やすか、シンプレックスノイズを検討します。
- 格子点で平坦になる:格子点で必ず 0 なので、1 層だけだと「0 の高さに規則的に戻る」印象が出ることがあります。入力座標に回転やオフセットを加えて層を重ねると目立たなくなります。
- 浮動小数点の精度:座標が大きくなると(数万単位など)シェーダーの
float精度が足りずブロック状に崩れます。ワールドをチャンク単位でずらして小さな座標で評価しましょう。
デモで試すこと
- 「高さの元になる値」をただの乱数に切り替えてください。頂点ごとの乱数には隣とのつながりがなく、地形として使えないことが分かります。
- 「格子点と勾配ベクトル」を表示したまま周波数を上げ下げすると、格子の間隔と山の大きさが連動します。
- 「地形を流す」をオンにすると、座標をずらしながら新しい地形を生成し続けます。どこまで進んでも継ぎ目がないのが、関数として定義されたノイズの強みです。