Distance fields & implicit shapes

Domain Deformation / Twist / Bend

座標変形

評価する座標をねじり、形を曲げる。

7 / 10

Interactive demo

Preparing the demo…

Domain Deformation / Twist / Bend

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

This explanation is currently available in Japanese.

ひとことで

形そのものは変えずに、形を評価する座標のほうを変形させることで、ねじる・曲げる・揺らすといった変形を加える手法です。距離場で表した形なら、「この点は元の形のどこに当たるか」という写像を 1 つ挟むだけで、頂点を 1 つも持たずに形を自由に変形できます。

d(p)=f元の形( T(p) )d(\mathbf{p}) = f_{\text{元の形}}\big(\,T(\mathbf{p})\,\big)

ゲームでの使いどころ

  • ねじれた建造物・魔法の柱:塔や柱をねじって、ファンタジーや SF らしい造形にする。
  • 曲がった橋・アーチ・トンネル:まっすぐな部品を曲げて、カーブした構造物を作る。
  • ぷるぷる揺れるもの:ゼリー、スライム、脈打つ肉塊、爆発前に膨らむ物体。
  • VFX:渦に吸い込まれる、波打つ、溶けて垂れるといった演出。

しくみ

変形 TT は「変形後の空間の点 p\mathbf{p} を、変形前の形のローカル座標に戻す」写像です。

ねじり(Twist):高さ yy に比例した角度だけ、xzxz 平面で点を回します。

θ=k y,T(p)=(cos⁡θ x−sin⁡θ z,  y,  sin⁡θ x+cos⁡θ z)\theta = k\,y,\qquad T(\mathbf{p}) = \big(\cos\theta\,x - \sin\theta\,z,\ \ y,\ \ \sin\theta\,x + \cos\theta\,z\big)

曲げ(Bend):横位置 xx に比例した角度で xyxy 平面を回すと、まっすぐな板が弓なりになります。

揺れ(Wobble):時間と高さに応じた正弦波で座標をずらすと、形が震えて見えます。

表面の模様も変形後の座標 T(p)T(\mathbf{p}) で描けば、模様ごと空間が歪むので、変形の様子がよく分かります(デモの格子模様)。

実装のポイント

  • 歩幅を縮める:変形は空間を引き伸ばしたり縮めたりするので、結果の値は正確な距離ではなくなります。変形の「引き伸ばし率の上限」(リプシッツ定数)LL が分かれば、距離を LL で割る(歩幅に 1/L1/L を掛ける)ことで安全にスフィアトレーシングできます。ねじりなら、半径 rr の位置での引き伸ばし率は 1+(kr)2\sqrt{1 + (k r)^2} です。
  • 回転・平行移動は安全:剛体変換(回転と平行移動)は距離を変えないので、補正は不要です。一様な拡大縮小 ss は、座標を ss で割って評価し、結果に ss を掛けます。
  • メッシュの頂点変位との違い:頂点変位は頂点を動かすので、頂点の細かさで変形の滑らかさが決まります。座標変形は画素ごとに評価されるので、どれだけ強く曲げても角ばりません。

つまずきやすい点

  • 踏み越えによる穴やちぎれ:強く変形すると距離が過大になり、光線が表面を突き抜けて穴やちぎれが出ます。デモで「歩幅を縮めて安全に進む」をオフにし、強さを上げると確認できます。
  • 影や遮蔽も同じ距離場を使う:影の計算でも距離を使うので、変形が強いと影に筋やむらが出ることがあります。
  • 法線の差分幅:強く変形した部分では、法線を求める差分の幅を小さめにしないと、細部の陰影がぼやけます。

デモで試すこと

  1. 「ねじり」では、形はただの箱です。表面の格子模様が斜めに流れていることから、空間ごとねじれていることが分かります。変形前の輪郭(灰色の線)と比べてください。
  2. 「曲げ」では、まっすぐな板がアーチ状に曲がります。ゲームのアーチ橋やトンネルを、まっすぐな部品から作れます。
  3. 「揺れ」は時間で座標を揺らしたゼリーです。形のデータは一切動いていません。
  4. 「歩幅を縮めて安全に進む」をオフにし、「強さを自動で変える」をオフにして強さを最大にすると、表面に穴やちぎれが出ます。

References

Unreal Engine Mesh Distance Fields ↗

A general reference for this subcategory.