01単純なルールが、複雑な模様を生む
ヒョウの斑点、シマウマの縞、熱帯魚の紋様、サンゴの形——自然界には複雑で美しい模様があふれている。これらはどうやって生まれるのか。設計図があるわけではない。驚くべきことに、ごく単純な局所ルールの繰り返しから、これらの模様は自発的に立ち現れる。
1952年、アラン・チューリングは「形態形成の化学的基礎」という論文で、2つの物質が反応しながら拡散すると、空間に安定した模様(チューリングパターン)が生まれることを数学的に示した。本稿で扱う反応拡散系は、その代表的なモデルだ。これまでの実験ノートで扱ってきた「計算」を、画面全体の生きた模様として描き出す。
02グレイ・スコットの式
反応拡散系の中でも有名なのがグレイ・スコットモデルだ。2つの仮想的な化学物質 U と V を考える。Uは「基質」、Vは「生成物」。この2つが、次のルールで変化する。
そして U と V は、それぞれ周囲へ拡散する
これを式にすると、各点での U, V の時間変化は次のように書ける。
∂V/∂t = Dv·∇²V + U·V² − (f+k)·V
∇²(ラプラシアン)が拡散、U·V²が反応を表す。fは U の供給率、kは V の除去率。
このf と k の値を変えるだけで、生まれる模様が劇的に変わる——それが反応拡散系の最大の魅力だ。式は固定したまま、たった2つの数字で、迷路にも、斑点にも、うねる虫にもなる。
03状態をテクスチャに持つ — もう一つのGPGPU
ここからが実装だ。粒子のシミュレーションでは、各粒子の状態を「バッファ」(1次元の配列)に持った。だが反応拡散系は2次元の場——画面の各ピクセルが状態を持ち、隣のピクセルと影響し合う。この2次元の状態を保持するのに最適なのがテクスチャだ。
各ピクセルに U と V の2つの値を持たせる。rg32float形式のテクスチャを使えば、R チャンネルに U、G チャンネルに V を格納できる。コンピュートシェーダーは、このテクスチャを読んで計算し、結果を別のテクスチャに書く。
コンピュートシェーダーでは、各ピクセルが自分と上下左右・斜めの隣を読んでラプラシアン(拡散)を計算し、グレイ・スコットの式で次の U, V を求める。
textureLoad(src, p+offset)で隣のピクセルを直接読める。反応拡散のように「各点が周囲と影響し合う」場の計算には、テクスチャが向いている。
04ダブルバッファ — 読みと書きを分ける
ここで重要な制約がある。同じテクスチャを、同時に読みながら書くことはできない。もし1枚のテクスチャで計算すると、あるピクセルを更新した後、隣のピクセルがその「更新済みの値」を読んでしまい、計算が壊れる。全ピクセルは「同じ時刻の状態」を見る必要がある。
そこでテクスチャを2枚(A, B)用意し、交互に読み書きする。Aを読んでBに書く→次はBを読んでAに書く→またA…と切り替える。これがダブルバッファだ。
05全画面に描く — テクスチャを絵にする
計算した状態テクスチャを、画面に表示する。やり方はシンプルだ。画面全体を覆う四角形(2つの三角形)を描き、そのピクセルごとにテクスチャから V の値をサンプリングして、色に変換する。
頂点バッファすら要らない。頂点シェーダーがvertex_indexから画面隅の座標を直接生成し、フラグメントシェーダーが各ピクセルでテクスチャを読んで色を決める。計算結果のテクスチャが、そのまま画面の絵になる。V の濃度をどう色にマッピングするかで、同じ模様がシアンにも炎にも虹にもなる。
06f と k の魔法 — パラメータで模様が激変
反応拡散系の醍醐味は、式は同じまま、f と k の2つの数字だけで模様が一変することだ。これらをuniformでシェーダーに渡せば、実行中に切り替えられる。
動く点 (f=0.014, k=0.054) 増殖 (f=0.030, k=0.057)
ただし注意がある。f, k の組み合わせには「模様が広がる領域」と「種が点のまま止まる領域」がある。同じグレイ・スコットでも、パラメータ次第で画面全体に広がることも、孤立した点で固まることもある。どの値が広がるかは、実際に計算して確かめるのが確実だ。本稿のデモのプリセットは、いずれも広がりを数値的に確認した値を採用している。
07試してみる
下のデモは、ここまで解説した反応拡散系がそのまま動いている。パターンを切り替えて模様の激変を見たり、画面をタッチして種をまいたり、配色を変えたりできる。単純な2つの式から、生命的な模様が自発的に育っていく様子を体感してほしい。
08結論 — 計算と生命のあいだ
反応拡散系が見せるのは、ただの綺麗な模様ではない。設計図のない自己組織化——中央の制御なしに、局所的なルールの繰り返しだけで、全体に秩序ある構造が生まれる現象だ。生物の模様、細胞の分化、さらには銀河の構造まで、自然界の形作りの根底には、こうした自己組織化がある。
技術的には、これは粒子描画とは異なるGPGPUの形を示している。粒子は1次元バッファに状態を持ち点として描いた。反応拡散は2次元テクスチャに状態を持ち、面として描く。compute がテクスチャを更新し、render がそれを画面に貼る——この「テクスチャを介したGPGPU」は、流体、煙、群衆、地形生成など、場のシミュレーション全般に通じる強力なパターンだ。
単純な計算が、生命の模様になる。手のひらの中のGPUで、チューリングが70年前に数式で予言した形態形成が、いま実際に立ち現れる。計算と生命のあいだには、思いのほか短い距離しかないのかもしれない。