Skip to content

第05回 TextMeshPro と SDF

前回: 第04回 半透明表現と UV アニメーション / 次回: 第06回 ノイズ

TextMeshPro から SDF の考え方に触れる

文字の輪郭は どう描かれているのか

身近で意外な 利用例

前回の振り返り

半透明と UV アニメーションを扱いました

  • 第04回では AlphaAlpha Clip、マスクを使い、 透明度を制御する方法を学びました
  • Time を使って UV をずらし、テクスチャーが流れる表現を作りました
  • UV 計算をさらに拡張して、フリップブックアニメーションにも触れました
  • 今回は TextMeshPro の文字描画から 形の輪郭を制御する SDF の仕組みに触れます

今回の授業で扱うこと

文字表現から図形の変形へ

  • TextMeshPro が文字をきれいに描ける理由
  • 形の境界からの距離を持つデータ、SDF の紹介
  • SDF としきい値で 表示範囲や輪郭の太さを制御する考え方
  • 距離を計算した図形を合成し 形を変化させる考え方
  • フォントや UI 表現で SDF が使われる理由
  • 文字表現と図形モーフィングにつながる SDF の基本

今回の授業内容

フォント描画、距離関数、輪郭制御

  • TextMeshPro とフォント描画
  • SDF の考え方
  • しきい値による切り抜き
  • 輪郭とぼかしの制御
  • SDF 図形の合成とモーフィング
  • 授業内課題

TextMeshPro とは

Unity の高品質なテキスト表示機能

  • TextMeshPro (TMP)は Unity で使われる文字表示用のコンポーネントです
  • 元はサードパーティ製のアセットでしたが現在は Unity に統合されています
  • UI ラベル、ボタン、スコア表示、会話文などゲーム中の文字表示に広く使われます
  • リッチテキストや細かなスタイル設定にも対応しており 現在の Unity の標準的な文字表示機能です
  • 「TextMesh ProがUnityに参加 2017年3月20日」 https://unity.com/ja/blog/games/textmesh-pro-joins-unity

TMP の特徴

高品質な文字表示と柔軟な装飾

TMP の SDF 文字装飾の例
TMPでの文字装飾の例 アウトラインや影、太さの調整が可能なばかりか 疑似的なライティング表現も可能

  • 拡大縮小しても輪郭が崩れづらい 高品質な文字表示を実現しています
  • アウトライン、影、太さ、ぼかしなど 文字の見た目を細かく調整できます
  • SDF の距離情報を使うことで TMP は輪郭や装飾を安定して制御しています

SDF を使用しない文字画像の弱点

拡大すると輪郭が崩れる

TMP とビットマップフォントの比較
上がTMP、下がビットマップフォント ビットマップフォントは拡大するとぼやける

  • 文字をただのビットマップ画像として持つと 拡大した際にピクセルが目立つようになり 輪郭が崩れてしまいます
  • 輪郭を保つために高解像度のフォント画像を 用意すると今度はデータ量が増えてしまいます
  • UI では画面解像度や表示サイズが変わるため 文字の輪郭を安定して描く仕組みが必要です

文字の輪郭を保つための技術

境界までの距離をテクスチャーに保存する

  • 色や透明度を扱う通常のテクスチャー画像と異なり、 SDF では各ピクセルに文字の境界までの符号付き距離を保存します
  • 描画時は得られた距離値を補間し、しきい値で内側と外側を判定します 透明度ではなく距離を扱うため、低解像度でも輪郭を再構成しやすくなります
  • Improved Alpha-Tested Magnification for Vector Textures and Special Effects Chris Green, Valve, 2007年
    https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf

TextMeshPro の Font Asset

文字の形をアトラスに保存する

TextMeshPro のフォントアトラス例
アトラス化された文字 境界からの距離を表すグラデーションが入っている

  • TextMeshPro の Font Asset には 使用する文字を1枚にまとめた フォントアトラスが入っています
  • 各ピクセルには文字の輪郭までの距離が グレースケール値として保存されています
  • シェーダーはその距離をしきい値で判定し 文字本体、ぼかし、アウトライン等の 見え方を調整します

TMP の文字修飾

SDF の値は様々に応用可能

TMPの文字修飾の例
TMPの文字修飾の例 アウトラインや影、太さの調整が可能なばかりか 疑似的なライティング表現も可能

  • Face Color で文字本体の色を変える
  • Outline で文字の外側に縁取りを付ける
  • Underlay で影のような表現を加える
  • Dilate や Softness で太さやにじみを調整する
  • これらは全て SDF の距離情報を活用して 実現されています

SDF の紹介

Signed Distance Field

SDF 可視化図
灰色が元の形、赤が内側、緑が外側 円の大きさが境界までの距離を表す 出典: Drummyfish, Wikimedia Commons, CC0

  • SDF は Signed Distance Field の略です
  • ある点が形の境界からどれだけ離れているかを 数値として扱うことで形状を表現する方法です
  • Signed は符号付きという意味です 形の内側と外側を正負の値で区別できます
  • シェーダーでは、この距離の値を使って 形の表示、輪郭、ぼかしを表現できます

SDF と通常の画像との違い

色ではなく距離を扱う

