ライトは2つの方法のいずれかでレンダリングすることができます。
頂点ライティング は、メッシュの頂点だけで照明を計算し、頂点間のサーフェス上では、頂点の値を補間します。ライティングエフェクトの中には、頂点ライティングにサポートされないものもありますが、処理のオーバーヘッドの面では、2 つを比べるとこちらの方が間違いなく有利です。また、古いグラフィックカードでは、頂点ライティングが、唯一利用可能な方法である場合があります。
ピクセルライティング は、すべてのスクリーンピクセルを個別に計算します。レンダリングに時間がかかりますが、頂点ライティングで不可能なエフェクトのいくつかを行うことができます。法線マッピング、ライトのクッキー、リアルタイムのシャドウはピクセルライト用だけにレンダリングされます。さらに、スポットライトの形状やポイントライトのハイライトは、ピクセルモードでレンダリングした方がずっと見栄えが良くなります。
ライトは、レンダリング速度に大きな影響を与えます。ですから、ライトの品質をよくするとフレームレートが低下します。ピクセルライトは頂点ライトよりもはるかに高いレンダリングオーバーヘッドを持つので、Unity はピクセル単位で最も明るいライトをレンダリングし、残りを頂点ライトとしてレンダリングします。ピクセルライトの最大数は、スタンドアロンビルドターゲットの Quality Settings で設定することができます。
Render Mode プロパティーを使って、あるライトを優先的にピクセルライトとしてレンダリングすることができます。ライトをピクセルライトとしてレンダリングするかどうかを決定するときに、Important と設定されたモードのライトには、より高い優先順位になります。 Auto (デフォルト) に設定したモードでは、指定されたオブジェクトがどれだけそのライトの影響を受けるかに基づいて Unity が自動的にライトを分類します。ピクセルライトとしてレンダリングするライトは、個々のオブジェクトベースで決定されます。
詳細については、グラフィックスパフォーマンスの最適化 のページを参照してください。
リアルタイムのシャドウはレンダリングのオーバーヘッドが非常に高いので、使用する際には注意が必要です。最初に、投影する可能性のあるオブジェクトをシャドウマップへレンダリングしておきます。その後、シャドウを受ける可能性のあるオブジェクトがレンダリングされる時に、このシャドウマップが使われます。シャドウを有効にすると、上述のピクセル/頂点ライトよりも、さらに大きな影響をパフォーマンスに与えます。
ソフトシャドウは、ハードシャドウよりも大きなレンダリングのオーバーヘッドを持っていますが、これは GPU に影響を与えるだけで、CPUに多くの余分な作業は発生しません。
Quality Settings には、 Shadow Distance 値が含まれていて、カメラからこの距離を超えているオブジェクトは、すべてシャドウなしでレンダリングされます。遠くのオブジェクトのシャドウは、通常は、気づかれることはありません。これはレンダリングするシャドウの数を減らすために有用な最適化です。
ディレクショナルライト特有の問題は、1 つのライトがシーン全体を照らすことができてしまうことです。つまり、シャドウマップがしばしば、シーンの大部分をいっぺんにカバーし、パースペクティブエイリアシングとして知られている問題が発生するシャドウができやすいことです。簡単に言えば、 パースペクティブエイリアシングでは、カメラの近くに表示されるシャドウマップのピクセルは遠くのものに比べて、拡大されて「分厚く」見えます。この影響を低減するために、単にシャドウマップの解像度を上げることもできますが、その結果、解像度の低いシャドウマップで十分よく見えてた距離の離れた領域で、レンダリングのリソースが無駄に消費されてしまいます。
したがって、問題の良い解決方法は、カメラからの距離が増加して解像度が低下したら、別のシャドウマップを使うことです。これらの独立したマップは カスケード として知られています。 Quality Settings から、0, 2 , 4 つのカスケード (Cascades) を選択することができます。Unity は、カメラの錐台内のカスケードの位置を計算します。カスケードは、ディレクショナルライトでのみ有効になっていることに注意してください。詳細は、 ディレクショナルライトのシャドウ を参照してください。
マップのサイズを計算する際の最初のステップは、ライトが照射できるスクリーンビューの領域を決定することです。 ディレクショナルライトに関しては、スクリーン全体を照らすことができますが、スポットライトやポイントライトに関しては、その領域はライトの広がりの形状 (ポイントライトの球形、やスポットライトの円錐形) がスクリーン上へ投影したものです。投影された形状は、スクリーン上にピクセル単位の特定の幅と高さを持ちます。この2つの値の大きい方が、光の「ピクセルサイズ」です。
シャドウマップの解像度が Quality Settings で High に設定されている場合、シャドウマップのサイズは、以下のように計算されます。
グラフィックスカードが、512MB 以上のビデオメモリを有する場合、上のシャドウマップの限度は、ディレクショナルライトでは 4096、スポットライトでは 2048、ポイントライトでは 1024 まで増加されます。
Medium のシャドウの解像度では、シャドウマップのサイズは High の半分の値であり、Low では、High の 4分の 1 のサイズになります。
ポイントライトは、他のタイプよりもサイズの限界が低く設定されています。なぜなら、キューブマップをシャドウに使用するからです。つまり、この解像度でキューブマップの 6 面がいっぺんにビデオメモリに保持されなければならないからです。描画するのにも非常に負荷がかかります。シャドウを投影する可能性のあるものを、キューブマップ 6 面全てに描画する場合があるからです。
1 つ以上のオブジェクトがシャドウを落としていない場合、次の点をチェックする必要があります。
古いビデオグラフィックスハードウェアはシャドウをサポートしていない場合があります。シャドウを扱うことができる最低限のハードウェア仕様のリストについては、後の説明を参照してください。
シャドウは Quality Settings で無効にされている場合があります。Quality Settingsで適切な品質レベルになっており、設定でシャドウが有効になっていることを確認して下さい。
シーンのすべての メッシュレンダラー は、 Receive Shadows と Cast Shadows とともに正しく設定する必要があります。どちらも、デフォルトで有効になってますが、気づかないうちに無効になっていないかを確認して下さい。
不透明なオブジェクトのみ、シャドウを投影したり受けたりします。ですから、ビルトインの 透明 シェーダーやパーティクルシェーダーを使用したオブジェクトは、シャドウを投影したり受けたりしません。一般的に、フェンス、植生などののようなすき間のあるオブジェクトには、代わりに 透明カットアウト シェーダを使うことができます。カスタム シェーダー はピクセルライライティングと Geometry レンダーキュー を使用しなければなりません。
VertexLit シェーダーを用いたオブジェクトはシャドウを受けることができませんが、投影はできます。
フォワードレンダリングパス では、もっとも明るいディレクショナルライトだけしかシャドウを投影しないシェーダーもあります (特に、これはUnity のバージョン 4.x 以前の古いビルトインシェーダで発生します)。複数のシャドウを落とすライトを設定したい場合は、代わりに ディファードシェーディング レンダリングパスを使用する必要があります。fullforwardshadows
サーフェスシェーダー ディレクティブを使用してすべてのシャドウをサポートする独自のシェーダを有効にすることができます。
ビルトインのシャドウは、Unity でサポートされているほとんどすべてのデバイス上で使用できます。以下のカードが各プラットフォームでサポートされています。
GL_OES_depth_texture
をサポートしていることが必要です。特に、Android Tegra 2/3 ベースの Android デバイスは、サポートしていません。そのため、Android Tegra 2/3 ベースの Android デバイスはシャドウをサポートしません。