Unityシェーダ入門 #006 FowardRenderingでの影
UnityのForward Renderingでは1つのDirectional Lightからのみ、リアルタイム影を落とすことが出来ます。影をカスタマイズしたい場合があるので、処理の流れをまとめてみました。
1.
シャドウマップを生成します。
QualitySettingのShadowCascadesによって、1,2,4枚のカスケードシャドウマップが生成されます。
(2,4枚の場合でも、1枚のテクスチャにまとめられる[=テクスチャアトラス]ようです)
ここではシェーダのShadowCasterパスが用いられます。
2.
深度を比較して、画面空間上での影を求めます。
ここではシェーダのShadowCollectorパスが用いられます。
3.
2で求めた影の画像に対してブラー処理が行われます。
4.
FowardRenderingのbaseパスで、3で生成した影テクスチャから影の量を取得し、ライトをその分だけ減衰させます。
※1
Unityでは半透明オブジェクトに影が落ちません。
これは4で直接影を求めるのではなく、2+3を経由しているからです。
2+3では画面の影を1枚のテクスチャに格納するわけですが、この時点で最も手前の影しか考慮されないことがわかります。例えば不透明ポリゴンの上に半透明ポリゴンが1枚重なっている場合、不透明ポリゴンに落ちる影と、半透明ポリゴンに落ちる影の両方を考慮しなければなりませんが、1枚のテクスチャではそれは不可能であり、不透明オブジェクトの分しか扱えないのです。
※2
ちなみに4で直接影を求めようと試みましたが、シャドウマップUV計算用の行列(ライト行列?)が正しく渡されないようで無理でした。
※3
DeferredRenderingの場合Internal-PrePassCollectShadows.shaderで2を行っているのかな?1は多分一緒(ShadowCasterパス)な気がします。
参考はここ。随分昔の話ですが、挙動を見る限り変わってなさそうです。
Deferred Cascaded Shadow Maps - Aras' website