星形のSDFテクスチャー
しきい値で復元した星形
SDF画像と復元の例 境界の距離を使うことで拡大しても輪郭が保たれる

  • 通常のテクスチャーは ピクセルごとの色を保存します
  • SDF テクスチャーは形の境界からの距離を グレースケール値として保存します
  • ぼやけた画像に見えますが 値をしきい値で判定することで くっきりした形を復元できます

SDF 表示の考え方

距離の値を透明度に変換する

Shader Graph の Step によるSDF表示例
Shader Graph での SDF 表示の例 距離をしきい値で判定して採用している

text
distance = Sample Texture 2D(SDF Texture, UV).r

alpha = distance > threshold ? 1 : 0

Base Color = Color
Alpha      = alpha
  • 実際の Shader Graph では Sample Texture 2DStepBranch などで 近い処理を作れます

よりなめらかな境界を得る

Smoothstep を使う

Shader Graph の Smoothstep によるSDF表示例
Smoothstepの効果の例 しきい値の前後で値がなめらかに変化するため 境界のジャギーが目立たなくなる

text
distance = Sample Texture 2D(SDF Texture, UV).r

alpha = smoothstep(threshold - softness,
                   threshold + softness,
                   distance)

Base Color = Color
Alpha      = alpha
  • Step での表示は境界がはっきりしすぎて ジャギーが目立つことがあります
  • Smoothstep を使えばしきい値の前後で 値をなめらかに補間できます

アウトラインを作る

2つのしきい値を使う

Shader Graph で外周と内側をしきい値で分ける例
外周用の表示と内周用の表示を組み合わせて アウトラインを作っている例 Gradientを使えばより細かな調整が可能

  • 本体より少し外側まで表示する範囲を作り アウトラインの色を乗せれば 文字の周りに縁取りを付けることができます
  • フォントや UI アイコンでは 視認性を上げるためによく使われます
  • TextMeshPro の文字修飾は この考え方を基本にして実装されています

SDF 図形を計算する

テクスチャーがなくても形を作れる

Shader Graph の Circle ノードによる SDF の例
Shader Graph に実装されている SDF 関数の例 計算で SDF の円形状を作成している

  • SDF は画像として用意するだけでなく UV や座標から計算することもできます
  • 円のような単純な形の距離を計算すれば シェーダー内で図形を作れます
  • 図形そのものではなく距離を扱うため 合成や変形を数式で扱いやすくなります

SDF 図形を合成する

Min と Max で合成方法が変わる

SDFのMinとMax合成例
SDF 図形の合成の例 Min は共通部分、Max は和集合になる

  • SDF の距離値を比較すると 複数の形を1つの距離場として扱えます
  • 内側を正の値として扱う場合 Minimum は両方の内側だけを残します
  • Maximum はどちらかの内側を残します

SDF でモーフィングする

距離を混ぜて形を変える

Shader Graph で SDF を Lerp してモーフィングする例
二つの SDF 画像を補間してのモーフィングの例 Blend の値を変えると円と星型の間で形が変化する

  • 2つの SDF 図形を用意して 距離の値を Lerp で補間すれば 形をなめらかに変化させることができます
  • 補間量を時間やパラメーターで変えるだけで 簡単にモーフィング表現を作ることができます

実習

SDF の操作を体験する

数値で画像を作れるのは ちょっと不思議な 感覚かもだ

実習1

円の SDF を作る

  1. URP Unlit Shader Graph を作成する
  2. UV から中心座標との差を求める
  3. Length で中心からの距離を計算する
  4. 半径から距離を引いて円の SDF にする
  5. Smoothstep で円として表示する

実習2

SDF 画像を補間して変形する

  1. 2つの SDF 画像を用意する
  2. サンプリングした距離値を Lerp で混ぜる
  3. FloatMorph プロパティを追加する
  4. Morph を動かして形の変化を確認する
  5. Time を使って自動で変化させる
  6. 境界の硬さも調整できるようにする

授業内課題

2つの SDF を使って 形が変化するマテリアルを 作成してください

距離を混ぜると 形を変えられます

課題の条件

以下を満たしてください

  • 2つの SDF の距離値を扱っている
  • Maximum で図形を合成できる
  • Morph で2つの形を補間できる
  • Softness で境界の硬さを調整できる
  • 本体色をマテリアル側から変更できる
  • スクリーンショットまたは動画で変化が確認できる

この回の到達目標

  • SDF が境界からの距離を持つデータだと説明できる
  • しきい値で形を切り抜く考え方を説明できる
  • Smoothstep で境界の柔らかさを調整できる
  • SDF がフォントや UI 表現に使われる理由を説明できる
  • SDF 図形を合成・補間して形を変えられる

今回のまとめ

形状を距離で表現する SDF の基本

  • SDF は形の境界からの距離を持つデータです
  • 距離情報をしきい値で判定して形を切り抜くことができます
  • Smoothstep を使えば輪郭の硬さを調整できるなど SDF は様々な表現に応用できます
  • SDF はフォント描画だけでなく図形の合成やモーフィングにも役立ちます

おつかれさまでした!

次回予告 第06回 ノイズ

絵が描けない人の 救世主