Math World Lab

プロシージャル生成の数学(補間ノイズ)

ランダムな制御点を滑らかにつなぐ補間関数が、自然に見える地形・テクスチャを生み出す仕組み

この単元の発見をシェア
3行要約(Key Takeaways / AIOサマリー)
1
プロシージャル生成ノイズ(パーリンノイズなど)は、格子点にランダムな値を置き、それらの間を「補間関数」でつないで連続的な値を作る技術
2
単純な直線補間(線形補間)は折れ線状のカクカクした変化になるが、滑らか補間(スムーズステップ・コサイン補間)を使うと自然な丘や谷のような滑らかな曲線になる
3
この滑らかな補間曲線こそが、ゲームの地形・雲・木目テクスチャなど、自然物のランダムだが滑らかな見た目を生成する数学的な核心部分

なぜこれを学ぶのか? — 現実社会とテクノロジーでの価値

Purpose & Motivation

なぜ生まれたのか?

プロシージャル生成ノイズ(パーリンノイズなど)は、格子点にランダムな値を置き、それらの間を「補間関数」でつないで連続的な値を作る技術

身につく武器・思考力

単純な直線補間(線形補間)は折れ線状のカクカクした変化になるが、滑らか補間(スムーズステップ・コサイン補間)を使うと自然な丘や谷のような滑らかな曲線になる

実社会・ITでの活躍現場

  • •ゲーム地形生成における1次元補間ノイズの実装
  • •ITシステム・アルゴリズム実装における論理設計
  • •データ分析やシミュレーションにおける数理モデリング

Layer 1 — 直感・シミュレーター

「規則を変更」ボタンで格子点上のランダムな制御値を再生成し、スライダーで補間方式(線形補間 ↔ スムーズ補間)を切り替えてみよう。同じ制御点でも、補間関数を変えるだけで生成される曲線の印象がガラッと変わることが確認できる。

補間方式: 線形補間寄り0%
線形補間(カクカク)スムーズステップ(滑らか)
💡 補間関数の役割:

オレンジの点が格子点上のランダムな制御値、青い曲線がその間を補間した結果です。線形補間は lerp(vi,vi+1,t)=(1−t)vi+t vi+1\text{lerp}(v_i, v_{i+1}, t) = (1-t)v_i + t\,v_{i+1}で直線的につなぎますが、スムーズステップ補間は S(t)=3t2−2t3S(t) = 3t^2 - 2t^3 を介することで両端の傾きが0になり、滑らかにつながります。

↑ スライダーを右に動かすほど、カクカクした折れ線が滑らかな丘陵のような曲線に変わっていきます。これを2次元・3次元に拡張し、値の代わりに勾配ベクトルを使ったものが「パーリンノイズ」で、ゲームの地形やテクスチャ生成の基盤技術です。

直感チェック!ミニクイズ

制御点の間を単純な「線形補間(直線でつなぐ)」ではなく「スムーズステップ補間」でつなぐと、生成される曲線にはどのような変化が起きるか?

Layer 2 — 定義・受験・証明

定義

格子点 x=0,1,2,…x = 0, 1, 2, \ldots にそれぞれランダムな値 v0,v1,v2,…v_0, v_1, v_2, \ldots が割り当てられているとき、格子点の間の任意の位置 x=i+tx = i + t(ただし 0≤t≤10 \le t \le 1)における値を「補間関数」によって連続的に求める。

最も単純な「線形補間(Linear Interpolation, Lerp)」は次式で定義される。

lerp(vi,vi+1,t)=vi+t(vi+1−vi)=(1−t)vi+t vi+1\text{lerp}(v_i, v_{i+1}, t) = v_i + t(v_{i+1} - v_i) = (1-t)v_i + t\, v_{i+1}

より自然な曲線を得るための「スムーズステップ補間」は、tt をそのまま使う代わりに、次の緩和関数 S(t)S(t) を通してから線形補間の式に代入する。

S(t)=3t2−2t3,smooth(vi,vi+1,t)=(1−S(t))vi+S(t) vi+1S(t) = 3t^2 - 2t^3, \qquad \text{smooth}(v_i, v_{i+1}, t) = (1-S(t))v_i + S(t)\, v_{i+1}

公式・数理モデル

lerp(vi,vi+1,t)=(1−t)vi+t vi+1,S(t)=3t2−2t3\text{lerp}(v_i, v_{i+1}, t) = (1-t)v_i + t\, v_{i+1}, \qquad S(t) = 3t^2 - 2t^3

証明・導出

スムーズステップ関数 S(t)=3t2−2t3S(t) = 3t^2 - 2t^3 が「滑らかさ」を生む理由は、区間の両端での微分係数(傾き)にある。

S(t)S(t) を微分すると、

S′(t)=6t−6t2=6t(1−t)S'(t) = 6t - 6t^2 = 6t(1-t)

これより端点での傾きを調べると、

S′(0)=6⋅0⋅1=0,S′(1)=6⋅1⋅0=0S'(0) = 6 \cdot 0 \cdot 1 = 0, \qquad S'(1) = 6 \cdot 1 \cdot 0 = 0

すなわち t=0t=0 と t=1t=1 の両方で傾きがちょうど 00 になる。これは「補間曲線が格子点に速度ゼロで滑らかに接続される」ことを意味し、隣り合う区間の補間曲線をつなげても折れ点(傾きの不連続)が生じない。

