リアルタイムの影 (シャドウ) はレンダリングのオーバーヘッドがかなり高くなります。影を投影するゲームオブジェクトは、最初にシャドウマップにレンダリングする必要があります。それから、そのマップを使用して、影を受けるオブジェクトをレンダリングします。
ソフトシャドウは、ハードシャドウよりも大きなレンダリングのオーバーヘッドを持っていますが、これは GPU に影響を与えるだけで、CPUに多くの余分な作業は発生させません。
複雑なジオメトリのリアルタイムシャドウのレンダリングが許容範囲を超える高額な費用を要する場合は、低 LOD メッシュまたはプリミティブを使用してシャドウを投影することを検討します。
この方法では過剰に多くのリソースが消費される場合は、キャラクターの下にある単純なメッシュまたはクアッドにぼかしたテクスチャを適用して影を偽装したり、カスタムシェーダーでブロブシャドウを作成したりすることができます。
ライトが直接照らすサーフェスに、部分的に影があるように見えることがあります。正確にシャドウマップで指定された距離であるべきピクセルが、ずっと遠くにあるように計算されてしまう場合があるためです (これは、シャドウフィルタリングやシャドウマップに低解像度画像を使用した結果)。その結果として、実際には照らされるべきピクセルが影になって模様を作る、“シャドウアクネ” と言われる現象が発生します。
シャドウアクネを防ぐために、ライトバイアス の設定を調整することができます。
シャドウマップの距離にバイアスを加えて、境界線上のピクセルが比較をパスするようにしたり、ジオメトリを法線に沿って少しだけ差し込むことができます。
ビルトインレンダーパイプラインでは、影が有効になっているときに、Light Inspector の Bias と Normal Bias プロパティでこれらの値を設定することができます。
Bias 値をあまり高く設定しないでください。なぜなら、ゲームオブジェクトが作る影の近くの領域は時々誤って照らされることがあるからです。この結果、オブジェクトから離れた影となり、ゲームオブジェクトがまるで空中に浮かんでいるように見えます。
同様に、Normal Bias 値をあまり高く設定すると、ゲームオブジェクトに対し、影の幅が狭くなりすぎてしまいます。
ある状況では、Normal Bias が “ライトのにじみ” と呼ばれる、望ましくない効果の原因になることがあります。ライトのにじみとは、ライトが近くのジオメトリから影になる領域に漏れてしまうことです。可能なソリューションはゲームオブジェクトの Mesh Renderer を開き、 Cast Shadows プロパティを Two Sided にします。これによって、問題を解決できる場合があります。ただし、よりリソース負荷が高くなり、シーンをレンダリングするときにパフォーマンスのオーバーヘッドが増加します。
ライトの Bias 値には、望まないエフェクトが発生しないように微調整が必要な場合があります。一般に、計算するよりも目測で値をとる方が簡単です。
さらに、シャドウアクネを避けるために シャドウパンケーキ という技術を利用できます。ライト方向に沿ってシャドウマップをレンダリングするときに、使用するライト空間の範囲を減らすという考えです。結果として、シャドウマップをより正確にし、シャドウアクネを削減します。
上のダイアグラムでは、以下を示しています。
影を投影するものを (頂点シェーダーの) 最適化された空間のニアクリップ面に固定します。一般的にこの方法は効果的ですが、そのニアクリップ面を横切るとても大きな三角に関しては、アーティファクトを発生することがあります。
この場合、青い三角の頂点の 1 つを最適化されたニアクリップ面の範囲内に置きます。ただし、ここうすると、三角の形状を変えるため、正しくない影を作成してしまうことがあります。
この問題を回避するには Quality ウィンドウの Shadow Near Plane オフセット プロパティを微調整します。これにより、ニアクリップ面を戻します。ただし、この値を非常に高く設定すると、そのうちにシャドウアクネが発生します。なぜなら、シャドウマップがライトの方向で対応する必要がある範囲が増えるためです。他の方法として、問題のある影の投影の三角形をテッセレーションすることもできます。
1 つ以上のオブジェクトが影を作らない場合、次の点をチェックする必要があります。
Quality ウィンドウで、リアルタイムの影が完全に無効になっている場合があります。正しい品質レベルが有効になっていて、その設定で影がオンになっていることを確認してください。
シーンのすべての メッシュレンダラー は、 Receive Shadows と Cast Shadows とともに正しく設定する必要があります。どちらも、デフォルトで有効になってますが、気づかないうちに無効になっていないかを確認して下さい。
不透明なオブジェクトのみが影を落とし、影を受けます。そのため、ビルトインの 透過 シェーダーや パーティクルシェーダーを使うオブジェクトは、影を落としたり、受けたりすることはありません。一般的に、フェンスや植物などの “ギャップ” のあるオブジェクトには、代わりに 透過切り抜き シェーダーを使用することができます。カスタム シェーダー は、ピクセルライトで、ジオメトリのレンダーキュー を使用する必要があります。
VertexLit シェーダーを用いたオブジェクトは影受けることができませんが、投影はできます。
ゲームオブジェクトが “Unlit” タイプのシェーダー付きのマテリアルを持つ場合、Unity は影を計算することはできません。Unity は、ライティングをサポートするシェーダーを持つマテリアルの影のみを計算できます。
ビルトインレンダーパイプラインで、フォワードレンダリングパス を使用すると、一部のシェーダーは最も明るいディレクショナルライトのみが影を投影することを許容します (特に、この状態は Unity のバージョン 4.x 以降のビルトインシェーダーで発生します)。複数の影を落とすライトを設定する必要がある場合は、代わりに ディファードシェーディング レンダリングパスを使用する必要があります。fullforwardshadows
サーフェスシェーダー ディレクティブを使用してすべての影をサポートする独自のシェーダーを有効にすることができます。