TextMeshProのマテリアル


投稿日:2024年1月10日 | 最終更新日:2024年3月25日

概要

TextMeshProでは専用のシェーダーをもつマテリアルを使うことで、文字にテクスチャを適用したり、アウトラインやシャドウ、グローなどの様々なエフェクトをつけることができます。

デフォルトのマテリアル

フォントアセットの作成時に、サブアセットとしてデフォルトのマテリアルが自動作成されています。

各テキスト表示で使用するマテリアル

テキストが使用するマテリアルの設定は、コンポーネントの「MaterialPreset」から行います。

TexeMeshPro用のマテリアルの作り方

TexeMeshPro用のマテリアルは、フォントアセットに対応したマテリアルを作る必要があるため、少し特殊な作り方をします。

Textオブジェクトのインスペクターから作る

Text系オブジェクトのインスペクターウィンドウの最下段にあるマテリアル表示の、右上(または右クリック)のコンテキストメニューから「Create Material Preset」をすると、現在設定されているマテリアルを元に新しくマテリアルが作られ、それが自動的にコンポーネントに設定されます。
なお、Textが非表示だとマテリアル項目の表示がされない点に注意してください。

他のマテリアルを複製して作る

デフォルトのマテリアルや作成済みのマテリアルを複製することでも新たなマテリアルを作ることができます。
プロジェクトウィンドウで、元となるマテリアルを選択して複製するか、右クリックのコンテキストメニューから「Create Material Preset」としてください。

名前に注意

マテリアルの名前は、目的に応じた名前に変えるなどして整理しやすくしましょう。
名前を変える際には制約があり、「元のフォントアセットの名前をスペース区切りにした最初の部分」を含む必要があります。
たとえば、元のフォントアセットが「SampleFont SDF」だったら「SampleFont」が含まれる名前を付ける必要があります。

参考:フォントアセットの名前は「フォント名 SDF」のままでつけない

マテリアルの編集

マテリアルの各設定を編集することで、様々なエフェクトをつけることができます。
マテリアル自体のインスペクターから直接編集しても良いですし、コンポーネントの最下段のマテリアルの設定から編集することもできます。

ただし、マテリアルの内容を変更すると、そのマテリアルを使っているすべてのテキストの見た目が変わってしまうので注意してください。
これはコンポーネントから編集している場合も同じです。
編集しているのはコンポーネント固有の値ではなく、設定されたマテリアルそのものの値なので、そのマテリアルを使っている他の全てのテキストの見た目が変化します。
LegacyTextではアウトラインの太さなどをコンポーネントの値によって個別に調整できましたが、そういったやり方はできないということです。
新しいエフェクトをつけたい場合は、上記の手法でマテリアルを新しく作成し、その新しいマテリアルのほうの値を編集してください。

SDFシェーダー

使用するシェーダーを変えることで、使用する機能を増やしたり減らしたりできます。
マテリアルが使用するシェーダーは、マテリアルの「Shader」から変更することができます。
TextMeshProに対応するシェーダーは、シェーダー選択メニューの「TextMeshPro/」以下にあります。

TextMeshProは、符号付き距離フィールド (SDF) という技術を使ってテキスト描画をします。
SDF処理用のシェーダーが用意されているので、基本的にはそれを使用する必要があります。
SDFを使用したくない場合は、ビットマップ用のシェーダを使います(ここでは説明は省略します)

SDFシェーダーと対応機能一覧表

以下に、TextMeshProのシェーダーと、対応している機能を一覧表にまとめました。
「Local Lighting」はシーンのLightingに影響を受けない軽量な光沢処理です。
「Surface Lighting」は、シーンのLightingを反映しますが、描画負荷が高くなります。
また、TextMeshProのシェーダーには通常(デスクトップ)のバージョンとモバイルバージョンがあります。
モバイルバージョンは、処理が簡略化され一部使えない機能がありますが、負荷の軽い描画が可能です。
アウトラインやシャドウをつけるだけであれば、モバイル版が最速で表示できます。

