自作のファーシェーダをアップデートすべく、色々と調べています。
調べていく中で、だいぶ自分の中でレンダリングパスについて整理できてきたのでまとめたいと思います。
詳細はこちら(Forward Renderingパスの詳細 / Forward Rendering Path Details - Unity Manual)
Unityでライトと影(Shadow)を制御する
Unityでは、ライトと影のレンダリングはいくつかのレンダリングパスを用いて行います。
レンダリングパスには以下のものがあります。(Unity Manualから引用)
Deferred Lighting
Deferred Lighting はライトと影が最も厳密にレンダリングされます。もし多くのリアルタイムライトを使いたいのであれば最適でしょう。ただ、これはハードウェアがある一定のレベルが必要なので、Unity Pro 専用で、 Mobile Devices ではサポートされていません。
さらに詳しくは Deferred Lighting page を参照して下さい。
Forward Rendering
Forward Rendering はシェーダーベースのRendering Pathsです。 これはパーピクセルライト(ノーマルマップやlight Cookiesが含まれます)をサポートし、1個のディレクショナル(一方方向)ライトからのリアルタイムシャドウをサポートします。 デフォルト設定では、パーピクセルライトモードでは最小の数のライトでレンダリングされます。 残りのライトは頂点で計算されます。
さらに詳しくは Forward Rendering page を参照して下さい。
Vertex Lit
Vertex Lit は一番軽いRendering Pathsで、リアルタイム影もサポートされていません。古いマシンでは最も使われるでしょうし、モバイルプラットフォーム限定利用されるかもしれません。
ForwardBaseレンダリング
(Unity Manualから引用)
Base Passは一つのピクセルごとの指向性ライトおよび全ての頂点ごと/SHライトを適用します。
指向性ライト(平行光源、ディレクショナルライト)によるライティングが可能なレンダリングです。
それ以外のライトについては球面調和としてライトが計算され、それを適用します。
マニュアルによれば、このモード(タグに"LightMode"="ForwardBase"
を指定したパス)は、ひとつの指向性ライトによるピクセルライトと、影のサポートがあるようです。
つまり、 ForwardBaseではポイントライトやスポットライトなどはサポートされません。
ForwardAddレンダリング
指向性ライト以外のライトについて計算が可能なレンダリングです。(指向性ライトも含まれます)
しかし、こちらのモードでは、いわゆる 影(Shadow)をレンダリングすることができません。
影を適用する(Receive Shadow)場合は上記のForwardBaseレンダリングでレンダリングしなければなりません。
これはつまり、影のレンダリングは指向性ライトのみが適用できる(※1)、ということです。
実際にシェーダを書いてみると、シャドウマップなどのテクスチャ情報が定義されておらず、利用できなくなります。
※1 ... Unity Pro版であれば遅延ライティングにより、その他の影も適用できるようです。
分かりやすいレンダリングの例
LightModeの違いによるレンダリングの結果は、以下のキャプチャが分かりやすいでしょう。
上側にあるライト(太陽みたいなアイコンのほう)が指向性ライト、左端にあるのが スポットライト です。
上記サンプルは、シェーダに少し細工をしてレンダリングした結果です。
ForwardBaseで一回(若干小さい、正常な球体)、ForwardAddでもう一回(若干大きい、上下が欠けた球体)レンダリングされているのが分かると思います。
ForwardAddでレンダリングする際に、 モデルを法線方向に少しだけふくらませる処理 を入れています。
結果、スポットライトを使用したレンダリング(つまりForwardAdd)の場合は、光が当たっているところだけ、少しだけ膨らんだモデルがレンダリングされているのが分かると思います。
ドキュメントによると、ライトの数だけForwardAdd
パスがレンダリングされるようです。
それを合成し、最終的なシーンをレンダリングしている、というわけですね。
なので、複数ライトを適用する場合は、シェーダ内で複数ライトを直接取得して合成するのではなく、各々のライト用のレンダリングが走るので、基本的にはひとつのライトだけを考慮してレンダリングすればいいわけです。
(これを理解するまでだいぶ色々悩んだ( ;´Д`))
実際にこの状態でライトを増やしていくと、その分、照らされている領域がしっかりと明るくなるのが確認できます。