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