シェーダー名 内容 Face Outline Underlay Local Lighting
Bevel、Bump Map、
Environment Map
Surface Lighting
Bevel、Bump Map、
Environment Map
Glow
Distance Field 基本となるシェーダー ×
Distance Field Overlay Distance Fieldとほぼ同じ。
シーン内の他のすべてのものの手前にレンダリングする。
×
Distance Field (Surface) テキストに、シーン内のライトによるラィティング効果を加えるためのもの。
FaceとOutlineに、Gloss(光沢)パラメーターが追加
Undelayは使用できない
注*URPやHDRP環境ではサーフェスシェーダーが使えないので使用不可。参考
× ×
Distance Field - Mobile 軽量なモバイル版。
Face、Outlineではテクスチャが使用できない。
ライト関係とGlowは使用不可
× × ×
Distance Field Overlay - Mobile Distance Field - Mobileとほぼ同じ。
シーン内の他のすべてのものの手前にレンダリングする
× × ×
Distance Field (Surface) - Mobile Surfaceのモバイル版。
ライト関係の設定はできないが、シーン内のラィティングの影響を受ける。
Underlayが使えなくなる
Glowが使用可能
× ×
Distance Field Masking - Mobile UIでソフトマスクが設定されているときに使用?
3.2以降が必須?

マテリアルの機能のリファレンス

Face

テキスト本体の見た目を制御します
モバイル版ではテクスチャ関連の設定はできません。

プロパティ 詳細 サンプル
Color 文字色
コンポーネントのColor設定と乗算されます。
Texture テクスチャを適用します。
コンポーネントの「UV Mapping」で、
張り付け方(1文字ごとにテクスチャを貼るか、行ごとに貼るかなど)の調整ができます。
  Tiling X/Y テクスチャのタイリング値。
テクスチャをタイリングするときに調整する。
  Offset X/Y テクスチャのUVオフセット値。
テクスチャの張り付け位置をずらす場合に使用する。
  Speed X/Y UVスクロールのスピード。
0より大きい値を設定すると、テクスチャをUVスクロールアニメーション表示する。
注:シーン ビューで確認するには「Always Refresh」を有効にしてください
Softness 文字のエッジをぼかします。
Outlineを設定している場合はOutlineごとぼかしがかかります。
Dilate 輪郭線の位置の増減値。主に、文字の太さを調整します。
負の値を指定すると文字が細くなり、正の値を指定すると文字が太くなります
Gloss シーン内のライトに対する光沢( 鏡面ハイライトの強弱)。Distance Field (Surface)のみ使用可能。
高く設定するほど、鏡面ハイライトが小さくなります。
ハイライトはSpceculerColorの設定や、シーン内のライトオブジェクトの位置や強さ設定によって変わります。

Outline

テキストにアウトラインを追加します。
モバイル版ではテクスチャ関連の設定はできません。

プロパティ 詳細 サンプル
Color アウトラインの色
Texture アウトライン専用のテクスチャを適用します。
アウトラインのColor値が乗算して適用されます。
コンポーネントの「UV Mapping」で張り付け方の調整ができます。
  Tiling X/Y テクスチャのタイリング値。
テクスチャをタイリングするときはこの値を増やす。
  Offset X/Y テクスチャのUVオフセット値。
テクスチャの張り付け位置をずらす場合に使用する。
  Speed X/Y UVスクロールのスピード。
0より大きい値を設定すると、テクスチャをUVスクロールアニメーション表示する。
注:シーン ビューで確認するには「Always Refresh」を有効にしてください
Thickness アウトラインの太さを調整します。値が大きいほど太くなります。
文字の輪郭の外側だけでなく、内側に向かってもアウトラインは太くなります
そのため「Face」の「Dilate」プロパティを合わせて調整する必要があります。
文字の太さを変えずに外側にのみアウトラインを表示したい場合は、「Dilate」と「Thickness」をおなじ値にしてください。
Gloss シーン内のライトに対する光沢( 鏡面ハイライトの強弱)。Distance Field (Surface)のみ使用可能。
高く設定するほど、鏡面ハイライトが小さくなります。
ハイライトはSpceculerColorの設定や、シーン内のライトオブジェクトの位置や強さ設定によって変わります。

