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

影のトラブルシューティング

影のパフォーマンス

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

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

シャドウアクネ

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

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

ライトバイアスの設定

シャドウアクネを防ぐために、ライトバイアス の設定を調整することができます。

シャドウマップの距離にバイアスを加えて、境界線上のピクセルが比較をパスするようにしたり、ジオメトリを法線に沿って少しだけ差し込むことができます。

ビルトインレンダーパイプラインでは、影が有効になっているときに、Light Inspector の 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 とともに正しく設定する必要があります。どちらも、デフォルトで有効になってますが、気づかないうちに無効になっていないかを確認して下さい。

  • 不透明なオブジェクトのみが影を落とし、影を受けます。そのため、ビルトインの 透過 シェーダーや パーティクルシェーダーを使うオブジェクトは、影を落としたり、受けたりすることはありません。一般的に、フェンスや植物などの “ギャップ” のあるオブジェクトには、代わりに 透過切り抜き シェーダーを使用することができます。カスタム シェーダー は、ピクセルライトで、ジオメトリのレンダーキュー を使用する必要があります。

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

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

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

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