テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】TextMeshProのアウトラインは、uGUIのと比べてとても良い

f:id:tsubaki_t1:20170920045940j:plain

前回に続きTextMeshPro。今回はアウトラインについてです。

TextMeshProのアウトライン

f:id:tsubaki_t1:20170920054157j:plain

まず本題です。

TextMeshProは、シェーダー側でアウトラインを実現しています。元々SDFでフォントを実現する仕組みなので、その辺りは割と簡単に出来ているのかなと。

アウトラインの設定方法

アウトラインの設定は、マテリアルのOutlineのThicknessから行います。

この項目を増やすと、文字にアウトラインが付きます。

f:id:tsubaki_t1:20170920054618j:plain

ただ実際に行えば分かる通り、このアウトラインは内側に進みます。太いフォントでもThicknessの値が大きい場合、文字のシルエットが変化してしまうかもしれません。

f:id:tsubaki_t1:20170920054847j:plain

内側滲む対策は、文字を広げる事で回避

この内側に滲む問題の手っ取り早い対策は、文字を広げてしまうことです。

FaceのDilateの値をOutlineのThicknessと同じくらいの値を設定してやると、内側への滲みと文字の広がりが丁度よい感じに相殺されます。

f:id:tsubaki_t1:20170920055053j:plain

f:id:tsubaki_t1:20170920055222j:plain

 

アウトラインの色々なエフェクトを試してみる

TextMeshProのアウトラインは色々と出来ます。

例えば、Faceの色を透明にして中抜きアウトラインを表現したり、SoftnessやGrowを活用してボケた感じのアウトラインを作ったり、ぶっといアウトラインを用意したり云々。

f:id:tsubaki_t1:20170920060118j:plain

ただ、ぶっといアウトラインを表現する場合、アウトラインも含めて1文字である事に注意が必要です。アウトラインが隣の文字を侵食します。

 Spacingで文字の間を詰めると、こんな表現になるかもしれません。

f:id:tsubaki_t1:20170920060451j:plain

 

ポリゴン数も増えず、オーバードローも無い。レイアウトにも優しい

TextMeshProで良い点の一つは、uGUIの文字ずらしアウトライン系と異なり、ポリゴンが増えず、オーバードローがない点です。

実際にUI Profilerで確認しても、ポリゴンは通常のフォントと同じ1文字6点のみ。またアウトラインの有無にかかわらず同程度の表現であることが確認出来ます。

f:id:tsubaki_t1:20170920055742j:plain

f:id:tsubaki_t1:20170920055755j:plain

特にポリゴンが少ないので、レイアウト変更したときのコストは割安です。

 

uGUIのアウトライン手法と問題について

一方uGUIのアウトラインはどうでしょう。

uGUIのアウトライン表現は、上下左右にズラシた文字を利用したアウトラインです。この手法では、上下左右に少しずつズラした文字+中央の文字でアウトラインを表現しています。

http://tsubakit1.sakura.ne.jp/images/201406210055390f9.gif

細い文字はアウトラインを太くしにくい問題

まず起こるのが、細い文字はアウトラインを太くしにくい…という事です。

文字をズラして表示する関係上、細い文字…例えばLightと名前が付くようなフォントでアウトラインを表現しようとすると、十分な太さに移動する前に、はみ出てしまいます。

f:id:tsubaki_t1:20170920051007j:plain

ただまぁ、これは実は強引に解決することが出来なくはないです。

uGUIのアウトラインは「UIを利用してアウトラインを作る」ので、小さめのアウトラインを連打することである程度の太さのアウトラインを実現出来ます。

f:id:tsubaki_t1:20170920051509j:plain

色を変えると分かりやすいかもしれません。

f:id:tsubaki_t1:20170920051727j:plain

しかし、このアプローチは場合によっては地獄を呼びます。

文字を表現するために沢山の描画が発生する問題

アウトラインでもう一つ問題になるのがオーバードローです。

単純にアウトラインの文字を一つ書くには、エッジ用に上下左右で4、中央で1の5枚描画する必要が出てきます。

この辺りUI Profilerで確認すると、とても光っているのが確認できます。

白ければ白いほど、ヤバイです。

f:id:tsubaki_t1:20170920052138j:plain

まぁオーバードロー自体は実はそれ程問題にならないかもしれません。オーバードローは描画面積が広ければ問題になりますが、所詮文字です。多分範囲は限定的でしょう。

 

どちらかと言えば、気になるのはもう一つ。ポリゴン数です。ワイヤー表示すると、中々にエグい表示が確認出来ます。

f:id:tsubaki_t1:20170920052457j:plain

特にUIがちょくちょく更新される場合、かつ文字数が多いような場合は、レイアウトコストやら云々が結構なコストになるかもしれません。

具体的にはコレくらい。

f:id:tsubaki_t1:20170920052927j:plain

ソレはソレとして