Underlay

テキストの下(奥)におなじテキストを描画をします。主にシャドウの描画に利用します。
LegacyTextのOutlineやSahdowコンポーネントのイメージに近く使えます。
応用として、シャドウではなくアウトライン効果としても使えるので、Outlineと組み合わせて二重アウトラインを描画可能です。
Surface系のシェーダーでは使用不可能。

プロパティ  詳細  サンプル
Underlay Type アンダーレイのタイプを設定します。
  None アンダーレイを表示しない
  Normal テキストの下にアンダーレイを表示します。標準的なドロップシャドウ処理です。
Underlayはテキストの後ろに描いてシャドウ処理などをする

テキストを透明にして、Underlayを分かりやすく表示
  Inner Faceをマスク領域とした反転描画を、アンダーレイとして表示します。
テキスト切り抜きを通して見えるタイプのドロップシャドウが作成されます。
このタイプの表示をするには、Faceのアルファ値を1未満にして透明にする必要があります。

Innerはテキストをマスク領域とした反転描画
Faceを透明にしないと見えない
Normalと比較すると反転しているのがわかる。 
Color アンダーレイの色
Offset X/Y アンダーレイの表示位置のオフセット。
たとえば、影の位置や方向を調整するのに使用します。
Dilate アンダーレイの輪郭線の位置の増減値。主に、アンダーレイの太さを調整します。
負の値を指定すると細くなり、正の値を指定すると太くなります
Softness アンダーレイをぼかします。
0より大きい値を指定すると、アンダーレイをぼやけさせることができます。

Bevel

ベベル(斜面)はテキストの立体感を表現するために使用します。
基本的にはOutlineが設定されているテキストで使用し、Outlineに立体的な傾斜がかかったようにみえる明暗(陰とハイライト)をかけます。
Outlineのないテキストにも適用できますが、その場合はBevelがFace部分に対してかかるように、Widthを正の値で、Offsetを負の値にして数値を調整する必要があります。
明暗の付き方はその他のライト系の設定(Local LightingまたはSurface Lightingと、Bump MapとEnvironmental Map)によって変わります。

プロパティ 詳細 サンプル
*Faceと同じ色のOutlineに対してBevelをかけたもの
Type ベベルのタイプの設定。以下の二種から選択する。
  OuterBevel Face部分が浮き出ているような立体感を出す。
アウトラインに外側から内側に向かって盛り上がっているような明暗をつけます。
  InnerBevel Outline部分が盛り上がっているような立体感を出す。
アウトラインの外側からアウトラインの中央まで盛り上がり、
アウトラインの中央からテキストの内側に向かって盛り下がるような明暗をかけます
Outerタイプよりも勾配は急激になる。
Amount 盛り上げる部分の高さの差の量
高いほど急激に高さが変わるため、明暗が強くでます。

←低          高→
Offset ベベルをかける位置をずらすための値。
Outlineとは違う位置にベヘルをかけたり、Outlineなしでベベルをかけるために使用します。
負の値を設定すると内側にずれ、Face領域にはみだしてベヘルがかかります。
正の値を設定すると外側にずれます。
Offsetが異なるとベベルはかなり違ったものが生成されることになります。

←負          正→
Witdh ベベルの幅(太さ)を調整するための値。
0の場合、ベベルはOutlineと同じ幅にかかります。
負の値を設定することで細くなり、正の値を設定すると太くなります。
Offsetと合わせてベベルのかかる領域を調整します。

負のOffsetと合わせて数値を調整することで、
Face領域にかけるベベルの太さを調整できます。

