Following, springs & flocks

Boids / Flocking

ボイド

分離、整列、結合で鳥や魚の群れを動かす。

8 / 10

Interactive demo

Preparing the demo…

Boids / Flocking

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

This explanation is currently available in Japanese.

ひとことで

Craig Reynolds が 1987 年に発表した、鳥や魚の群れをシミュレーションする手法です。各個体が「近くの仲間から離れる(分離)」「近くの仲間と向きをそろえる(整列)」「近くの仲間の中心へ寄る(結合)」という 3 つの単純な規則に従うだけで、全体として渦を巻いたり分かれたり合流したりする、生き生きとした群れが生まれます。

ゲームでの使いどころ

  • 環境の生き物:空を飛ぶ鳥の群れ、水中の魚群、コウモリ、ホタル。
  • 大群の敵:ゾンビの群れ、虫の大群、ドローンの編隊。
  • RTS のユニット移動:同じ目的地へ向かう部隊が重ならずにまとまって進む。
  • パーティクル表現:魔法の光の粒子が群れのようにまとわりつくエフェクト。

しくみ

個体 ii の近傍(半径 rr 以内の仲間)の集合を NiN_i とすると、3 つの操舵力は次のとおりです。

Fsep=∑j∈Nipi−pj∥pi−pj∥2(近いほど強く離れる)Fali=1∣Ni∣∑j∈Nivj−vi(平均の速度に合わせる)Fcoh=1∣Ni∣∑j∈Nipj−pi(平均の位置へ向かう)\begin{aligned} \mathbf{F}_{\text{sep}} &= \sum_{j \in N_i} \frac{\mathbf{p}_i - \mathbf{p}_j}{\lVert \mathbf{p}_i - \mathbf{p}_j \rVert^2} && \text{(近いほど強く離れる)}\\ \mathbf{F}_{\text{ali}} &= \frac{1}{|N_i|}\sum_{j \in N_i} \mathbf{v}_j - \mathbf{v}_i && \text{(平均の速度に合わせる)}\\ \mathbf{F}_{\text{coh}} &= \frac{1}{|N_i|}\sum_{j \in N_i} \mathbf{p}_j - \mathbf{p}_i && \text{(平均の位置へ向かう)} \end{aligned}

これらを重み付けして合計し、上限で切り詰めて速度に加えます。どの個体も「群れ全体」を知らず、近くの数匹しか見ていないのに、全体の形が生まれる創発の代表例です。

規則強すぎると弱すぎると
分離ばらばらに散る重なり合って団子になる
整列全員が同じ向きの行進になる無秩序に動き回る
結合1 つの塊に固まる小さな群れに分裂する

分離は、近傍半径よりずっと近い相手(デモでは約 0.45 倍)だけから受けるのが一般的です。同じ半径で 3 つを計算すると、分離が勝って群れが広がりきってしまいます。

実装のポイント

  • 近傍探索が計算量の本体:素朴に全ペアを調べると O(n2)O(n^2) です。数百匹ならそれでも動きますが、千匹を超えるなら空間ハッシュで近傍候補を絞ります。
  • 視野角:真後ろの仲間を無視する(視野角を 270° 程度にする)と、群れの先頭が後ろに引っ張られず、流れる感じが増します。
  • GPU で数万匹:位置と速度をテクスチャやバッファに置き、コンピュートシェーダーで更新、インスタンシングで描画すれば、数万〜数十万匹を動かせます。

つまずきやすい点

  • パラメータの調整が難しい:3 つの重みと半径が相互に影響します。まず分離と結合のバランスで「適度な密度」を作り、整列で流れを作る順に調整すると迷いにくくなります。
  • 更新順序の偏り:同じ配列を読みながら書き換えると、先に更新された個体の新しい速度を後の個体が読むことになります。速度の計算と位置の更新を 2 段階に分けます(デモも同じ構成です)。
  • 境界での不自然な反射:壁で速度を反転させると群れが割れます。境界の手前から徐々に戻す力をかけます。

デモで試すこと

  1. 「分離」「整列」「結合」を 1 つずつ 0 にしてみてください。整列なしでは向きがばらばらに、結合なしでは群れが崩れて散らばります。
  2. 「近傍の半径」を小さくすると小さな群れに分かれ、大きくすると大きな 1 つの群れになります。黄色の 1 匹と、それが「見ている」水色の仲間の数に注目してください。
  3. 「捕食者を放つ」をオンにすると、群れが割れては合流を繰り返す、魚群らしい回避行動が現れます。

References

Spring-It-On ↗

A general reference for this subcategory.