まぁ実際問題、文字が背景に溶け込まないようにする事が目的の場合、アウトラインは薄いの一つで問題ないかもしれないので、そこまで問題にはならないかもしれません。

またダイナミックフォントが使えるのは、かなり強力なuGUIのメリットです。使いやすい物をケースバイケースで使い分けるのが良いかなと。

関連

tsubakit1.hateblo.jp

indie-du.com

tsubakit1.hateblo.jp

www.youtube.com

【Unity】TextMeshProのMaterial Presetを増やす方法

f:id:tsubaki_t1:20170919223923g:plain

久しぶりの更新は、TextMeshProのMaterial Presetを増やす方法について。

TextMeshProは文字を表現するのに便利な表現

f:id:tsubaki_t1:20170919231014j:plain

https://www.assetstore.unity3d.com/jp/#!/content/84126

 

TextMeshProは、フォントを表現する際に便利な機能です。

(uGUIと比較して)高度なレイアウトシステム、(uGUIと比較して)多機能な表現、(uGUIと比較して)良いパフォーマンス、(uGUIと比較して)手間が多いのが特徴です。

www.slideshare.net

 

最も特徴的なのはズームしてもフォントが綺麗…という所です。

uGUIはゲーム画面(シーンビューの解像度ではない)の画面解像度からフォントの解像度を生成します。そのままなら余り問題は無いのですが、フォントをスケールすると、フォントがボケて見えてしまうかもしれません。TextMeshProはこの辺りを工夫して描画しているため、ズームしても滲みません(但し、事前準備が必要)。

この機能から、自由にカメラの移動が可能なVRや、文字演出等の表現に向いてます

f:id:tsubaki_t1:20170919232644g:plain

また単純にアウトラインがuGUIより綺麗です。

 

 

Material Presetでエフェクトのあるマテリアルを選択

TextMesh Proでフォントにアウトラインやノーマル、サーフェースを設定する場合、マテリアルの設定を変更します。パラメータをシェーダーに流し込み、表現自体はシェーダー(GPU側)で行う事で、CPU側の負荷を下げています。

お陰で、文字の表面をスクロールしても、CPU負荷は0です。

f:id:tsubaki_t1:20170919225138g:plain

 

このマテリアルの差し替えは、Material Presetを使用します

ただし、FontAssetを生成した直後は設定可能なマテリアルは一種類しか無い為、複数のエフェクトを設定する事が出来ません。

複数のテキストを用意した際、Material Presetの値は共有されているため、一つのテキストのエフェクトを変更したつもりでも他のテキストもエフェクトがかかってしまいます

f:id:tsubaki_t1:20170919225353j:plain

ここでFontAssetを増やすのはナンセンスなので、マテリアルを増やしてMaterialPresetで複数のエフェクトを持てるように設定します。

 

Material PresetはCreate Preset Materialで増やす

肝心のマテリアルを増やす方法ですが、Create Preset Materialのメニューを使用します。

FontAssetのマテリアルを選択中、Inspectorでマテリアルのコンテキストメニューを表示でCreate Preset Materialが選択出来ます。この方法で増やしたマテリアルはTextMeshProのMaterial Preset一覧に表示されます。

f:id:tsubaki_t1:20170919230409j:plain

f:id:tsubaki_t1:20170919230550j:plain

f:id:tsubaki_t1:20170919230628g:plain

また、この方法で生成したマテリアルはDeplicate(複製)で量産しても、Material Preset一覧に表示されます。

f:id:tsubaki_t1:20170919230811j:plain

これで色々なエフェクトが使い放題

関連

www.slideshare.net

qiita.com

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

雑記

そして7日後、SNSは再開された で思うことがあったので、月初めに思い切ってスマホからTwitterを消した所、Twitter依存がかなり減った。

ただ、同時にブログ更新意欲がガッツリ減った。どうやら自分のブログ更新モチベーションはTwitterの反応とかその辺りから来てるっぽい。むむむ

【Unity】シェーダーで3Dモデルのアニメーションを行う Animation Texture Baker

f:id:tsubaki_t1:20170903220052g:plain

今回はシェーダーで3Dモデルのアニメーションを行います。

シェーダーで3Dモデルのアニメーションを行う

最近流行りのアプローチの一つに、シェーダーでモデルのアニメーションを行う…という物があります。

例えば各頂点のXYZ等の情報をテクスチャのRGBAに格納し、それの読み取り位置を時間でズラす事により、キャラクターのアニメーションを実現する…的な感じです。

f:id:tsubaki_t1:20170903221135j:plain

 

この辺りはUnite 2017のインスタンシング公演で少し触れた他、最近のUniteでは割と何度も取り上げられている項目だと記憶しています。

www.slideshare.net

とりあえずやってみる

作ってみようと思いましたが、既に良い感じのがあったのでソレを使います。

github.com

Animation Texture Bakerの導入

Animation Texture Bakerを導入します。

詳しく確認していませんが、AnimationBakerがあれば多分OKです。

f:id:tsubaki_t1:20170903222051j:plain

