title: "ディストーション" description: "UV座標を変形させるディストーションエフェクトを学びます。波紋や渦巻きなどの座標変形テクニックを習得します。" chapter: "08-textures" order: 4 challenge: description: "渦巻き(Swirl)ディストーションを実装しましょう。中心からの距離に応じて座標を回転させ、渦巻き状にパターンを歪ませてください。" hints:
- "中心からの距離で回転角度を決めます: float angle = dist * 5.0;"
- "2D回転の公式: x' = xcos(a) - ysin(a), y' = xsin(a) + ycos(a)"
- "完成形: vec2 centered = uv - 0.5; float dist = length(centered); float angle = dist * 8.0 - u_time; vec2 rotated = vec2(centered.xcos(angle)-centered.ysin(angle), centered.xsin(angle)+centered.ycos(angle)); vec2 distorted = rotated + 0.5; そしてこの distorted を使ってパターンを描画します。"
ディストーション
UV座標の変形
これまで学んだエフェクトは色の値を変換するものでしたが、ディストーションは座標自体を変形させます。テクスチャやパターンを読み取る前にUV座標を歪ませることで、波紋、渦巻き、レンズ歪みなどの効果が得られます。
// 通常のパターン取得
vec3 color = pattern(uv);
// ディストーション適用
vec2 distortedUV = distort(uv);
vec3 color = pattern(distortedUV);
「色を変えるのではなく、どこを見るかを変える」のがディストーションの本質です。
波紋エフェクト
中心からの距離に応じたsin波で座標をずらします:
vec2 centered = uv - 0.5;
float dist = length(centered);
// 距離に応じた波紋
float wave = sin(dist * 30.0 - u_time * 3.0) * 0.02;
// 中心方向にずらす
vec2 distorted = uv + normalize(centered) * wave;
sin(dist * 周波数) で距離に応じた同心円状の波を作り、その振幅分だけ座標をずらします。u_time を引くことで波が外側に広がるアニメーションになります。
渦巻きエフェクト
中心からの距離に応じて座標を回転させます:
vec2 centered = uv - 0.5;
float dist = length(centered);
// 距離に応じた回転角
float angle = dist * 8.0;
// 2D回転
vec2 rotated = vec2(
centered.x * cos(angle) - centered.y * sin(angle),
centered.x * sin(angle) + centered.y * cos(angle)
);
vec2 distorted = rotated + 0.5;
中心に近いほど回転角が小さく、遠いほど大きく回転するので、渦巻き状の歪みになります。
2D回転の復習
2D回転行列を使った座標変換:
vec2 rotate(vec2 p, float angle) {
float c = cos(angle);
float s = sin(angle);
return vec2(p.x * c - p.y * s, p.x * s + p.y * c);
}
この関数は原点中心で回転するので、まず座標を中心に移動してから回転し、元に戻す必要があります。
ノイズディストーション
前章で学んだノイズをディストーションに使うと、有機的な歪みが得られます:
vec2 offset = vec2(
valueNoise(uv * 5.0),
valueNoise(uv * 5.0 + vec2(100.0))
);
vec2 distorted = uv + (offset - 0.5) * 0.1;
魚眼レンズ
中心からの距離を非線形に変換すると、魚眼レンズのような効果が得られます:
vec2 centered = uv - 0.5;
float dist = length(centered);
float power = 2.0;
vec2 distorted = 0.5 + normalize(centered) * pow(dist, power);
組み合わせ
ディストーションはチェーンすることができます:
vec2 uv1 = ripple(uv); // まず波紋
vec2 uv2 = swirl(uv1); // 次に渦巻き
vec3 color = pattern(uv2); // 最後にパターン取得
右のエディタでは、チェッカーボードパターンに波紋ディストーションを適用しています。
まとめ
- ディストーションはUV座標を変形させるエフェクト
- 波紋 —
sin(距離)で放射状の歪み - 渦巻き — 距離に応じた回転
- ノイズで有機的な歪み
- 複数のディストーションを組み合わせられる