Fluids & reaction

Reaction–Diffusion / Gray–Scott Model

反応拡散

物質の反応と拡散から斑点や迷路模様を成長させる。

10 / 10

Interactive demo

Preparing the demo…

Reaction–Diffusion / Gray–Scott Model

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

2 種類の物質が反応しながら広がる(拡散する)様子を計算すると、斑点、しま、迷路、サンゴのような模様がひとりでに生まれます。数学者アラン・チューリングが 1952 年に「動物の模様はこうしてできるのでは」と提案した仕組みで、グレイ・スコット模型はその代表的な計算モデルです。2 つのパラメータを少し変えるだけで、模様の種類ががらりと変わります。

ゲームでの使いどころ

  • 生物的なテクスチャ:動物の斑点やしま、珊瑚、脳のようなしわ、菌類の広がり。手描きでは難しい「自然な不規則さ」を持った模様を作れます。
  • 成長する表現:感染が広がる、侵食する、魔法の紋様が浮かび上がる、といった時間とともに模様が育つ演出。GPU で毎フレーム計算すれば、リアルタイムに広がります。
  • ディスプレイスメント:模様の濃さで表面を盛り上げると(頂点変位)、珊瑚や生き物の皮膚のような立体的な表面になります。
  • 手続き的なアート:タイトル画面やアートワークの生成。

しくみ

物質 A(餌)と物質 B(A を食べて増える物質)の濃さ aa, bb を、各マスで次の式に従って更新します。

∂a∂t=Da ∇2a−ab2+f (1−a),∂b∂t=Db ∇2b+ab2−(k+f) b\frac{\partial a}{\partial t} = D_a\,\nabla^2 a - a b^2 + f\,(1 - a), \qquad \frac{\partial b}{\partial t} = D_b\,\nabla^2 b + a b^2 - (k + f)\,b
  • ∇2\nabla^2(ラプラシアン)は「周りの平均との差」で、拡散(周りへ広がってならす働き)を表します。A は B より速く広がります(Da=1D_a = 1, Db=0.5D_b = 0.5 など)。
  • ab2a b^2 が反応で、B は A を 1 つと B を 2 つで B を 3 つにする(A を食べて増える)。
  • f(1−a)f(1 - a) は補給で、A は外から一定の速さ ff で補われます。
  • (k+f) b(k + f)\,b は除去で、B は一定の速さ kk で消えていきます。

模様が生まれる理由:B が増えた場所では A が食べ尽くされます。A は速く広がるので、B の周りの少し離れた場所まで A が減り、そこでは B が育ちません。「近くでは増え、少し離れると抑えられる」という働きが、一定の間隔で B の塊を並べ、模様を作ります(短距離の活性化と長距離の抑制)。

ff と kk の組み合わせで、模様の種類が決まります。

模様ffkk
増える斑点(細胞分裂)0.03670.0649
迷路・しま0.0290.057
サンゴ0.05450.062
穴の開いた膜0.0390.058

実装のポイント

  • GPU のピンポンバッファで:状態を浮動小数点テクスチャに置き、1 フレームに 10〜40 回ほど更新します。模様が育つのに数千ステップかかるので、1 フレームに何回も回します。
  • ラプラシアンは 3×3 の重みで:上下左右 0.2、斜め 0.05、中心 −1 の重みにすると、格子の向きの偏りが少ない丸い模様になります。
  • 端をつなぐ:テクスチャの繰り返し設定を使えば、端と端がつながった模様になり、タイル状に敷き詰めたり、ドーナツ形(トーラス)に継ぎ目なく貼ったりできます。
  • 最初の種:全体を A = 1、B = 0 にし、ところどころに B の小さな塊を置くと、そこから模様が育ちます。

つまずきやすい点

  • 何も起きない・すべて消える:ff と kk が模様の生まれる範囲から外れると、B がすぐに消えるか、一面に広がって均一になります。模様が出る範囲はとても狭いので、既知の値から少しずつ動かします。
  • 時間刻みが大きすぎる:1 ステップの変化を大きくしすぎると、値が暴れて発散します。拡散係数と時間刻みの積が 0.25 程度を超えないようにします。
  • テクスチャの伸び:3D モデルに貼ると、UV の伸び縮みに合わせて模様も伸びます。UV の縦横比に合わせてテクスチャの解像度を決めます。

デモで試すこと

  1. ドーナツの表面で、サンゴのような模様が育っていきます。模様の濃さ(物質 B の量)で表面が盛り上がっています。
  2. 「模様」を切り替えると、補給の速さ f と消える速さ k が変わり、斑点が分裂して増える、迷路のしま模様になる、などがらりと変わります。
  3. f と k のスライダーを少しずつ動かして、模様がどう変わるかを確かめてください。ほんのわずかな違いで、模様が消えたり、全体を覆ったりします。
  4. 表面をクリックすると、その場所に B を置いて、新しい模様の種をまけます。「種をまき直す」で最初からやり直せます。

References

Karl Sims — Reaction-Diffusion Tutorial ↗