一方、線形補間 lerp(vi,vi+1,t)=vi+t(vi+1−vi)\text{lerp}(v_i, v_{i+1}, t) = v_i + t(v_{i+1}-v_i) の傾きは区間内で常に一定値 (vi+1−vi)(v_{i+1}-v_i) であり、隣接区間との境界(格子点)で傾きが急変するため、曲線全体としては「角」を持つ折れ線になる。

さらに S(0)=0, S(1)=1S(0)=0,\ S(1)=1 が成り立つため、両端点では smooth(vi,vi+1,0)=vi\text{smooth}(v_i,v_{i+1},0)=v_i、smooth(vi,vi+1,1)=vi+1\text{smooth}(v_i,v_{i+1},1)=v_{i+1} となり、制御点そのものの値は線形補間と変わらず正確に通過する。つまりスムーズステップは「通過点は変えずに、つなぎ方(速度)だけを滑らかにする」補正関数である。

押さえておきたいポイント

  • 線形補間は計算が軽い反面、格子点で傾きが不連続になり「カクカクした」見た目になる
  • スムーズステップ(または五次関数によるさらに滑らかな版、コサイン補間)は両端で傾き0になり、自然な曲線を生む
  • 1次元のこの補間を2次元・3次元の格子に拡張し、各格子点に「値」ではなく「勾配ベクトル」を割り当てたものがKen Perlinの考案した「パーリンノイズ」であり、映画・ゲームの地形やテクスチャ生成の標準技術
  • 補間関数の選択はコンピュータグラフィックスにおける「見た目の自然さ」と「計算コスト」のトレードオフを体現する典型例である
参照基準・学習指導要領との対応

本トピックの内容・数理モデルは、文部科学省学習指導要領(算数・数学・情報)および国際標準カリキュラムに準拠し、エンジニアリング現場の実装事例と照らし合わせてMath World Lab編集部により検証・作成されています。

Layer 3 — 工学応用・現場実装

ゲーム地形生成における1次元補間ノイズの実装

少数のランダムな制御点から、線形補間またはスムーズステップ補間によって連続的な地形の高さ関数を生成する。実際の3Dゲームエンジン(Unity, Unreal Engine等)の地形生成やクラウドシェーダーでは、この考え方を2次元・3次元・多オクターブ(複数周波数の重ね合わせ)に拡張したパーリンノイズ/シンプレックスノイズが使われている。

1// スムーズステップの緩和関数: S(t) = 3t^2 - 2t^3
2function smoothstep(t: number): number {
3 return 3 * t * t - 2 * t * t * t;
4}
5
6// 格子点上の制御値を補間して、連続的な地形の高さを返す
7function interpolatedNoise(
8 controlPoints: number[],
9 x: number,
10 mode: "linear" | "smooth"
11): number {
12 const i = Math.floor(x);
13 const t = x - i;
14
15 const v0 = controlPoints[i % controlPoints.length];
16 const v1 = controlPoints[(i + 1) % controlPoints.length];
17
18 const factor = mode === "smooth" ? smoothstep(t) : t;
19 return v0 + factor * (v1 - v0);
20}
21
22// 8個のランダムな制御点(例: 地形の高さのシード値)
23const controlPoints = Array.from({ length: 8 }, () => Math.random() * 10);
24
25// x = 0 〜 8 の範囲を0.1刻みでサンプリングして地形プロファイルを生成
26const terrainProfile = Array.from({ length: 80 }, (_, k) => {
27 const x = k * 0.1;
28 return {
29 x,
30 linear: interpolatedNoise(controlPoints, x, "linear"),
31 smooth: interpolatedNoise(controlPoints, x, "smooth"),
32 };
33});
34
35console.log("地形プロファイル(先頭5点):", terrainProfile.slice(0, 5));

次に学ぶならコレ!おすすめトピック

この単元と深い繋がりを持つ、あわせて学ぶと理解が深まるおすすめ単元

数理モデル・概念が近い関連トピック

B(t) 媒介変数CSS cubic-bezier
関連度高高校数学

ベジェ曲線とデザイン幾何学(フォント・UIの数理)

「制御点を引っ張ると曲線が曲がる理由」線分内分が創り出す美しきグラフィックス

関連度高工学応用

最短経路探索(ダイクストラ法とA*アルゴリズム)

グラフ上の無数のルートから「最もコストが小さい道」を一瞬で見つけ出す数学

関連度高工学応用

当たり判定アルゴリズムの数学

2点間の距離公式と座標の不等式だけで、ゲームの「衝突」を判定する仕組み

同じレベルで次に挑戦したいトピック

同レベル推薦工学応用

勾配降下法

谷底を探すAIの基本アルゴリズム

同レベル推薦工学応用

ニューラルネットワークの数学(順伝播と活性化関数)

入力に重みを掛けて足し合わせ、非線形関数で発火させるAIの基本素子

同レベル推薦工学応用

レコメンドの仕組み(コサイン類似度とベクトル検索)

ユーザーの好みと商品の近さを「ベクトルのなす角」で判定するアルゴリズム

工学・実社会での応用先でつながるトピック

工学・実践連携小学校・算数

円の面積と円周率

半径を変えると、円周と面積はどう変わる?

工学・実践連携小学校・算数

三角形・多角形の面積

頂点を動かして、面積の公式が成り立つ理由を確かめよう

工学・実践連携小学校・算数

単位変換(長さ・面積・体積)

長さが2倍になると、面積・体積は何倍になる?

あなたの数学力をさらに伸ばす

数学の弱点診断や算数パズルに挑戦してみませんか?

簡単な質問に答えてあなたにぴったりの学習ロードマップを発見したり、直感を試すパズルで数の面白さを体験できます。