遅延レンダリングのシャドウ


12

遅延レンダリングに関する資料を読んだので、その要点は理解できたと思います。しかし、私が理解していないのは、それがどのように影を達成するかです。私が知る限り、Gバッファは各ライトのシャドウマップの作成を含まないため、ライティングパスが各ピクセルがオクルードされているかどうかをどのように認識するかについて混乱しています。結局のところ、カメラの視点から見える特定のピクセルは実際には特定の光の視点からは見えない可能性があり、そのオクルージョンジオメトリはカメラの視点からは見えない可能性があるため、Gバッファーに何も書き込まれません。 。

シャドウマップのレンダリングを開始すると、フォワードレンダリングとほぼ同じように見えます。シャドウマップをレンダリングするために、すべてのライトに対してシーン内のすべてのジオメトリをレンダリングします。

では、遅延レンダリングは、フォワードレンダリングと同等のシャドウをどのように実現するのでしょうか。

回答:


14

遅延シェーディングは影に対して特別なことは何もしません。シャドウマップを通常どおりレンダリングしてから、テクスチャとしてバインドされた適切なシャドウマップを使用して各ライトをレンダリングする必要があります。

ライティングを適用するためにメインビューでシーンを再描画する必要がないため、フォワードレンダリングよりも優れています。シャドウマップの描画は、ピクセルシェーディングを行う必要がないため、メインビューでより多くのパスを描画するよりもはるかに安価であることがよくあります。また、シャドウマップに含まれるシーンが少ない場合があります(より多くのものを選択できます)。

人々は、1つのライト(通常は主な指向性ライト)に対して「遅延シャドウ」を行うことがあります。これを行う主な理由は、カスケードシャドウマップ、または同じライトに対して複数のシャドウマップを使用する別のアプローチを使用するためです。Gバッファの1つのチャネルをシャドウマスク(点灯している場合は白、シャドウしている場合は暗い)用に予約し、カスケードされたすべてのシャドウマップをこのGバッファチャネルに適用できます。次に、ライトのシェーダーはシャドウマスクを読み取り、ライトカラーに乗算します。シャドウとシェーディングを分離するのでこれは便利ですが、すべて同じシャドウマップを描画しています。


1
あなたがいる場合は非常に賢いあなたは(キューブマップDX10サンプルがないように)「インライン」シャドウマップの作成にGBufferの作成中にジオメトリシェーダを使用して試みることができます。それが行われたのか、それが可能であるのか、または最終的に遅くなるのかどうかはわかりませんが、シャドウマップの作成が遅延シェーディングに近づくか、または宗教に応じて定義に組み込まれます。
ジョナサンディキンソン

6

さて、シャドウマップとは何ですか?シャドウマップは、テクセルが単純な質問に答えるテクスチャです。テクセルによって表される方向に沿って、ライトからどのくらいの距離でライトが遮られますか?テクスチャ座標は、特定のシャドウマッピングアルゴリズムに応じて、さまざまな射影テクスチャリング手段を使用して生成されます。

射影テクスチャリングは、単にオブジェクトをテクスチャの空間に変換する方法です(そしてもちろん、私はそれが逆に聞こえることを知っています。しかしそれはそれがどのように機能するかです)。シャドウマッピングアルゴリズムは、いくつかの異なる種類の変換を使用します。しかし、最終的には、これらは1つの空間から別の空間への単なる変換です。

シャドウマップをレンダリングするときは、ジオメトリの頂点を取り、標準のレンダリングパイプラインを介してそれらを変換します。ただし、カメラと投影行列は、ビューの位置と方向ではなく、ライトの位置と方向に合わせて設計されています。

シャドウマップを使用してフォワードレンダリングを行う場合は、オブジェクトを通常どおりにレンダリングし、頂点をビューカメラスペースに変換し、ビューの投影行列を通過させます。ただし、ライトカメラと投影マトリックスを介して頂点を変換し、頂点ごとのデータとしてフラグメントシェーダーに渡します。投影テクスチャリングを介してそれらを使用して、シャドウテクスチャにアクセスします。

ここが重要なポイントです。射影テクスチャアクセスは、テクスチャ上でアクセスする場所が、サーフェス上のそのポイント(フラグメントシェーダーでレンダリングしているポイント)とライトの間の方向を表すように設計されています。したがって、レンダリングされるフラグメントでオクルージョンが発生する深度を表すテクセルをフェッチします。

しかし、このパイプラインについて特別なことは何もありません。頂点の位置をシャドウテクスチャに変換してフラグメントシェーダーに渡す必要はありません。ワールドスペースの頂点位置をフラグメントシェーダーに渡し、フラグメントシェーダーにそれらをシャドウテクスチャの射影空間に変換させることができます。確かに、まったく同じテクスチャ座標が得られるので、多くのパフォーマンスを捨てることになります。しかし、それは数学的に実行可能です。

実際、ビューカメラ空間の頂点位置をフラグメントシェーダーに渡すことができます。次に、それらをワールドに変換し、次にライトカメラ空間に変換し、次に射影シャドウテクスチャ空間に変換します。そのすべての変換を1つの行列に入れることができます(影の投影アルゴリズムによって異なります)。繰り返しますが、これにより以前とまったく同じものが得られます。そのため、フォワードレンダリングを実行する理由はありません。

ただし、遅延レンダリングでは、すでにカメラ空間の頂点位置を表示しいます。そうでなければ、照明を行うことができません。あなたはそれらをバッファに書き込むことによって大量のメモリと帯域幅を無駄にしたか、またはあなたは賢く、深度バッファとさまざまな数学を使用してそれらを再計算しました(ここでは説明しませんがオンラインでカバーされています)。

どちらの方法でも、ビューカメラ空間の位置があります。また、前述のように、マトリックスを適用して、ビューカメラ空間からシャドウ投影テクスチャ空間に変換できます。だから...それをしてください。次に、シャドウマップにアクセスします。

問題が解決しました。


(最適化のために)遅延レンダリングでライトごとのジオメトリを除外することは可能ですか?
サマウサ

@Samaursa:「ライトごとのジオメトリを除外する」とは何ですか?シャドウマップに入ってから?点灯してから?
Nicol Bolas

それに関する質問にお答えいただきありがとうございます。他の人のために、彼らが質問/回答にしたい場合:gamedev.stackexchange.com/q/178755/2287
サマウサ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.