[Noise 入門 #51] 量子揺らぎ(Quantum Fluctuation)と空間崩壊

はじめに

第5集までの「Procedural World編」では、ノイズを用いて地形を隆起させ、雲を浮かべ、無限に広がるボクセル世界を構築してきました。
つまり、これまではノイズを使って「世界(World)」という物理的な実体を作ってきたことになります。

しかし、今回から始まる第6集【神領域】では少し趣向を変えます。物理法則に基づく自然物ではなく、「現象(Phenomenon)」や「エネルギー」そのものを描画します。

その第一弾となる本記事のテーマは「量子揺らぎ(Quantum Fluctuation)」です。 高周波な 4D Simplex Noise を極限まで Domain Warping(座標のねじれ)させ、空間が沸騰し、次元が歪むような「目に見えないエネルギーの奔流」を GLSL で実装し、その数式的・視覚的な構造を解剖・鑑賞していきます。

前回の記事:

生成された「量子揺らぎ」の瞬間

まずは、今回のロジックによって生成される、極限状態の「量子揺らぎ」のビジュアルをご覧ください。

穏やかに流れる雲や波とは対照的に、空間そのものが引き裂かれ、細かな粒子が超高速で沸騰しているような、混沌としたエネルギーの渦が確認できるはずです。

 

Youtube:


この表現のロジックを解剖する(知見)

このビジュアルは、ただ闇雲に複雑な数式を並べたわけではありません。これまで学んできた「FBM(Fractal Brownian Motion)」と「Domain Warping」という2つの強力な武器を、あえて「物理法則が破綻するレベル」まで過剰に掛け合わせた結果として生まれています。

この現象を引き起こすための3つのコア・ロジックを解剖してみましょう。

1. 高周波(High Frequency)による「空間の沸騰」

地形や雲を作る際、私たちは通常、ノイズの基本周波数(Frequency)を低く設定して「滑らかなうねり」を作りました。しかし今回は、ベースとなる周波数を意図的に極端に高く設定します。

これにより、空間全体が微細な単位で振動し始めます。滑らかなグラデーションは失われ、まるでブラウン運動をする素粒子のように、ノイズの値がピクセル単位で激しく明滅(沸騰)する土台が出来上がります。

2. 多重再帰的な Domain Warping(座標崩壊)

[#06] や [#07] で解説した Domain Warping は、通常 $p’ = p + \text{noise}(p)$ のように、ある座標 $p$ をノイズの値によって一度(または二度)ずらすことで、「マーブル模様」や「流体のようなねじれ」を作りました。

量子揺らぎを表現するためには、このねじれを多重かつ再帰的に適用し、空間の幾何学的な秩序を完全に破壊します。

数式的なイメージとしては以下のようになります。 $$q = p + \text{noise}(p \cdot f_1) \cdot s_1$$ $$r = q + \text{noise}(q \cdot f_2) \cdot s_2$$ $$p_{final} = r + \text{noise}(r \cdot f_3) \cdot s_3$$

ここで重要なのは、「すでに激しく歪んだ座標($q$ や $r$)をシード値として、さらにノイズをサンプリングして歪ませる」という点です。パラメーターである強さ($s$)を臨界点まで引き上げると、座標系が自己崩壊を起こし、視覚的には「空間が裂けた」ような鋭利なエッジと混沌が生まれます。

3. 4D(時間次元)による「脈動」

静止した画像の崩壊ではなく、「沸騰し続けるエネルギー」を表現するためには時間軸が不可欠です。今回は 4D Simplex Noise を採用し、第4のパラメーターとして u_time (経過時間)を流し込みます。

単に2Dや3Dのノイズ空間をカメラが移動する(スクロールする)のとは異なり、4Dノイズの時間を進めることで、空間の構造そのものがその場でモゾモゾと変容し続ける、有機的で予測不能な「脈動」を得ることができます。

それでは、ブログの続きとなる「実装とパラメーターの解説」パートを作成します。そのままMarkdownに貼り付けていただけます。

実装と鑑賞:神のパラメーターを操る

実際に GLSL でこの「量子揺らぎ」を記述してみましょう。

第6集では、ゼロからアルゴリズムを組み上げる苦労は一旦脇に置きます。以下の Fragment Shader コードをお手元の Three.js 環境(ShaderMaterial)に貼り付け、パラメーター(uniform 変数)を操作して、空間が崩壊する様を「鑑賞」してください。

※ 4D Simplex Noise のコア関数(simplex4d_noise)は、[#15] で実装したものをそのまま流用します。

// --- Uniforms(外部から操作する神のパラメーター) ---
uniform float u_time;
uniform vec2 u_resolution;

// 鑑賞用の調整パラメーター
uniform float u_noise_frequency; // 推奨値: 1.0 〜 5.0 (沸騰の細かさ)
uniform float u_warp_strength;   // 推奨値: 1.0 〜 10.0 (空間崩壊のトリガー)
uniform float u_time_scale;      // 推奨値: 0.1 〜 2.0 (脈動のスピード)

// 発光カラー
uniform vec3 u_base_color;       // 例: vec3(0.05, 0.05, 0.1) 暗い宇宙の色
uniform vec3 u_accent_color1;    // 例: vec3(0.2, 0.8, 1.0) 量子的な青白さ
uniform vec3 u_accent_color2;    // 例: vec3(1.0, 0.2, 0.5) 破壊的なマゼンタ

// --- 4D Simplex Noise (実装省略: #15 を参照) ---
// float simplex4d_noise(vec4 p) { ... }

void main() {
    // ピクセル座標の正規化(画面中央を原点に)
    vec2 st = gl_FragCoord.xy / u_resolution.xy;
    st = st * 2.0 - 1.0;
    st.x *= u_resolution.x / u_resolution.y;

    // 時間のスケール調整
    float t = u_time * u_time_scale;

    // --- 【神領域:多重・再帰的 Domain Warping の錬成】 ---

    // 1. 初期座標に周波数を掛け、高周波な土台を作る
    vec4 p = vec4(st * u_noise_frequency, 0.0, t * 0.5);

    // 2. Warp 1層目:座標 p を少し歪ませて q を作る
    vec4 q = p + vec4(
        simplex4d_noise(p + vec4(0.0)),
        simplex4d_noise(p + vec4(5.2)),
        simplex4d_noise(p + vec4(1.3)),
        0.0
    ) * 0.2;

    // 3. Warp 2層目:歪んだ q をシードにしてさらに大きく歪ませ、r を作る
    vec4 r = q + vec4(
        simplex4d_noise(q + vec4(1.7)),
        simplex4d_noise(q + vec4(9.2)),
        simplex4d_noise(q + vec4(8.3)),
        0.0
    ) * u_warp_strength * 0.5;

    // 4. Warp 3層目(臨界点):r を使って最終的な座標 f_p を破壊的に生成
    vec4 f_p = r + vec4(
        simplex4d_noise(r + vec4(3.1)),
        simplex4d_noise(r + vec4(4.6)),
        simplex4d_noise(r + vec4(7.2)),
        0.0
    ) * u_warp_strength;

    // 最終的なノイズ値を抽出(完全に秩序を失った値)
    float noise_val = simplex4d_noise(f_p);

    // --- 【カラーリングと発光処理(VFX)】 ---

    // 揺らぎの「等高線」を抽出し、鋭いパルス(発光)を作る
    float contour = 1.0 - abs(noise_val);
    float pulse = pow(contour, 8.0); // 8乗して光の鋭さを強調

    // 歪み具合(f_pの各成分)を利用して色を動的にブレンド
    float mix_factor = clamp(f_p.x * f_p.y * 0.5 + 0.5, 0.0, 1.0);
    vec3 color = mix(u_base_color, u_accent_color1, noise_val * 0.5 + 0.5);
    color = mix(color, u_accent_color2, mix_factor);

    // 最後にパルスの発光を加算
    color += u_accent_color1 * pulse * 2.0;

    gl_FragColor = vec4(color, 1.0);
}

鑑賞のポイント(チューニングガイド)

Three.js 側の JavaScript で、上記の uniform にGUI(Dat.GUI や Lil-gui など)を接続してみてください。

  1. u_warp_strength を 0.0 から徐々に上げる: 最初はただの細かい砂嵐(沸騰)だったものが、値が 3.0 を超えたあたりから空間が引き伸ばされ、10.0 に近づくと完全に次元が裂けたような「渦」が画面のあちこちに発生します。
  2. u_time_scale で時間の流れを操作: 激しく崩壊している状態で u_time_scale を 0.1 程度まで落とすと、スローモーションでエネルギーが蠢く、非常に神秘的な現象を観察できます。

数式が物理法則を逸脱し、純粋な「視覚効果(VFX)」として破綻するギリギリの美しさ。これが神領域のノイズアートです。

おわりに

第6集【神領域】の第一歩として、「量子揺らぎ(Quantum Fluctuation)」を実装し、空間が崩壊する様を鑑賞しました。

これまでの地形生成では、ノイズをいかに「コントロールして自然界に似せるか」がテーマでした。しかし今回は、多重かつ再帰的な Domain Warping を用いて、ノイズの座標系を意図的に「崩壊」させることで、未知のエネルギーやVFX(視覚効果)を生み出しました。

数式が物理法則の枠を外れ、純粋なアートや魔法として画面に立ち現れる瞬間。これこそが、Shader とノイズがもつ真のポテンシャルであり、神領域と呼ぶにふさわしい表現です。

次回以降も、この「現象の解剖」を続けていきます。 空間をねじ曲げるだけでなく、化学反応のシミュレーション(チューリング・パターン)との融合や、ノイズをドロドロの液体金属に変える表現など、さらに深い未知の視覚体験へと潜っていきましょう。

終わらないノイズの旅路、第6集も引き続きお付き合いください。