ディレクショナルライトの影
グローバルイルミネーション

Light のトラブルシューティングとパフォーマンス

Light は2つの方法のいづれかでレンダリングすることができます:

  • Vertex lighting は、メッシュの頂点だけで照明を計算し、頂点間のサーフェイス上では、頂点の値を補間します。いくつかの照明効果は、vertex lighting ではサポートされていませんが、処理のオーバーヘッドの面では、こちらの方が間違いなく有利です。また、旧式のグラフィックカードでは、唯一利用できる方法の場合があります。

  • Pixel lighting は、すべてのスクリーンピクセルを個別に計算します。レンダリングは遅いですが、pixel lights は vertex lighting では不可能ないくつかの効果を可能にします。 Normal-mapping 、 light cookies および realtime shadows をレンダリング出来るのはPixel lightingだけです。さらに、スポットライトの形状や点光源のハイライトは、ピクセルモードでレンダリングした方が、より綺麗に見えます。

スポットライトレンダリングと vertex モードの比較
スポットライトレンダリングと vertex モードの比較

Lights は、レンダリング速度に大きな影響を持っています。照明の品質はフレームレートと反比例します。 pixel lights は vertex lights よりもはるかに高いレンダリングのオーバーヘッドを持っているので、 Unity はピクセル単位で最も明るい lights をレンダリングし、残りを vertex lights としてレンダリングします。 pixel lights の最大数は、webplayer および、スタンドアロンビルドターゲットに応じて Qualiy Steeings で設定することができます。

Lightsは、その Render Mode プロパティによって、 pixel light としてレンダリングすることができます。 pixel light としてレンダリングするかを決定するとき、 Important に設定されたモードの light は、より高い優先順位が与えられます。 Auto (デフォルト) に設定したモードでは、Unity は指定されたオブジェクトが light の影響を受けるかどうかによって自動的に light のレンダリング方法を決定します。 pixel lights としてレンダリングされた lights は、個々のオブジェクトベースで決定されます。

詳細については、Optimizing Graphics Performance のページを参照してください。

Shadow のパフォーマンス

リアルタイムシャドウはレンダリングのオーバーヘッドが非常に高いので、使用する際には注意が必要です。最初に、影を落とす可能性のあるオブジェクトをシャドウマップへレンダリングしておくと、その後、影を受ける可能性のあるオブジェクトがレンダリングされる時に、このシャドウマップが使われます。シャドウを有効にすると、上述のピクセル/バーテックスのトレードオフよりも、さらに大きな影響をパフォーマンスに与えます。

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

Quality Settings には、 Shadow Distance の値が含まれていて、カメラからこの距離を超えているオブジェクトは、すべてシャドウなしでレンダリングされます。遠くのオブジェクトのシャドウは、通常は、気づかれることはありません。これはレンダリングするシャドウの数を減らすために有用です。

directional lights 特有の問題は、一つの光がシーン全体を潜在的に照らすことができてしまうことです。これは、シャドウマップが、しばしば、シーンの大部分を一度にカバーし、 "perspective aliasing" として知られている問題に影響されやすいシャドウが作られることを意味します。簡単に言えば、 perspective aliasing は、シャドウマップのピクセルが、カメラの近くで見ると遠くのものに比べて、拡大されて「分厚く」見えることを意味します。この影響を低減するためにシャドウマップの解像度を向上させることができますが、その結果、レンダリングのリソースが、解像度の低いシャドウマップで十分よく見えてた遠い領域のために浪費されてしまいます。

したがって、問題の良い解決方法は、カメラからの距離が増加して解像度が低下したら、別のシャドウマップを使うことです。これらの独立したマップは cascades として知られています。 Quality Settings から、0(ゼロ)、2つまたは4つのcascadesを選択することができます; Unity は、カメラの錐台内のcascadesの位置を計算します。cascadesは、 directional lights でのみ有効になっていることに注意してください。詳細は、 directional light shadows ページを参照してください。

シャドウマップのサイズを計算する方法

マップのサイズを計算する際の最初のステップは、光が照射できるスクリーンビューの領域を決定することです。 directional lights のために、スクリーン全体を照射することができますが、スポットライトやポイントライトによって、面積は光の広がり(ポイントライトの球、または、スポットライトの円錐)の形状のスクリーン上への投影です。投影された形状は、スクリーン上にピクセルで特定の幅と高さを持ちます; この2つの値の大きい方は、光の "pixel size" とします。

シャドウマップの解像度が( Quality Settings ) High に設定されている場合、シャドウマップのサイズは、次のように計算されます:

  • Directional lights: NextPowerOfTwo ( ピクセルサイズ*1.9 )、最大2048まで。
  • Spot lights: NextPowerOfTwo(ピクセルサイズ), 最大1024まで。
  • Point lights: NextPowerOfTwo(ピクセルサイズ* 0.5)、最大512まで。

