Unityのジャギり影の原因と回避策

# 前置き
Unityをインストールし、空のプロジェクトを立ち上げ
お気に入りのモデルをシーンに配置したとき、
こんな経験はないだろうか

![unitychan_shadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/463731cc-0dfe-cde9-7456-34f7b1f8928a.png)

「「「影なんかジャギってない？？」」」

今回はこの影のジャギりの話をします

# 前提
Unity : 2020.3.33f1

# 影を作る技法とその問題点
Unityで影を描画するには
「光源から見て最も近いオブジェクトまでの距離」をマッピングし（デプスシャドウマップ）
カメラから見たときに対象と光源の距離が上記より大きければ影が落ちている
という技法を用いています（デプスシャドウ技法）
（光源からの距離）≠（光源から見て最も近いオブジェクトまでの距離）なら影が落ちる、というロジックです

![depth_shadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/baba69e7-7d82-4ef6-c70b-754f3e4212cc.png)

この技法だと光源が遠いと影の情報が少なく、影にジャギりが起こってしまいます
これが [透視エイリアシング](https://docs.unity3d.com/ja/current/Manual/shadow-cascades.html) です
※Directional Lightだと距離関係なく起きます

![DepthShadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/feab33f1-14c1-3aec-a878-9fb2be729728.png)

![ジャギり_PointLight.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/dcb3eeb1-ef66-6fb9-7729-0acdbbcaeae4.gif)
↑↑ライトが遠のくにつれてジャギりが大きくなっていく↑↑


## ジャギりの解消方法
これを解消する方法がいくつか考案されています
・デプスシャドウマップの解像度を上げる
・ソフトシャドウ処理を行う
・カメラからの距離でシャドウカスケードを行う

### デプスシャドウマップの解像度を上げる
LightingのShadowのResolutionで変更できます

![lighting_shadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/50e1aef7-28f4-d818-e1c0-6409cedaa961.png)

当然ですが描画負荷が上がるので注意です

### ソフトシャドウ処理を行う
影の輪郭にはほかにもShadow Typeという設定があり、
輪郭がくっきりする「Hard Shadow」と輪郭がぼやける「Soft Shadow」があります

![unitychan_shadow_soft_shadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/d57dab7f-5bdc-989f-7aef-149377fb4cbd.png)

デプスシャドウマップの解像度を上げるよりは気軽に使える上に現実の影に近くなりますが
現実の影とはロジックが違うので細かいバグが起こる可能性があります

### カメラからの距離でシャドウカスケードを行う
デプスシャドウマップの解像度が問題ならば
近景用と遠景用でデプスシャドウマップを分けてしまうという技法もあります

カメラからの距離でデプスシャドウマップを複数枚用意し、距離に応じて読み分けます
この技術のことをシャドウカスケード（Shadow Cascade）と呼びます

![ShadowCascade.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/ec8656e7-e7f6-5878-52e9-9ca7612c0304.png)

![ShadowCascade.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/eb06ef80-ff53-852c-c03f-f8abeb01f885.gif)

被写体との距離で影が切り替わっています

# 描画コストを減らしたい
上記はすべて描画コストがかかってしまいます
どこかをコストアップすれば、どこかをコストダウンしなければならないのが世の常です

今度は逆に「ジャギりを出さないで描画コストを抑える方法」をまとめました

・Shadow Distanceを狭める
・ShadowをテクスチャにBakeする

## Shadow Distanceを狭める
Unityでは落ち影が見える範囲を指定できます
落ち影が見えくなると計算がスキップされるため軽量化され、カスケードよりも処理が軽減されます

しかし影が急に消えるので非常に目立ちます
これは影を事前に計算して焼き付けておくBaked Shadowなどを行って和らげます

## 影を事前に計算してBaked Shadowにする
地形や建物など、動的に動かない物体の影はRealtimeに計算する必要がありません
こういったStaticな物体には影を事前に計算してテクスチャに焼きつけることで効率化できます

これであればどんなに離れても計算処理に影響しませんし
焼きつけたテクスチャの解像度次第で綺麗な影にしあがります

Baked Shadowを含めたBaked Lightingについては
今後の記事で紹介します

# Quality設定 について
影やライティング処理は端末のスペックによって設定を変える必要があります
UnityではProject Settings > Quality でVery Low～Ultraなど端末のスペックごとにライティング設定を切り替えれます

今回話したShadow周りの設定もここに含まれているので
是非一度いじって遊んでください

![unity_shadow_cascade_setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/2e3c5a0d-4baa-71a1-097b-db2827de103b.png)

# 感想
Unity触って初期のころから感じてた影のジャギりですが
調べてみると意外と簡単な理由だったことが分かりました

また同時に影の処理が重く難しいこともわかりました

Unityでは様々な機能を提供してくれているので
しっかり設定して臨場感ある演出をしていきたいです

ここまで読んでいただきありがとうございました
そのうちBaked Lightingについてもまとめます

# 余談
デプスシャドウマップ技法の問題であるジャギりを克服する手法はいくつか考案されています
詳しくはこちらなどの記事を参照ください

https://news.mynavi.jp/article/graphics-24/

# 参考

https://docs.unity3d.com/ja/2018.1/Manual/ShadowOverview.html

https://unity-chan.com/

© Unity Technologies Japan/UCL