8

DirectX初心者として、私は深度バッファ、特に不明瞭なピクセルに対してピクセルシェーダーがどのように呼び出されるかについて頭を抱えようとしています。

私が理解していることから、ラスタライザーは、描画されているプリミティブをカバーしている各ピクセルのピクセルシェーダーを呼び出し、その後、出力マージャーステージの後半で、出力マージャーは深度バッファーをチェックし、バックバッファー内のピクセルを破棄、書き込み、またはブレンドします.

非常に複雑なオブジェクトの前に単純な不透明オブジェクトをレンダリングしている場合、これは無駄に思えるので、複雑なオブジェクトのピクセル シェーダーを呼び出す前に、ラスタライザーに深度マップをチェックさせると便利なようです。

調査を行うと、初期の Z テストや保守的な Z テストなどへの参照が見つかりましたが、それに関するドキュメントもほとんどないようです。ラスタライザー状態記述子オブジェクトでそれを構成する方法を探しましたが、OM 状態記述子でそのようなものしか見つかりませんでした。

これは、DX9 の SetRenderState で設定することも可能だったようです (私は DX9 の経験もありません)。

私の調査によると、これは、オブジェクトを前後にレンダリングする場合に一部のハードウェアが行うことのように思えますが、それは正しいですか? どうすればわかりますか?すべての Control DirectX が提供するので、これを制御できないのは奇妙に思えます。これは、適切な最適化のように思われるためです:)

これに関する情報または参照は感謝されます

4

1 に答える 1

26

深度テストに関する限り、DirectX は深度テストがピクセル シェーダーの後に行われるように見える必要があると述べていますが、実際にそうしなければならないとは述べていません。実際には、初期の z は、多くのメーカーのハードウェアに長年にわたって存在しています。多くの場合、初期 Z のコストを回避するために、個々のピクセルではなく、一度に多くのピクセルの「タイル」で動作する Hierarchical Z と呼ばれる、初期よりもさらに早い形式の Z テストがあります。

初期の Z は、デバイスに設定した特定の状態でオンまたはオフにできるものではありません。ハードウェアは、できるだけ早く Z テストを実行し、ピクセル シェーダーの後以外の場所にあることがわからないようにします。

ただし、ハードウェアが z テストを実行する能力を制限する可能性がある特定のことがあります。ハードウェアが深度値を書き込むかどうかを決定する前にピクセル シェーダーを実行する必要があるため、アルファ テスト、「破棄」(ピクセルを殺す) の使用、およびカバレッジへのアルファはすべて確実に初期 z 書き込みを無効にします。アルファ テスト / 破棄を使用していて、z 書き込みが必要ない場合は、それらをオフにすると、初期 z が利用可能になる可能性が最も高くなります。

初期の Z が必要な場合は、ピクセル シェーダーで「深度」を変更/書き込むことは絶対にできません。この状況では、ハードウェアは初期のテストを実行することさえできません。ピクセル シェーダーで決定したため、初期の z テストも初期の z 書き込みも実行できません。

ピクセル シェーダーから深度を書き込む必要があるが、ラスタライザーが生成した値以上の深度値のみを書き込むことを保証できる場合は、文書化されていないSV_DepthGreater出力セマンティックを使用できます。補間された深さよりも小さい深さの値を書き込まないことを約束しているため、ハードウェアは初期の z テストを試行して実行できますが、ピクセル シェーダーの最後まで z の書き込みを延期します。(SV_DepthLessEqualたまたま逆 z-test/z-buffer を使用している場合は、同等のものがあります)。

z テストはパイプラインの最後で行われるように見える必要があるため、ピクセル シェーダーで UAV を使用すると、早期 z も無効になります。レンダー ターゲットが唯一の出力ではなくなり、DirectX 仕様では最終的に z テストが行​​われるように見える必要があると規定されているため、最終的に z テストに失敗するピクセルに対しても UAV 書き込みが行われる必要があります。このため、[earlydepthstencil]と呼ばれる属性が Shader Model 5 に追加されました。この属性は、UAV 書き込みが発生している場合でも、初期 z が発生しても (可能であれば) 喜んでピクセル シェーダーを実行しないことを DirectX に伝えます。

要約すると、上記の少し風変わりなこと (SV_DEPTH を使用して深度を変更する、カバレッジにアルファを使用する、クリップ/破棄を使用するなど) のいずれも行っていない場合は、初期 Z の利点を既に得ている可能性があります。z-write が必要ない場合は常にオフにし、SV_DEPTH への書き込みは避けてください。

于 2013-07-27T16:44:58.787 に答える