見出し画像

TextMesh Proを印字風に加工する【後編】

こんにちは、カキレモンです。後編なので一応前回の続きですが、必ずしも前編を読む必要はありません。

UnityのTextMesh Proをいじって遊びます。こんな感じのを作ります。

前回に引き続き参考:

今回のコード:

What is 印字風

もともと手書き風・毛筆風に加工する方法を模索していたんですが、できそうな方向に妥協した結果できたものです。

印刷物やスタンプなどのかすれたりにじんだりした字、あるいはそれらが経年劣化で剥げた状態のようなものをイメージしています。文学チックな雰囲気に合わせたりホラーっぽいテイストを醸したりできるかもしれません。

このサイトを参考に、方針はだいたいこんな感じです。

①輪郭を凸凹にする(+線の一部を欠けさせる)
②ランダムなインクはねを追加する

シェーダー用のノイズ関数

輪郭の変形やインクはねにランダムな要素を使うのでノイズ関数の出番です。Shader Graphだと便利なノイズ関数があらかじめ用意されていますが、今回は手書きコードなので自分で定義する必要があります。何でもいいですが、パーリンノイズを使いました。ノイズ関数に関しては参考になるサイトがたくさんあるのでそちらをご参照ください。

やっぱりここが一番分かりやすいと思います。なおサンプルコードはGLSLで書かれているのでUnityで使うためには適宜読み替え(GLSL→HLSL)が必要です。

あるいは、最初からUnityシェーダ向けに解説しているこちらのサイトも分かりやすいかもしれません。

ちなみに普通にパーリンノイズを書くと値域が制限されるらしい(出典)ので、(0,1)の範囲で使いたい場合はやや注意が必要です。

step1. 文字の形にノイズを加える

前回は、dの値を大きくすると文字が太くなることを確認しました。ということで、dの変化を局所的にすれば輪郭に凹凸を加えられそうです。とりあえず、パーリンノイズをそのまま足してみます。(perlinNoiseの具体的な実装は本記事で扱いません。)

- 編集
half d = tex2D(_MainTex, input.texcoord0.xy).a;

- 追加
half perlin = perlinNoise(input.texcoord0.xy * 100);
d = (d + perlin * 0.25) * input.param.x

half4 c = input.faceColor * saturate(d - input.param.w);

前回言及したとおり手を加える部分はPixShaderの最初のあたりです。(1行目にあったinput.param.xの位置を変えているので注意)

こうなります。↓

スクリーンショット 2021-11-02 220934 (2)

これはこれで味があるとも言えますが、まだ「極太」感が強すぎますね。smoothstepを使ってノイズの「間引き」をします。

half d = tex2D(_MainTex, input.texcoord0.xy).a;

half perlin = perlinNoise(input.texcoord0.xy * 100);

- 追加
perlin = smoothstep(0.4, 1, perlin);

d = (d + p * 0.25) * input.param.x

half4 c = input.faceColor * saturate(d - input.param.w);

スクリーンショット 2021-11-02 221156 (2)

ちょっとそれっぽくなりました。数値を変えて色々試してみてください。ちなみに今はノイズの値が正なので膨らむだけですが、値の範囲を変えて負の値も含まれるようにすれば文字の一部を欠けさせることができます。

step2. インクの飛び散りを表現する

パーリンノイズはどうしても変化がなめらかなので、smoothstepを使っても粒の1つ1つが大きくなりがちです。そこで、ノイズの値をべき乗して変化を大きくします。それ以外は先程と同様のロジックです。

half d = tex2D(_MainTex, input.texcoord0.xy).a;

half perlin = perlinNoise(input.texcoord0.xy * 100);
perlin = smoothstep(0.4, 1, perlin);

-追加
half splash = perlinNoise(input.texcoord0.xy * 200);
splash = smoothstep(0.3, 1, pow(splash, 3));

d = (d + perlin * 0.25 + splash * 5) * input.param.x

half4 c = input.faceColor * saturate(d - input.param.w);

スクリーンショット 2021-11-24 172349

インクの飛び散りが表現できました。

step3. パラメータをシェーダープロパティにする

​それだけですが、ちょっと詰まったのでメモ。元々のTextMesh Proのシェーダーはカスタムエディタで表示されるため、追加したプロパティをインスペクタからいじることができません。そこで、末尾にあるカスタムエディタの指定は削除しておく必要があります。

        ...
        ENDCG
	}
}

-この行をコメントアウト
//CustomEditor "TMPro.EditorUtilities.TMP_SDFShaderGUI"
}

できたもの

さらに細かい修正を加えて、最終的にはこんな感じになりました。フォントはデフォルトのLiberationSansのままですが、結構違う雰囲気になったんじゃないでしょうか?最終的なコードはGitHubをご確認ください。

スクリーンショット 2021-11-24 181328 (4)

おわりに

はい、お疲れさまでした。今回は長かったので大変です。うまくまとめきれず大味な記事になってしまいました。

ちなみに冒頭のツイートではAnimationを使ってマテリアルのプロパティをいじっています。マテリアルのプロパティを直接Animationで操作することはできないため、いったん別スクリプトを経由する必要があります。

TextMesh Pro、実はちゃんと使ったことはほとんどないんですが触ってみると便利そうですね。でもカスタムシェーダーを書くのはもうやりたくないです。ということで今回も終わりです。

それでは、また。

この記事が気に入ったらサポートをしてみませんか?