読者です 読者をやめる 読者になる 読者になる

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