ひとことで
箱・球・円柱のような単純な形を、和(くっつける)・差(くり抜く)・交差(共通部分だけ残す)で組み合わせて複雑な形を作る方法です。符号付き距離場で形を表していると、これらの操作は距離の最小値と最大値だけで書けてしまいます。
ゲームでの使いどころ
- レベルの組み立て:Quake や Unreal のブラシ(BSP)エディタは、箱を足したり引いたりして部屋や通路を作る CSG の考え方で作られていました。
- 破壊・掘削:壁に弾痕や穴を開ける、地面を掘る、トンネルを開ける。距離場の地形なら、球を差し引くだけで形が変わります。
- 造形ゲーム・プロシージャルモデル:『Dreams』や『Claybook』のように、プレイヤーが形を足し引きして造形する。
- レベル内のギミック:扉の開口部、窓、ドーナツ状の足場などを、簡単な形の組み合わせで作る。
しくみ
距離場で考えると、各操作は次のように理解できます。
- 和(min):どちらかの形に近ければその距離。どちらかの内側(負)なら結果も内側。
- 交差(max):両方の内側にあるときだけ負になる。遠いほうの距離を取るので、外側の値は「近すぎる」ことはない。
- 差(max と符号反転): は「B の外側を内側とみなした形」です。それと A の交差が「A から B を引いた形」になります。削られてできた新しい面は B の表面なので、デモでは B の色で塗られます。
操作を木構造(CSG 木)に組み合わせれば、デモの機械部品のように「箱と球の交差から、3 本の円柱を引く」といった形も 1 つの式で表せます。
メッシュの CSG との違い:ポリゴンメッシュ同士のブール演算は、面同士の交線を求めて切り貼りする難しい計算で、数値誤差で穴が開くこともあります。距離場なら min と max だけなので確実で、形を動かしながらリアルタイムに組み替えることもできます。
実装のポイント
- 色や材質の割り当て:min や max でどちらの値が選ばれたかを覚えておけば、面ごとに材質を変えられます(差の面を焼け焦げた色にする、など)。
- ゲームロジック側の対応:見た目の穴に合わせて当たり判定も変える必要があります。距離場で当たり判定をしていれば同じ式を使えますが、物理エンジンのメッシュ形状を使う場合は、形を作り直すか、マーチングキューブなどでメッシュ化します。
- 多数の穴:穴の数だけ距離の評価が増えます。数が多い場合は、穴を空間ハッシュで管理して近くのものだけ評価したり、ボクセルに焼き込んだりします。
つまずきやすい点
- 差と交差の結果は厳密な距離ではない:max を取った結果は、内側・角の近くで正確な距離より小さく(保守的に)なることがあります。描画には問題ありませんが、距離の値そのものを使う効果(ソフトシャドウの柔らかさなど)はわずかにずれます。
- 薄い壁の突き抜け:差で壁を薄く削った部分は、スフィアトレーシングの許容誤差より薄いと穴が開いて見えることがあります。
- 角が鋭すぎる:min と max は角をそのまま残すので、機械的な形には向きますが、有機的な形にはスムーズユニオンが向いています。
デモで試すこと
- 「和」「差」「交差」を切り替え、B(球)が動くにつれて形がどう変わるかを見てください。線で表示された元の箱と球との関係が分かります。
- 「差」では、削られた面が球の形(赤)になっていることを確認してください。
- 「CSG 木(部品)」では、箱 ∩ 球 − 3 本の円柱という 1 つの式で、機械部品のような形ができています。
- 「壊せる壁」で壁をクリックすると、その位置の球が差し引かれて穴が開きます。メッシュを作り直さずに、何度でも削れます。