title: "fBm (Fractal Brownian Motion)" description: "複数のノイズを重ね合わせるfBmを学びます。異なるスケールのノイズを組み合わせて、雲や地形のような複雑なパターンを生成します。" chapter: "07-noise" order: 4 challenge: description: "fBmを使って地形のような見た目を作りましょう。fBmの値に応じて色を段階的に変え、水(青)→砂浜(黄)→草地(緑)→山(茶)→雪(白)のカラーマップを適用してください。" hints:
- "fBmの値をしきい値で分岐させます。例: n < 0.4 なら水、n < 0.5 なら砂浜..."
- "smoothstep を使うと境界を滑らかにできます。"
- "水: vec3(0.1, 0.3, 0.6), 砂浜: vec3(0.8, 0.7, 0.4), 草地: vec3(0.2, 0.5, 0.2), 山: vec3(0.4, 0.3, 0.2), 雪: vec3(1.0) のように設定します。"
fBm (Fractal Brownian Motion)
自然はフラクタル
海岸線、山脈、雲——自然の形はフラクタル的な性質を持っています。大きなスケールの凹凸の上に、小さな凹凸が重なり、さらにその上に細かい凹凸が...という構造です。
1回のノイズでは、1つのスケールの変化しか表現できません。fBm(Fractal Brownian Motion) は、異なるスケールのノイズを重ね合わせることで、フラクタル的な複雑さを生み出します。
fBmの仕組み
基本的な考え方はシンプルです。ノイズを倍々のスケールで計算し、半分の振幅で足し合わせます:
float fbm(vec2 st) {
float value = 0.0;
float amplitude = 0.5; // 振幅
float frequency = 1.0; // 周波数
for (int i = 0; i < 6; i++) {
value += amplitude * valueNoise(st * frequency);
frequency *= 2.0; // 周波数を倍に(lacunarity)
amplitude *= 0.5; // 振幅を半分に(gain)
}
return value;
}
各ループ(オクターブ)で:
- 周波数を2倍にする → より細かいスケールのノイズ
- 振幅を半分にする → 細かいスケールほど影響が小さい
lacunarity と gain
fBmの性質を制御する2つのパラメータ:
| パラメータ | 意味 | 典型値 | |-----------|------|--------| | lacunarity | 周波数の倍率 | 2.0 | | gain (persistence) | 振幅の減衰率 | 0.5 |
frequency *= lacunarity; // 通常 2.0
amplitude *= gain; // 通常 0.5
- lacunarity を上げる → オクターブ間のスケール差が大きくなる
- gain を上げる → 高周波の影響が大きくなり、よりザラザラに
- gain を下げる → 高周波の影響が小さくなり、より滑らかに
オクターブ数
ループ回数(オクターブ数)はディテールの細かさを決めます:
- 1〜2オクターブ — なめらかな丘
- 4〜6オクターブ — 雲のような複雑さ
- 8以上 — 非常に細かいディテール(計算コスト高)
実用的には 4〜6オクターブで十分な場合がほとんどです。
雲テクスチャ
右のエディタでは、fBmを使って雲のようなテクスチャを生成しています。fBmの値を色にマッピングすると、非常にリアルな雲が表現できます。
float n = fbm(uv * 3.0 + u_time * 0.1);
vec3 sky = vec3(0.4, 0.6, 0.9);
vec3 cloud = vec3(1.0);
vec3 color = mix(sky, cloud, n);
fBmの応用
fBmは驚くほど多様な表現に使えます:
- 雲 — fBmの値を白と空色の間でマッピング
- 地形 — fBmの値を高さとして、色で段階表示
- 水面 — fBmでUV座標を歪ませて波紋を表現
- 炎 — fBmにy方向の減衰と時間変化を加える
- 大理石 —
sin(x + fbm(...))で縞模様にノイズを加える
Domain Warping
fBmの結果をさらに別のfBmの入力にするDomain Warpingは、非常に有機的な模様を作れます:
float n = fbm(st + fbm(st + fbm(st)));
まとめ
- fBmは複数オクターブのノイズを重ね合わせる
- lacunarity(周波数倍率)とgain(振幅減衰)で性質を制御
- 4〜6オクターブで十分な複雑さが得られる
- 雲、地形、水面など自然現象の表現に不可欠