GameProgrammar's Night

ゲームプログラム系の覚え書き

DistanceFieldTextureのDistance

 さらにツールの実装を見つけまして、ソースを読んだ結果、DistanceFieldTextureに書き込む距離に関して勘違いしていたことに気づきました。修正した所、オレオレツールでもSDFツールと同等のクオリティが出るようになりました。オレオレツールのソースも更新しました。
 その過程で距離について、少々考えたので、それについてのメモ

DistanceFieldTexutreにおける距離とは?

 自分が一番勘違いしていた所であり、これさえわかればDistanceFieldTexture生成自体は簡単です。
 DistanceFieldの距離は、-1~1の範囲を取る符号付き距離です。文字や図形の境界線を0として、内側方向にプラス、外側方向にマイナスを取る距離になります。

f:id:katze_7514:20130706193000p:plain

 内側とは文字や図形の形として描画されるべき部分です。オレオレツールでは真っ白(RGB(255,255,255))を内側として扱っています。
 DistanceFieldTextureには、この-1~1の距離を0~255に対応させて格納します。境界位置は127.5になるため、シェーダー上では0.5の色が境界線として描画されるべき位置となります。

 実際には127.5という値は入れられないので、127か128ということになるのですが、これをどっちに寄せるかでも微妙に描画結果が変わります。オレオレツールでは127に寄せています。

距離1をどの程度にするのか

 単にアルファテストでくっきり描画するだけなら、境界線となる0.5の位置さえ取れれば良いので、結構短くても大丈夫です。
 応用として縁取りやグロウなど文字装飾を入れるならば、距離は装飾の範囲情報として使いますので、どの程度装飾したいかによります。例えば、縁取りの場合、距離0.3~0.5の範囲を縁にするなどのように使いますので、1となる距離が長いほど太く縁取ることができるようになります。

 f:id:katze_7514:20130706194625p:plain

 極端にした例ですが同じ距離0.3~0.5でも、距離1の長さの取り方でかなり変わります。
 オレオレツールの場合、「係数 × 元画像の幅高さ大きい方 / 出力するDistanceFieldTextureの幅高さ大きい方」にしてます。ようは、DistanceFieldTexture上での距離1を係数にして、それを元画像上での距離に変換、変換した値を使って元画像上で距離を計算しています。