【Unity】リアルタイムシャドウをちゃんと理解して影を正しく描画する

Unityでリアルタイムシャドウをちゃんと理解して影を正しく描画する方法をまとめました。

Unity2018.4.0

影をOFFにする

まず影をOFFにしてみます。
あるライトが作る影だけをOFFにしたい場合、LightコンポーネントのShadow TypeをNo Shadowsにします。

f:id:halya_11:20190616231701p:plain

プロジェクト全体で影を使わない場合は以下の手順で設定します。

  1. Edit > Project Settings > Quality
  2. ShadowsグループののShadowsドロップダウンを選択
  3. Disble Shadowsを選択する

f:id:halya_11:20190616231800p:plain

これで影が適用されなくなります。

ハードシャドウ・ソフトシャドウ

くっきりした影をハードシャドウといいます。

f:id:halya_11:20190616230950p:plain

これに対しやわらかい影をソフトシャドウといいます。

f:id:halya_11:20190616231014p:plain

ソフトシャドウのほうが現実の影にも近く見栄えが良いですが、処理負荷が高くなる特徴があります。
これらの設定は以下の手順で切り替えます。

  1. Edit > Project Settings > Quality
  2. ShadowsグループののShadowsドロップダウンを選択
  3. ハードを使う場合はHard Shadows Only、ソフトを使う場合はHard And Soft Shadowsを選ぶ

f:id:halya_11:20190616231342p:plain

ここまでがプロジェクト全体の設定です。
ここからさらに、ライト毎の設定をすることができます。

  1. LightコンポーネントのShadow Typeを選択する
  2. Hard ShadowsかSoft Shadowsを選択する

f:id:halya_11:20190616231503p:plain

これでハード/ソフトな影が描画できます。

シャドウマップの解像度を上げてジャギを軽減する

ハードシャドウはジャギが発生しがちです。

f:id:halya_11:20190616232116p:plain

これを軽減するにはシャドウマップの解像度を上げるのが有効です。
解像度は以下の手順で上げることができます。

  1. Edit > Project Settings > Quality
  2. ShadowsグループのShadow Resolutionドロップダウンを選択
  3. 今より高い設定値を選択する

また、解像度はLightごとに設定することもできます。

f:id:halya_11:20190617002210p:plain

これを適切に設定することでジャギりが軽減されます。

f:id:halya_11:20190616232320p:plain

ただシャドウマップの解像度を上げるということは、
シャドウマップに書き込みを行う際にフラグメントシェーダが回る回数が増大し、
GPUの処理負荷が増えるということになるはずなので注意が必要です。

Shadow Distanceでシャドウマップに映す範囲を決める

シャドウマップに描画する範囲はShadow Distanceで設定できます。

  1. Edit > Project Settings > Quality
  2. ShadowsグループのShadow Distanceの値を変更する

この値を小さくすると狭い範囲をシャドウマップに描画するので、
影は綺麗になりますが遠くの方は影が表示されなくなります。

f:id:halya_11:20190616235145p:plain

反対にこの値を大きくすると広い範囲をシャドウマップに描画するので、
遠くまで影は描画されるものの影は粗くなっていきます。

f:id:halya_11:20190617000057p:plain

Close Fitでシャドウマップに映す範囲を自動調整する

さて影の設定にはShadow Projectionという項目があります。
デフォルトはStable Fitになっています。

f:id:halya_11:20190617000204p:plain

これをClose Fitに変更すると、シャドウマップの描画範囲が自動的に調整されます。
カメラで映している範囲が狭ければシャドウマップへの描画範囲も狭くなり、影がきれいになります。

tsubakit1.hateblo.jp

便利な機能ですが、シャドウエッジスイミングという、カメラやライトが動くと影がちらつく特性を持っています。

f:id:halya_11:20190617001249g:plain

そのため使える場面は限定されそうです。

バイアスを調整してシャドウアクネを防ぐ

シャドウマップの解像度が低いと、シャドウアクネと呼ばれる縞模様が生じることがあります。

f:id:halya_11:20190617003215p:plain

これを防ぐためには、LightのShadow Type > Realtime ShadowsのBiasとNormal Biasの値を大きくします。

f:id:halya_11:20190617003453p:plain

ただしBiasの値を大きくしすぎると影が物体から離れていくような見え方になります。
またNormal Biasの値を大きくしすぎると影が細くなっていくような見え方になります。

そのため大きな値にしすぎないように、かつアクネが消えるように調整する必要があります。

近くの影もきれいに描画するShadow Cascades(モバイル不可)

Shadow Distanceを大きく設定していると、近くの影はどうしてもシャドウマップの解像度が足りなくなり粗くなってしまいます。

f:id:halya_11:20190617004951p:plain

近くの方が細かいところまで気になってしまうのに、近くの影が粗くなるのはイケてません。
Shadow Cascadeを使うとこのような状況を改善できます。

  1. Edit > Project Settings > Quality
  2. ShadowsグループのShadow CascadesをTwo CascadesやFour Cascadesに変更する

f:id:halya_11:20190617005135p:plain

たとえばFour Cacadesに設定するとこのくらい変わります。

f:id:halya_11:20190617005254p:plain

この機能は、カメラの距離に応じてシャドウマップをいくつか用意してレンダリングする機能です。
カメラに近い部分のシャドウマップには詳細まで映るようにすることで影のクオリティを上げます。
ただシャドウマップを複数レンダリングする分、処理負荷は上がります。

またモバイルでは使えないとのことです。

モバイルプラットホームでは、シャドウカスケードをサポートしていないので
ディレクショナルライトのシャドウ - Unity マニュアル より

参考

docs.unity3d.com

docs.unity3d.com

tsubakit1.hateblo.jp