【Unity Shader】原神の顔の影の処理の考察

#はじめに
原神の顔の目の下の影の出方が気になったのでやり方を考えてみました

<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/b419cf6b-ccbb-95ae-f9eb-674d23f639ee.png">

URPでトゥーンシェーダー作成中...

#環境
Unity2020.2
URP
AmplyfyShaderEditor
↑ ShaderGraphはノードが少なく、自作するのが面倒なので...

## 影の出方は3Dモデルの法線ベクトルとライトのベクトルので決まります

法線とは？
分かりやすく言うと面と垂直な線です。
<img width="200" alt="代替テキスト" src="http://maya.indyzone.jp/wp-content/uploads/2017/02/1-8-3.jpg">
※なお直接法線をいじることも可能なのであくまでもイメージです
ライトのベクトルはライトが向いている方向ですね

## ハーフランバートを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/c05ee63c-f17d-1d01-34f0-c1f9fbc2983f.png)
ハーフランバートは
法線ベクトルとライトのベクトルの内積(ランバート)
を0.5をかけて0.5を足したもの
<img width="200"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/28ef0025-f622-e67c-28f6-2dcd15af678e.png">
ライトの向きと逆側が黒くなっていますね
これは影の出やすさを意味するものとなります

## 簡単なトゥーンシェーダを作成
先ほどのハーフランバート(0～1)に適当な値でStep(2値化)します
その値をもとに基本色と影色を塗り分けするだけで完成です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/ecc1fbe9-3275-3a0c-40fc-42a3c3042c28.png)
<img width="200"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/21ccac9d-2f17-fc7f-080b-365d1c708443.png">
基本的にはこれだけで、色の部分をテクスチャに置き換えるだけでシェーダーは完成です。

## 法線編集で影を操作

3Dモデルの法線情報を直接いじることにより、モデルの凹凸に関係なく
影の出やすさを調整することができます

先ほどのシェーダーで原神のモナちゃんをそのまま表示させてみます
[モナちゃん原神公式配布リンク](https://genshin.mihoyo.com/ja/news/detail/5885)

<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/94b9054b-6528-e67b-5186-6a21547b4640.png">

そのままだと顔の凹凸がそのまま影に影響し汚い感じになります...
ゲームで使用しているデータとは異なるようです...

適当に目と口の部分に凹凸がないモデルを作成し、法線を転写させます

<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/6a2eedc5-4082-a8ed-23b5-f31a9d64e72c.png">
※適当です
ひとまず変な影は出なくなりましたね

#本題

PCゲーム版
<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/b419cf6b-ccbb-95ae-f9eb-674d23f639ee.png">

今回用意したデータ
<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/a9679da6-01c5-ec4a-db7b-3f13f7d3a851.png">

目の下が影じゃないという点で違いがあります

法線編集で有名なこちらでは
[GUILTY GEAR Xrd開発スタッフが送るアニメ調キャラモデリングTIPS](https://www.slideshare.net/ASW_Yokohama/guilty-gear-xrdtips-124324946)

ポリゴンごとに法線を変更しているようですが、今回の3Dモデルにはそこにポリゴンはありません

なので今回はテクスチャデータをもとに同様なことを行います。
##テクスチャベースで法線編集
目の下を黒く塗るようなテクスチャを用意します
<img width="400"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/616492ad-c6c6-12e7-460d-3074e29a17a6.png">
※わかりやすいようにUVを表示しています

この黒くなった部分を指定方向に法線を曲げるような処理を追加します
ここで今回曲げる方向はGUILTY GEARの記事を参考にするとローカルX軸の反転を行いたいので

マスクの部分のみ法線方向に
Vector3(-1,1,1)を乗算します
<img width="600"  src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/7199a2c1-2d88-2367-47af-43198454e9fa.png>

※厳密にはここでWorldNormalはワールド空間なので一度ローカル空間に戻してから乗算する必要があります
<img width="600"  src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/ee925ac8-ebff-aa58-d85a-d5302f599808.png>


マスク部分のX成分が左右逆になっていることがわかります
<img width="300"  src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/b8ded24d-19f7-2f4b-51a5-34ee6853b56b.png>

こちらの法線データをもとに先ほど作成したトゥーンシェーダーを表示させます。

ここで問題が発生します
<img width="300"  src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/b3006bd1-4c46-5515-22d9-164468a612de.png>
X軸の反転だと反対側に影ができてしまいます
GUILTY GEARではこのような表現でしたが原神では影はできません

なので先ほどの法線をいじる前のハーフランバートと比較し
値が大きい方のみ採用する形をとります
<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/a9679da6-01c5-ec4a-db7b-3f13f7d3a851.png">
こちらの影の部分のみ適用のイメージです

<img width="300"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/709623e4-31e8-f5cf-88cf-a8d0b8181904.png">
ゲーム本編と同様に表示させることができました

今回X軸のみ反転させましたが
影の出やすさはZ軸も関係しますので
いい感じになる値を探します

##完成

<img width="600"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/9146ec96-af05-a559-43ee-8e6a697f2028.gif">

それっぽくなった気がします！
もう少し調整が必要そうですが30分クオリティー...

#まとめ
目の下の影は好みがありそうですね
上からライトが照らされるような時のみ表示するとかいろいろできそうです。

#最後に
改めてモナちゃんはが可愛いことが分かりました...
<img width="600"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308905/360afbdd-87df-ee06-a71a-80883f2f998a.png">