Outlineなしでベベルをかける場合、
正の値を設定しOffsetも負の値にして調整します。
Roundess ベベルの傾斜に丸みを持たせます。
多くの場合、その効果は微妙な違いになります。
Clamp ベベルの高さが一定の高さに達したら終了させる数値を設定します。
0の場合はなにもしません。数値が大きくなるほど、ベベルが低い高さで終了します。
Typeが「Outer Bevel」の場合は、Outlineの途中でベベルが終了します。
Typeが「Inner Bevel」の場合は、Outlineの中央部分になる前に最高点に達するため、盛り上がっている部分が太くなります。

Local Lighting

シーン内のライトではない、ローカルなライトの設定。
対象のテキストのみに作用する疑似的なライトです。
Bevel、Bump Map、Environmental Mapと組み合わせて、テキストに明暗をかけるために使用します。

プロパティ 詳細 サンプル
Light Angle ライトの角度
単位はラジアンで、0~6.2832(2π)の範囲で設定します。
デフォルト値は3.1416(π)で上方向からライトがかかります。 
Specular Color 鏡面ハイライトの色。
ハイライトの色の設定になります。
Specular Power 鏡面ハイライトの光の強さ。
値を大きくすると光が強くなり、ハイライトがより明るく広くなります。

←低          高→
Reflectivity Power 反射のしにくさ。
「Environmental Map」の影響度です。値が大きいほど、環境マップを強く反映します
テキストの凹凸がライトに対してどの程度の角度であればどれくらい強く光を反射するかの度合い。
値が小さいほどどんな角度でも光が反射されやすくなり結果としてハイライトが強く広くなる。
値が大きいと垂直に近くないと反射されづらくなり結果としてハイライトが弱く狭くなる。

←低          高→
Diffuse Shadow ディフューズ(拡散)シャドウ。
全体的なシャドウのレベルを調整します。
デフォルトは0.5でかなり全体が暗くなっている点に注意。
0に設定すると影響はなくなり、値が大きいほど暗くなっていき、明暗がつきづらくなります。

 0     0.5(デフォルト)  1
Ambient Shadow アンビエント(環境)シャドウ。周囲の光レベルを調整します。
通常あまり影響を与えない微妙な効果で、強いBevelやBumpMapを使用している場合のみ効果が顕著に出ます。
1を設定すると影響はなくなり、1より小さく設定するとテキストの傾きに基づいて色が暗くなります。

 1     0.5(デフォルト)  0

Surface Lighting

Distance Field (Surface)シェーダーを使用する場合のライトの設定。
Surface系のシェーダーを使っている場合は、シーン内のライトの影響をうけます。
したがって、ライトの色や位置や角度、強さの設定などによって明暗も動いて変化します。

テキストのマテリアル側に設定できる項目は「Specular Color」のみです。
FaceやOutlineの「Gloss」パラメーターと連動して、テキストにハイライトがつきます。

プロパティ 詳細 サンプル
Specular Color 鏡面ハイライトの色の設定

補足 Mobileでは

Distance Field (Surface) - Mobileシェーダーも、シーン内のライトの影響をうけます。
ライトの設定項目はなく、FaceやOultlineのGlossパラメーターも使用できませんが、簡易的にテキストにシーンライトの効果をつけることができます。

Bump Map

テキストにBumpMapとして法線(ノーマル)マップのテクスチャを設定し、凸凹の質感を追加します。
石や木のデコボコした質感や、紙のザラザラした質感を表現したりするのに使用します。
Bevelが設定されている場合は、両方混ざった結果が表示されます。

プロパティ 詳細 サンプル
Texture 使用する法線マップテクスチャを選択します。
設定するテクスチャはインポート設定でTextureTypeが「Normal map」になっている必要があります。
Face Faceに適用するBumMapの強度。0の場合は何も適用されません。
Faceを1、Outlineを0にして
Faceのみに適用
Outline Outlineに適用するBumpMapの強度。0の場合は何も適用されません。
Faceを0、Outlineを1にして
Outlineのみに適用

