This explanation is currently available in Japanese.
ひとことで
空間のあらゆる点に「いちばん近い表面までの距離」を割り当て、形の内側では符号を負にした関数(または、その値を並べたデータ)です。値が 0 になる場所がちょうど形の表面になります。ポリゴンのように面を並べて形を表すのではなく、「どこでも距離を答えられる関数」として形を表すのが特徴です。
ゲームでの使いどころ
- 形そのものを描く:レイマーチングで SDF を直接描く(デモシーン、『Dreams』や『Claybook』のような粘土・造形ゲーム)。
- ソフトシャドウとアンビエントオクルージョン:Unreal Engine の Mesh Distance Fields は、メッシュから焼いた SDF で遠くまで柔らかい影や遮蔽を計算します。
- 当たり判定・パーティクルの衝突:「その点は内側か」「表面まであと何 m か」「どちら向きに押し出せばよいか」が 1 回の評価で分かるので、大量の粒子を複雑な地形に当てるのに便利です(GPU パーティクルの衝突など)。
- 文字や UI:文字の形を SDF で持つと、拡大してもぼやけず、縁取りや光彩も安く描けます(MSDF)。
- 地形の編集:ボクセル地形で掘る・盛るといった編集を、距離の値の足し引きで表します。
しくみ
基本形の SDF は短い式で書けます。球なら中心からの距離から半径を引くだけです。
箱は、各軸で表面からどれだけはみ出しているかを使って、外側では角までの距離、内側では最も近い面までの距離(負)を返します。
SDF の最も大切な性質は、値 を半径とする球の中には表面が 1 つもないことです。この保証があるので、
- その距離だけ安全に進める(スフィアトレーシング)
- 形の組み合わせを最小値・最大値で表せる(CSG)
- 値の変化の向き(勾配)がそのまま表面の法線になる(距離場の勾配法線)
といった便利な操作が成り立ちます。また、距離 から一定値 を引く()だけで、形を だけ太らせて角を丸められます。
実装のポイント
- 関数で持つか、テクスチャで持つか:少数の基本形なら式で評価し、任意のメッシュは 3D テクスチャに距離を焼き込みます(ボリュームテクスチャの各ボクセルに距離を保存)。焼き込んだ SDF は解像度の分だけ細部が失われます。
- 移動・回転は逆変換で:形を動かすときは、形ではなく評価する点 のほうを逆向きに動かします。回転や平行移動は距離を変えないので、SDF の性質が保たれます。拡大縮小は、座標を で割ってから評価し、結果に を掛け戻します。
- 符号の規約:内側を負にするのが一般的ですが、ツールやエンジンによっては逆のこともあります。テクスチャに保存するときは、0.5 を表面として 0〜1 に写すことが多いです。
つまずきやすい点
- 「距離らしい値」と本当の距離は違う:形を組み合わせたり変形したりすると、値が正確な距離でなくなることがあります。符号(内外)は正しくても距離が過大になると、スフィアトレーシングで表面を突き抜けます。距離が実際より小さめ(保守的)なら安全ですが、処理は遅くなります。
- 外側の最小値は正確でも、内側は正確とは限らない:複数の形の最小値は、外側では正確な距離ですが、形が重なった内側では正確ではありません。
- 焼き込み SDF の解像度:細い部品(ワイヤーや薄い板)は、ボクセルより細いと消えてしまいます。
デモで試すこと
- 「断面の高さ」を上下させると、形を水平に切った断面で、内側(青)と外側(オレンジ)の距離の縞が変わります。白い線が距離 0、つまり形の輪郭です。
- 緑の探査点をドラッグしてください。表示される半透明の球(半径 = 距離)は、必ずどれかの形にちょうど接し、中には何も入りません。この性質が SDF のすべての応用の土台です。
- 等距離線は、形から離れるほど角が取れて丸くなります。箱の角の外側では、距離は角の 1 点までの距離になるためです。