title: "バリューノイズ" description: "格子点にランダム値を割り当て、補間することでなめらかなノイズを生成する手法を学びます。" chapter: "07-noise" order: 2 challenge: description: "バリューノイズを使って、グラデーションを歪ませてみましょう。横方向のグラデーション(uv.x)にノイズ値を加算して、ゆらぎのあるグラデーションを作ってください。" hints:
- "まずは基本のグラデーション float base = uv.x; を作り、そこにノイズを加算します。"
- "ノイズの影響度を調整するには係数を掛けます。例: base + valueNoise(uv * 5.0) * 0.3"
- "最終的に vec3 color = vec3(uv.x + valueNoise(uv * 5.0) * 0.3); のように書くと、ノイズで歪んだグラデーションが完成します。"
バリューノイズ
ランダムから「ノイズ」へ
前回学んだ疑似乱数は、ピクセルごとに完全にバラバラな値を返しました。自然界のテクスチャ(雲、山、木の肌)は、完全にランダムではなくなめらかな変化を持っています。
ノイズとは、空間的に連続で滑らかな疑似ランダム関数のことです。近くのピクセル同士は似た値を持ち、離れるにつれて変化します。
バリューノイズの仕組み
バリューノイズは最も単純なノイズ関数です:
- 格子点にランダムな値を割り当てる
- 格子点の間を補間する
float valueNoise(vec2 st) {
vec2 i = floor(st); // 格子点の整数部分
vec2 f = fract(st); // 格子内の位置(0.0〜1.0)
// 四隅のランダム値
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
// 補間
vec2 u = smoothstep(0.0, 1.0, f);
return mix(
mix(a, b, u.x),
mix(c, d, u.x),
u.y
);
}
floor と fract
floor(st) と fract(st) の役割を理解しましょう:
floor(st)— 格子点のインデックス。どのセルにいるかを示すfract(st)— セル内の位置。補間のウェイトに使う
例えば st = vec2(3.7, 2.3) なら:
floor=vec2(3.0, 2.0)→ 格子点(3, 2)のセルfract=vec2(0.7, 0.3)→ セル内の右寄り・やや下
バイリニア補間
4つの格子点の値をバイリニア補間(二方向の線形補間)で混ぜます:
c --- d
| |
| p | p = 現在のピクセル位置
| |
a --- b
まず横方向に補間(aとb、cとd)し、次に縦方向に補間します。
smoothstep で滑らかに
単純な線形補間(mix(a, b, f.x))だと、格子点で傾きが不連続になります。smoothstep を使うと、格子の境界で滑らかにつながります:
// 線形補間 — 格子の境目がギザギザ
vec2 u = f;
// smoothstep補間 — 滑らか
vec2 u = smoothstep(0.0, 1.0, f);
// さらに滑らかな補間(quintic)
vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
右のエディタでは、バリューノイズをグレースケールで可視化しています。uv にかけるスケール値を変えると、ノイズの粗さが変わります。
スケール
valueNoise(uv * 5.0) のようにスケールを変えると:
- 小さい値 → 大きなうねり(低周波)
- 大きい値 → 細かいノイズ(高周波)
まとめ
- バリューノイズは格子点のランダム値を補間して作る
floorでセル、fractでセル内位置を求めるsmoothstepで滑らかな補間を実現- スケール値で粗さを調整できる