Environment Map

Environment Map(環境マップ)は、周りの背景をテキストに写り込ませるために使用します。

プロパティ 詳細 サンプル
Face Color Faceに適用する環境マップに乗算する色。
黒に設定されていると、環境マップによる影響はなくなります。
Outline Color Outlineに適用する環境マップに乗算する色。
黒に設定されていると、環境マップによる影響はなくなります。
Texture 環境マップとして使用するテクスチャ。キューブマップである必要があります。
あらかじめ設定しておくほか、ランタイムで動的に生成したものを設定するようにプログラムすることも可能です。
Rotation 環境マップの回転設定のはずが、使用できない模様。(バグ?)
回転させるにはマテリアルプロパティの「_EnvMatrix」をプログラムから設定する必要がある模様。
Import Tmp Eamples Extras」で追加できるサンプルコードを参照。
Assets/TextMesh Pro/Examples & Extras/Scripts/EnvMapAnimator.cs
 設定した値で環境マップを回転させて適用します。
回転をアニメーションさせてエフェクトとして使用することもできます。

Glow

輪郭線にソフト処理つきの発光(グロー)表現をします。
FaceやOutlineの上(手前)に描画されますが、色を加算で処理するため背景となる色が暗いほうが目立ちます。(逆に真っ白なものの上では視認できなくなります)
(Surface)系のシェーダーで使用する場合、鏡面ハイライトなどのライティング処理も適用されます。
(Surface)以外のモバイル版では使用できません。

プロパティ 詳細 サンプル
Color グローの色。
加算合成されるためアルファ値が強度となります。
Offset グローの中心位置と輪郭線からのオフセット。
0の場合、FaceのDilateを適用した輪郭線に重なる。
正の値を指定すると、グローは輪郭の外側になります。
負の値を指定すると、テキストの中心に向かって移動します。
(FaceのDilateやOutlineのThicknessよりも微妙に大きい値が必要になる?単位が不明)
Inner グローの輪郭線から内側に向けての幅 
Outer グローの輪郭線から外側に向けての幅
Power 発光の強さ。値が大きいほど中心から離れた部分でも強く光り、値が小さいと弱くなる。
プログラム等でアニメーションすることで明滅アニメーションとしても使用可能。

Debug Settings

Debug Settingsで、詳細項目を確認・編集できます。
これは、シェーダーの不具合を調査、デバッグするためのものです。
シェーダーを開発する場合以外では基本的は触らないことが多いので、ドキュメントは省略します。

Paddingの与える影響

フォントアセットを作成したときに「SP/PD Ratio」という値が表示されますが、これは 「Sampling Point Size」に対する「Padding」の割合をパーセンテージで表示したものです。
(分子/分母で書くなら「PD/SP」が正しい表記なのでは?という気もしますが、TextMeshProではこう表記するようです)

このパーセンテージは、基本的には10%以上が推奨されています。
この数字によって各種エフェクトの太さや位置が決まります。

マテリアルの各エフェクトの設定値とPaddingの関係

TextMeshProで使用するSDF画像は、輪郭線からの距離データが収録されています。
「SP/PD Ratio」の比率を増やすほど、輪郭線から離れたところまで距離データが記録されます。

「SP/PD Ratio」0%    「SP/PD Ratio」10%      「SP/PD Ratio」20%

このPaddingによる広がりの部分(上記画像のボヤっとした部分)が、マテリアルでエフェクトを設定する場合にアウトラインの太さなどの基準値になります。

たとえば、Outline表示設定を全く同じ「FaceのDilateと、OutlineのThicknessを両方0.5」とした場合、
「SP/PD Ratio」の違いによって、アウトラインの表示結果は大きく変わります。

  0%      10%       20%

