ひとことで
物体の中に種点をばらまき、各種点に一番近い領域(ボロノイ領域)ごとに物体を切り分けて破片にする方法です。ボロノイ領域は必ず凸な多面体になるので、物理エンジンでそのまま剛体として扱えます。種点を衝撃の中心の近くに集めれば、中心ほど細かく、外側ほど大きく割れる、それらしい割れ方になります。
ゲームでの使いどころ
- 壊れる壁・柱・床:銃撃や爆発で壁に穴が開き、破片が飛ぶ。
- ガラス・氷・陶器:割れる窓や花瓶。ガラスは衝撃点から放射状に種点を並べると、ひびの入り方らしくなる。
- プリフラクチャー:割れ方を前もって作っておき(事前破砕)、壊れた瞬間に 1 枚の物体を破片の集まりに差し替える。実行時の計算がほぼいらないので、多くのゲームで使われる(Unreal の Chaos、Houdini の Voronoi Fracture など)。
- 岩の自動生成:大きな岩を割って、形のばらばらな石をたくさん作る。
しくみ
種点 のボロノイ領域は、「ほかのどの種点より に近い点」の集まりです。
と から等しい距離の点は、2 点を結ぶ線分の垂直二等分面の上にあります。つまり は、「 側の半空間」をすべての について重ねたもの(共通部分)です。
- 元の物体(ここでは箱)の多面体から始めます。
- ほかの種点 ごとに、法線 の平面で多面体を切り、 側だけを残します。
- 面を平面で切るには、各面の多角形をサザーランド・ホッジマン法で切り、切り口にできた点を集めて新しい面(割れ口)にします。
遠い種点との二等分面は領域に届かないので、近い順に調べ、「領域のいちばん遠い点までの距離」が「種点までの距離の半分」より小さくなったら打ち切れます。
実装のポイント
- 割れ口に別の素材:切り口の面に印を付けて、外側の面とは別のマテリアル(石の中身、ガラスの断面)にすると、割れた感じが強く出ます。
- 凹んだ物体:ボロノイ領域は凸ですが、元の物体が凹んでいる場合(L 字の壁など)は、凸な部分に分けてから割るか、メッシュのブーリアン演算で切り取ります。
- 全部を飛ばさない:衝撃の弱い破片は元の場所に残すと、穴の開いた壁になります。破片どうしを「接着」しておき、一定以上の力で外れるようにする方法もあります。
- 破片の後始末:破片が増えすぎると重くなるので、小さな破片は時間とともに消す、オブジェクトプールで使い回す、などの工夫をします。
つまずきやすい点
- 規則正しすぎる割れ方:種点を一様にばらまくと、どこも同じ大きさの破片になり、不自然です。衝撃点の近くに集めたり、ひびの方向に伸ばしたりします。
- 極端に小さい破片:種点が近すぎると、とても小さい破片ができ、物理が不安定になります。種点の間隔に下限を設けます(ポアソンディスク分布など)。
- 切り口の点の並び:切り口の点を角度順に並べ忘れると、面がねじれて描かれます。平面の法線の周りで反時計回りに並べます。
デモで試すこと
- 壁をクリックすると、その場所を撃ちます。当たった場所の周りだけが細かく砕けて飛び、外側は壁に残って穴が開きます。
- 「分解表示」を動かすと、割れる前の切り分け方(ボロノイ領域)が見えます。当たった場所の近くほど破片が小さいことを確かめてください。
- 「当たった場所への集中」を 0 にすると、どこも同じくらいの大きさの破片になります。
- 「壁に残す破片」を 0 にすると、すべての破片が崩れ落ちます。「素材」をガラスにすると、透けた破片と明るい割れ口になります。