Version: 2019.4
言語: 日本語
シャドウカスケード
Lighting ウィンドウ

シャドウのトラブルシューティング

シャドウのパフォーマンス

リアルタイムの影 (シャドウ) はレンダリングのオーバーヘッドがかなり高くなります。影を投影するゲームオブジェクトは、最初にシャドウマップにレンダリングする必要があります。それから、そのマップを使用して、影を受けるオブジェクトをレンダリングします。

ソフトシャドウは、ハードシャドウよりも大きなレンダリングのオーバーヘッドを持っていますが、これは GPU に影響を与えるだけで、CPUに多くの余分な作業は発生しません。

シャドウアクネ

ライトが直接照らすサーフェスに、部分的に影があるように見えることがあります。正確にシャドウマップで指定された距離であるべきピクセルが、ずっと遠くにあるように計算されてしまう場合があるためです (これは、シャドウフィルタリングやシャドウマップに低解像度画像を使用した結果)。その結果として、実際には照らされるべきピクセルが影になって模様を作る、“シャドウアクネ” と言われる現象が発生します。

不自然な影を作るシャドウアクネ
不自然な影を作るシャドウアクネ

Bias プロパティ

シャドウアクネを避けるために、シャドウマップの距離に Bias (バイアス) 値を加え、数値の境目にあるピクセルが確実に比較にとおるようにします。または、シャドウマップにレンダリングする間に、ゲームオブジェクトが法線に沿って少し差し込まれるようにします。これらの値は、シャドウが有効の時に Light インスペクターウィンドウの BiasNormal Bias プロパティで設定します。

Bias 値をあまり高く設定しないでください。なぜなら、ゲームオブジェクトが作るシャドウ近くの領域は時々誤って照らされることがあるからです。この結果、オブジェクトから離れたシャドウとなり、ゲームオブジェクトがまるで空中に浮かんでいるように見えます。

あまりにも Bias 値を高くすると、影がオブジェクトから離れているように見えます
あまりにも Bias 値を高くすると、影がオブジェクトから離れているように見えます

同様に、Normal Bias 値をあまり高く設定すると、ゲームオブジェクトに対し、影の幅が狭くなりすぎてしまいます。

Normal Bias 値を高くし過ぎると、シャドウの幅がとても狭くなります
Normal Bias 値を高くし過ぎると、シャドウの幅がとても狭くなります

ある状況では、Normal Bias が “ライトのにじみ” と呼ばれる、望ましくない効果の原因になることがあります。ライトのにじみとは、ライトが近くのジオメトリから影になる領域に漏れてしまうことです。可能なソリューションはゲームオブジェクトの Mesh Renderer を開き、 Cast Shadows プロパティを Two Sided にします。これによって、問題を解決できる場合があります。ただし、よりリソース負荷が高くなり、シーンをレンダリングするときにパフォーマンスのオーバーヘッドが増加します。

ライトの Bias 値には、望まないエフェクトが発生しないように微調整が必要な場合があります。一般に、計算するよりも目測で値をとる方が簡単です。

正常な影
正常な影

シャドウパンケーキ

さらに、シャドウアクネを避けるために シャドウパンケーキ という技術を利用できます。照明方向に沿ってシャドウマップをレンダリングするときに、使用する照明空間の範囲を減らすという考えです。結果として、シャドウマップをより正確にし、シャドウアクネを削減します。

シャドウパンケーキの原理を表現する図
シャドウパンケーキの原理を表現する図

上のダイアグラムでは、

  • 薄青の輪 はシャドウを投影するものを表しています。
  • 濃い青の四角 は元の照明空間を表しています。
  • 緑の線 は最適化されたニアクリップ面 (視錐台からみえない影を投じるものはすべて除外) を表しています。

影を投影するものを (頂点シェーダーの) 最適化された空間のニアクリップ面に固定します。一般的にこの方法は効果的ですが、そのニアクリップ面を横切るとても大きな三角に関しては、アーティファクトを発生することがあります。

大きな三角に発生する問題
大きな三角に発生する問題

この場合、青い三角の頂点の 1 つを最適化されたニアクリップ面の範囲内に置きます。ただし、ここうすると、三角の形状を変えるため、正しくない影を作成してしまうことがあります。

この問題を回避するには Quality ウィンドウの Shadow Near Plane オフセット プロパティを微調整します。これにより、ニアクリップ面を戻します。ただし、この値を非常に高く設定すると、そのうちにシャドウアクネが発生します。なぜなら、シャドウマップがライトの方向で対応する必要がある範囲が増えるためです。他の方法として、問題のある影の投影の三角形をテッセレーションすることもできます。

影が表示されない

1 つ以上のオブジェクトが影を作らない場合、次の点をチェックする必要があります。

  • Quality ウィンドウで、リアルタイムの影が完全に無効になっている場合があります。正しい品質レベルが有効になっていて、その設定でシャドウがオンになっていることを確認してください。

  • シーンのすべての メッシュレンダラー は、 Receive ShadowsCast Shadows とともに正しく設定する必要があります。どちらも、デフォルトで有効になってますが、気づかないうちに無効になっていないかを確認して下さい。

  • 不透明なオブジェクトのみ、影を投影したり受けたりします。ですから、ビルトインの 透明 シェーダーやパーティクルシェーダーを使用したオブジェクトは、影を投影したり受けたりしません。一般的に、フェンス、植生などののようなすき間のあるオブジェクトには、代わりに 透明カットアウト シェーダーを使うことができます。カスタム シェーダー はピクセルライライティングと Geometry レンダーキュー を使用しなければなりません。

  • VertexLit シェーダーを用いたオブジェクトは影を受けることができませんが、投影はできます。

  • ゲームオブジェクトが “Unlit” タイプのシェーダー付きのマテリアルを持つ場合、Unity はシャドウを計算することはできません。Unity は、ライティングをサポートするシェーダーを持つマテリアルのシャドウのみを計算できます。

  • ビルトインレンダーパイプラインで、フォワードレンダリングパス を使うと、もっとも明るいディレクショナルライトだけしか影を投影しないシェーダーもあります (特に、これはUnity のバージョン 4.x 以前の古いビルトインシェーダーで発生します)。複数の影を落とすライトを設定したい場合は、代わりに ディファードシェーディング レンダリングパスを使用する必要があります。fullforwardshadows サーフェスシェーダー ディレクティブを使用してすべての影をサポートする独自のシェーダーを有効にすることができます。

シャドウカスケード
Lighting ウィンドウ