地図/幾何/SDFと双曲

反応拡散 — 場が自分で育つ

反応拡散の場は二枚あって、互いの値を見ながら毎フレーム自分を書き換える。座標を入れたら即値が返る一枚関数ではなく、前のフレームの場が次のフレームの場の材料になる。時間は外から足す引数でなく、書き換えの繰り返しそのものから出てくる。

Gray-Scott 反応拡散は、二つの化学物質 A と B の濃度を格子の各セルで追う。A は外から一定率 feed で補充され、B は一定率 kill で抜かれる。反応 A + 2B → 3B で A が B に変わり、両方が拡散する。feedkill のわずかな違いで、斑点・迷路・縞といった模様が定常状態として立つ。Turing が 1952 年に動物の体表模様の起源として論じた仕組みの一例。拡散・移流・反応というこの枠組みは、流体の Navier–Stokes 方程式と同じ形をしている。

場が二枚ある。a は A の濃度、b は B の濃度で、どちらも GW × GH のセルを一次元配列に詰めたもの。全面を A で満たし(a は 1)、B はいくつかの正方形の種だけ撒く(b を 1 に)。更新ルールはまだ入れず、B の濃度だけを明るさに塗る。

B の種が並んだまま動かない。場が二枚あるだけで更新ルールが入っていないので静止する。拡散だけを入れると、各セルの値が近傍の平均と自分の差ぶんだけ近傍へ寄る。この近傍の平均と自分の差がラプラシアン。DB がその強さで、B が四方へにじむ。

種の角が取れて丸くにじみ、中心の濃さが薄れて周りへ散る。b2 という二枚目に書いて b.set(b2) で入れ替えているのは、更新中に元の値を読み続けるため。書きながら同じ配列を読むと、計算済みの隣のセルが混ざってしまう。読みと書きを分けるのがダブルバッファx > 0 ? i - 1 : i + GW - 1 の三項は、左端のセルが反対の右端を隣として参照する繞り込みで、面が筒状に繋がる。

拡散だけだと B はただ薄まって消える。補充・除去・反応を足すと Gray-Scott になる。A の式に拡散 DA * lap(a)、反応で減る分 - A*B*B、補充 + feed*(1-A) を足す。B の式に拡散 DB * lap(b)、反応で増える分 + A*B*B、除去 - (kill+feed)*B を足す。両方の場を毎フレーム更新する。

種が増殖して分裂し、迷路のように伸びていく。一フレームに step を 8 回回しているのは、一回の更新の変化が小さく、模様が育つまで時間がかかるため。feed0.037kill0.06 あたりから少し動かすと模様が変わる。feed を上げて 0.055kill0.062 にすると斑点が分裂を続け、feed0.026kill0.051 にすると線が太く繋がって珊瑚状になる。座標と値を結ぶ一枚関数と違って、場が状態を持ち、局所の書き換えだけで全体の模様が立つ。