Outline以外のエフェクトでも同じことで、「SP/PD Ratio」の値によってエフェクトの見た目の位置や大きさが変わってきます。
FaceのDilateや、OutlineのThicknessをはじめとして、多くの値が「Paddingで広がった部分」(上記画像のボヤっとした部分)の大きさを基準として、エフェクトをかけるからです。

「SP/PD Ratio」はマテリアルエフェクトの表示範囲の限界値でもある

マテリアルでエフェクトを設定する場合に、SDFデータがないところまでアウトラインなどのエフェクトを広げようとしてもデータがない所は扱えないため、それ以上大きなエフェクトは作れません。
数値の設定上は範囲外のところまでエフェクトを広げることができますが、実際の表示はカットされるか下記のアーティファクトとなります。
アウトラインだけならそこまで大きいものは必要ないことが多いのですが、アウトラインに加えてシャドウやグローなどをかけようとすると、わりとすぐエフェクト範囲の限界が来てしまいます。
そのためなるべく大きいほうが自由度は高いのですが、あまり大きくしすぎると必要になる画像サイズも増えてしまうというトレードオフ関係があります。

「SP/PD Ratio」をなるべく統一する

上記のように、「SP/PD Ratio」の値によって、マテリアルの設定に対してのエフェクトの大きさが変わってきます。
これは、フォントアセットを作り直したときに「SP/PD Ratio」が変わってしまうとテキストの見た目も変化してしまうという意味でもあります。
「Padding」と「Sampling Point Size」は、ピクセル数なので整数で定義されています。
少数値を設定して微調整するということはできませんので、現実的には「Padding」と「Sampling Point Size」は途中からは変えないようにする必要がでてきます。

フォールバックでは注意が必要

また、フォールバックを使っているときはさらに注意が必要で、全てのフォントアセットで「SP/PD Ratio」を統一する必要があります。
そうしないとサブメッシュのマテリアルが自動生成された場合に、一部の文字だけアウトラインが細かったり太かったりするなどの不具合がでてきます。
例えば、「SP/PD Ratio」が大きい英語フォントのフォールバックに、「SP/PD Ratio」が小さい日本語フォントを設定すると、このようにアウトラインの太さが不ぞろいになってしまいます。

参考:Feature Request - Better Fallback system for missing characters - Unity Forum

アーティファクト(ゴミのようなもの)の問題

マテリアルのエフェクトの大きさや位置に関わる数値を極端に設定すると、文字の周りにアーティファクトが表示される場合があります。
アーティファクトは中間生成物という意味ですが、この場合は不正に描画されてしまうゴミのような描画物です。

テキストサイズが小さい場合には、背後に灰色の四角系が描画されてしまうこともあります。

アーティファクトは、フォントアトラス画像内の隣接する文字のデータがはみ出て見えてしまうことで発生します。
そのため、アーティファクトを回避するには、フォントを作成するときに「Padding」の値を多めにして、アトラス画像内での文字同士の間隔を広くするのが基本になります。
基本的には「SP/PD Ratio」が10%以上になるように、Paddingの値を調整しましょう。(つまりPointSizeの1/10以上)
ただし、上記の「マテリアルの各エフェクトの設定値とPaddingの関係」にあるように、Paddingの値を変えるとエフェクトの大きさが変わる点に注意してください。

Pdadingを10%以上にしていても発生してしまうことがあるので、その際はエフェクトのほうを小さく設定して下さい。
アーティファクトはアウトラインを最大値かそれ以上に太く設定したりなどして、極端な値を設定すると起きやすくなります。
なので、大きなエフェクトを表示する場合は、限界少し手前で収めるなどして、値を調整してください。
また、<b>タグや、コンポーネントのFontStyle設定で「B」(太字)を使っているときには、アーティファクト問題が起きやすいようなので、その点も注意して下さい。
これは、「Font Weights」の「疑似的な」太字と斜体を使用する際に、太さの補正をかけているせいだと思われます。

参考リンク:TextMesh Pro - Text Mesh Pro - テキストの周囲の「ボックス」の不要な効果 / バグ - Unity フォーラム