web-dev-qa-db-ja.com

OpenGL-深度バッファ値にアクセスする方法は? -または:gl_FragCoord.zvs。テクスチャへのレンダリング深度

ピクセルシェーダーで現在処理されているピクセルの深度バッファー値にアクセスしたい。

どうすればこの目標を達成できますか?基本的に、2つのオプションがあるようです。

  1. テクスチャに深さをレンダリングします。これをどのように行うことができ、トレードオフは何ですか?
  2. Gl_FragCoord.zによって提供された値を使用します-しかし:これは正しい値ですか?
11
0xbadf00d

質問1:フラグメントシェーダーの深度バッファーから直接読み取ることはできません(私がよく知らない最近の拡張機能がない限り)。フレームバッファオブジェクト(FBO)にレンダリングする必要があります。典型的な手順:

  1. FBOを作成してバインドします。以前にFBOを使用したことがない場合は、glGenFramebuffersglBindFramebufferなどの呼び出しを検索します。
  2. カラーバッファとして使用するテクスチャまたはレンダーバッファを作成し、GL_COLOR_ATTACHMENT0またはglFramebufferRenderbufferを使用してFBOのglFramebufferTexture2Dアタッチメントポイントにアタッチします。このレンダリングパスからの深さだけを気にする場合は、これをスキップして、カラーバッファなしでレンダリングできます。
  3. デプステクスチャを作成し、FBOのGL_DEPTH_ATTACHMENTアタッチメントポイントにアタッチします。
  4. 使用したい深さを作成するレンダリングを行います。
  5. glBindFramebufferを使用して、デフォルトのフレームバッファに切り替えます。
  6. デプステクスチャをフラグメントシェーダーで使用されるサンプラーにバインドします。
  7. これで、フラグメントシェーダーは深度テクスチャからサンプリングできます。

質問2:gl_FragCoord.zは、シェーダーが操作しているフラグメントの深度値です。notフラグメント位置の深度バッファーの現在の値です。

25
Reto Koradi

gl_FragCoord.zは、現在のフラグメントのウィンドウスペースの深さの値です。デプスバッファに格納されている値とは関係ありません。フラグメントがdiscardedされておらず、合格した場合、値はlater深度バッファーに書き込まれる可能性がありますステンシル/深度テスト。

技術的には、深さを早期に書き込み/テストするハードウェアの最適化がいくつかありますが、すべての目的と目的のためにgl_FragCoord.zは、デプスバッファに格納されている値ではありません。

複数のパスでレンダリングしない限り、フラグメントシェーダーの深度バッファーの読み取りと書き込みはできません。つまり、深度テクスチャを使用して深度を読み取り、次に向きを変えて新しい深度を書き込むことはできません。これは、フラグメントシェーダーでブレンディングを実装しようとするのと似ていますが、DX11クラスのハードウェアと画像のロード/ストアでエキゾチックなことをしない限り、機能しません。

シャドウマッピングなどで最終的に描画されるシーンの深度のみが必要な場合は、深度のみのプリパスを実行して深度バッファを埋めることができます。 2番目のパスでは、深度バッファーを読み取りますが、書き込みは行いません。

5