ビデオグラフィックスカードが、512MB以上のビデオメモリを有する場合、上のシャドウマップの限度は、directional lights は4096、spot lights は2048、point lights は1024まで増加されます。

Medium シャドウ解像度は、シャドウマップのサイズは High 解像度の半分の値であり、Low シャドウ解像度では、4分の1のサイズになります。

シャドウのためにキューブマップを使用するため、ポイントライトは、他のタイプよりも、サイズの下限があります。つまり、この解像度で6つのキューブマップの面が一度にビデオメモリ内に保持されなければならないことを意味します。潜在的なシャドウキャスターは、キューブマップ6面全てのレンダリングが必要な場合があるかもしれないので、レンダリングするのに非常に負荷がかかります。

限られたメモリ条件

非常に少ないビデオメモリ上でゲームが動いている場合、シャドウマップの解像度を自動的に減らします。

一般的に、スクリーンデータ(backbuffer,frontbuffer,depth buffer)とレンダリングテクスチャのデータはビデオメモリに 必ず 保持しなければなりません。スクリーンデータとレンダリングテクスチャデータを格納するのに必要なメモリが消費されます。そして、残りのビデオメモリの 3分の1 は、シャドウマップで使用するために確保されます。任意のシャドウマップの解像度は、このメモリ上に収まるように落とされます。(すなわち、上記の処理は適用されますが、実際には落とした解像度です。)

すべてのテクスチャ、頂点データおよびその他のグラフィックのオブジェクトがビデオメモリからスワップアウトした場合、シャドウマップで使用することができるVRAMの理論上の最大は次の式によって与えられます。 (TotalVideoMemory - ScreenMemory - RenderTextureMemory) しかし、スクリーンやレンダリングテクスチャに使うメモリの量を正確に決定することはできません。さらに、いくつかのオブジェクトはスワップするべきではありません。例えば、すべてのテクスチャが、絶えずスワップイン-アウトされた場合のパフォーマンスは、著しく低下します。なので、Unity はシャドウマップが、”空き”ビデオメモリの3分の1を超えることは許可していません。こうすることによって、実際にうまく機能させることができます。

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

一つ以上のオブジェクトが影を落としていない場合、次の点をチェックしなければなりません。

  • 古いビデオグラフィックスハードウェアはシャドウをサポートしていない場合があります。シャドウを扱うことができるハードウェア仕様のリストについては、以下を参照してください。

  • シャドウは Quality Settings で無効にすることができます。Quality Settingsでシャドウのスイッチがオンの状態で、品質レベルを確認してください。

  • シーンのすべての Mesh Renderers は、それらの receive ShadowsCast Shadows を正しく設定しておく必要があります。どちらも、デフォルトで有効になってますが、意図せずに無効にされていないか確認します。

  • opaque オブジェクトのみ、シャドウをキャストとレシーブします。だから、ビルトイン Transparent を使用したオブジェクト、または、パーティクルシェーダは、キャストもレシーブもしないでください。一般的に、フェンス、植生などののような “gaps” のオブジェクトの代わりに Transparent Cutout シェーダを使うことができます。カスタム Shaders はピクセル点灯すると Geometry render queue を使用しなければなりません。

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

  • Forward rendering pathで、いくつかのシェーダは、もっとも明るい directional light だけが影を落とすことができます。(特に、これはバージョン4.xからの Unity のレガシービルトインシェーダで可能です。)複数の影を落とす光を設定したい場合、代わりに Deferred Shading レンダリングパスを使用する必要があります。fullforwardshadows surface shader を使用して “full shadows” をサポートするために、独自のシェーダを有効にすることができます。

シャドウをサポートするハードウエア

ビルトインシャドウは、Unity でサポートされているほとんどすべてのデバイス上で動作します。次のカードが各プラットフォームでサポートされています:

Windows

  • AMDのRadeon:すべてのGPUをサポートします。
  • Nvidia GeForce: GeForce FX(2003年頃)シリーズを除く、全てのGPUサポートします。
  • Intel: 915/945/GMA950 (2004年頃)を除く、全てのGPUをサポートします。

Mac OS X

OSXがサポートしているGPUは全てシャドウをレンダリングできます。

iOS、Android および Windows Phone

  • iOS: GL_EXT_shadow_samplers をサポートします。もっとも注目すべきことは、iPhone4はシャドウをサポートしていません。(iPhone4Sは、すでにサポートしています。)
  • Android: Android 4.0 以降、および、GL_OES_depth_texture をサポート。もっとも注意すべきことは、いくつかの Android Tegra 2/3 ベースの Android デバイスは、シャドウをサポートしていません。
  • Windows Phone: サポートはOSとモデルによって異なります。通常、Adreno 225と305 GPU はシャドウをサポートしていません。

コンソールゲーム機

  • 全てのコンソールゲーム機をサポートします。
ディレクショナルライトの影
グローバルイルミネーション