テクスチャでアニメーションするモデルの導入

次にモデルとアニメーションを入れます。

この機能はスライドや動画で思想を把握する限り、頂点数やアニメーションの長さに限界があります。また、メッシュは出来れば単一であることが望ましいです。

また Animation Texture Bakerの制限で、Animation(レガシー)のものしか使用できません。

 

ので、それを実現出来るモデルを引っ張ってきます。

例えば http://u3d.as/9WKとか

f:id:tsubaki_t1:20170903221528j:plain

インポートしたアニメーションのタイプはLegacyに設定します。

f:id:tsubaki_t1:20170903222130j:plain

アニメーションの変換

シーンにAnimation付きのモデルを配置し、Animation Texture Bakerをセット、

再生ボタンを押してゲームを再生します。

f:id:tsubaki_t1:20170903222336j:plain

これでBaked Animation Texフォルダに、シェーダーでアニメーションを行うPrefabが生成されます。

このPrefabをシーンに配置すれば、CPUに頼らずアニメーションしてくれます。

f:id:tsubaki_t1:20170903222557j:plain

f:id:tsubaki_t1:20170903223511j:plain

アニメーションをループさせたいならばマテリアルのLoopにチェックを入れたり、時間をズラシたいならDelta Time、速度を変更したいならAnimation Lengthの値を少しいじればOKです。

f:id:tsubaki_t1:20170903222736j:plain

GPU Instancingに対応してみる

初期状態はGPU Instancingには対応していないので、Instancingに対応的な事を軽くしてみます。

Shaderに#pragma multi_compile_instancingとか UNITY_VERTEX_INPUT_INSTANCE_IDとか、UNITY_SETUP_INSTANCE_ID(v);を追加して、物によってはUNITY_INSTANCING_CBUFFER_STARTとかも追加、

f:id:tsubaki_t1:20170903223858j:plain

f:id:tsubaki_t1:20170903225018j:plain

後はGraphics.DrawMeshInstancedで描画します。

これで1023体のゾンビを描画しても、殆どCPU負荷無く描画できています。

Unityが動作する最近のモバイル(MetalやOpenGLES3やVulkan)はインスタンシングが使えるので、割と動きます。*1

f:id:tsubaki_t1:20170903224959j:plain

 Graphics.DrawMeshInstancedIndirectで座標計算をCompute Shaderにやらせれば、CPU負荷は殆ど消せるかもしれません。対応面倒なんでやってませんが。

関連

 

www.youtube.com

 

 
 

*1:現在のAndroidの最低バージョンは4.1なので、OpenGLES3はそこそこ動きます。4.3未満が切れれば…

【Unity】Animator Parameterというウィンドウ

f:id:tsubaki_t1:20170829214417j:plain

何の役に立つのかよく分からんシリーズ

 

紹介する為に色々調べてみたけど、結局用途や使い道がよく分からん…という事でお蔵入りしてた項目も少しずつ紹介していこうと思います。

Animator Parameterというウィンドウ

Animatorの項目にAnimator Parameterというウィンドウがひっそりと存在しています。

これは端的に言えばAnimatorのパラメータを映すだけのウィンドウです。

f:id:tsubaki_t1:20170829214853j:plain

用途は簡単、そうAnimatorのパラメータを映すだけのウィンドウなので、Animatorのパラメータを映す事が出来ます。

f:id:tsubaki_t1:20170829214949j:plain

Animator Parameterウィンドウは何の役に立つのか

役に立つ…といえば、Animatorのパラメータを映す事が…ry

は置いといて、実際問題はどうなんでしょう。

 

Animatorで十分じゃね?

まずパラメータを表示する…という機能においては、Animatorウィンドウで十分です。この項目を独立させる必要性はありません。

Animatorはウィンドウを割と潰せるので、スペースが云々という言い訳も無用です。

f:id:tsubaki_t1:20170829215309j:plain

そうだ、Animatorを観測するのに使えるんじゃね…ん?ロックは何処だ?

ではロックすればどうでしょう。Animator Parameterが各Animatorのパラメータのみを表示し、状況を把握するのに役に立ちそうです。

 

さて、ロックは何処でしょう?

f:id:tsubaki_t1:20170829215613j:plain

答えは「無い」です。

 

Animator Parameterの表示する項目は常にAnimatorウィンドウと同じ内容を表示します。例えAnimatorをロックしたとしても、同じ内容です。

ソレ以前にAnimator Parameterはウィンドウを一つしか用意出来ないので、Animator Parameterを複数使ってパラメータを観測…みたいな事は出来ません。

 

強いて言うなら…

Animatorのウィンドウを別ディスプレイに表示して、パラメータだけを観測したいとか、そういった用途でしょうか…?うーん。

 

で、Animator Parameterはどうやって活用するの?

あ…AnimatorのParameterを見るのに使えるヨ…

 

感想

理解出来ると化ける機能もあるけど、

…用途不明な機能は意外と多い

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp