Distance fields & implicit shapes

Smooth Union / Smooth Minimum

スムーズユニオン

距離場を滑らかに合成して接合部を丸くつなぐ。合成後の値は厳密な距離とは限らない。

4 / 10

Interactive demo

Preparing the demo…

Smooth Union / Smooth Minimum

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

This explanation is currently available in Japanese.

ひとことで

2 つの距離場を合わせるとき、普通の最小値(min)の代わりに滑らかな最小値(smooth min)を使って、接合部に肉を盛ったように丸くつなぐ方法です。粘土やスライム、溶けた金属、生き物の体のように、パーツが自然につながった有機的な形を作れます。

ゲームでの使いどころ

  • 粘土・スライム・液体:プレイヤーが粘土をこねる造形ゲーム、スライムの敵、合体する水滴。
  • キャラクターや生き物の造形:胴体・腕・頭を別々の形で作り、継ぎ目を丸くつなげる(SDF で作るキャラクター)。
  • 地形と物体のなじませ:岩や建物の根元を地面と滑らかにつなぎ、置いただけに見えないようにする。デモの「床ともなめらかにつなぐ」がこれです。
  • VFX:溶けて合体する魔法の塊、伸び縮みするエネルギー体。

しくみ

よく使われる多項式の smooth min(Inigo Quilez)は次の形です。

h=clamp ⁣(12+dB−dA2k, 0, 1),d=mix(dB, dA, h)−k h (1−h)h = \text{clamp}\!\left(\frac{1}{2} + \frac{d_B - d_A}{2k},\ 0,\ 1\right),\qquad d = \text{mix}(d_B,\ d_A,\ h) - k\,h\,(1-h)
  • 2 つの距離の差が kk より大きい(片方がはっきり近い)ときは、hh が 0 か 1 になり、普通の min と同じ結果になります。
  • 差が kk 以内の範囲(2 つの形の境目付近)だけで 2 つの距離を混ぜ、さらに k h(1−h)k\,h(1-h) を引いて値を小さくします。値が小さくなるということは「表面がそこまで張り出す」ということなので、接合部に肉が盛られます。
  • 盛られる量は h=0.5h = 0.5 のとき最大で k/4k/4 です。

同じ hh を色や材質の混合にも使うと、デモのように接合部で色もなめらかに移り変わります。

実装のポイント

  • k の単位は距離:kk は「どれくらい離れたところから融合し始めるか」を表す長さです。形の大きさに対して 1〜3 割程度から試すと扱いやすいです。
  • 順番に依存する:3 つ以上の形を順に smooth min でつなぐと、つなぐ順番によって結果がわずかに変わります。気になる場合は、すべての距離を指数関数で合算する smooth min(log-sum-exp)を使う方法もあります。
  • smooth max で滑らかな差・交差:−smin(−a,−b,k)-\text{smin}(-a, -b, k) とすれば、くり抜いた穴の縁を丸めることもできます。

つまずきやすい点

  • 結果は厳密な距離ではない:接合部では値が本当の距離より小さくなったり大きくなったりします。等距離線の間隔が場所によって変わるので、スフィアトレーシングでは歩幅を少し縮めて安全側に倒します。
  • 離れていても影響する:kk を大きくすると、見た目には離れている形同士もふくらんでくっつきます。遠くの形同士が意図せず引き寄せられて見えることがあります。
  • メタボールとの違い:見た目は似ていますが、メタボールは影響の値を足し合わせる仕組みで、距離場の合成とは定義が違います。smooth min は 2 つずつ、距離として合成します。

デモで試すこと

  1. 「合成の幅 k」を 0 にすると普通の min になり、塊の境目に鋭い谷ができます。少しずつ増やすと、谷が埋まって滑らかにつながります。
  2. 右下のグラフは、2 つの距離の差(横軸)に対する合成結果です。普通の min は折れ曲がりますが、smooth min は差が k 以内の範囲で丸くなっています。
  3. 「床ともなめらかにつなぐ」をオンにすると、スライムの根元が床に溶け込むように広がります。
  4. 「断面の距離を表示」で、接合部の等距離線の間隔が詰まっている(厳密な距離ではない)ことを確かめてください。

References

Unreal Engine Mesh Distance Fields ↗

A general reference for this subcategory.