5

2 つのジオメトリ パスがあります。glBlendEquation(GL_MIN)最初のパスでは、デュアル デプス ピーリングと同様に、フラグメントのデプス値を float テクスチャに書き込みます。2 番目のパスでは、フラグメント シェーダーでの初期深度テストに使用します。

ただし、一部のフラグメントでは、深度の最小値を少しオフセットしない限り、深度テストが失敗します (eps以下を参照)。

ここに画像の説明を入力

テクスチャの設定:

glBindTexture(GL_TEXTURE_2D, offscreenDepthMapTextureId);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, screenWidth, screenHeight);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, offscreenDepthMapFboId);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  offscreenDepthMapTextureId, 0);

テクスチャは深度アタッチメントではなく、カラー アタッチメントとして使用されることに注意してください。GL_DEPTH_TEST最終パスでは使用できないため、両方のパスで無効にしました。

両方のパスで使用される頂点シェーダー:

#version 430

layout(location = 0) in vec4 position;

uniform mat4 mvp;
invariant gl_Position;

void main()
{
  gl_Position = mvp * position;
}

最初のパス フラグメント シェーダーはoffscreenDepthMapFboIdバインドされているため、深さを色としてテクスチャに書き込みます。ブレンディングにより、最小値のみが赤のコンポーネントになります。

#version 430

out vec4 outputColor;

void main()
{
  outputColor.rg = vec2(gl_FragCoord.z, -gl_FragCoord.z);
}

2 番目のパス、デフォルトのフレームバッファへの書き込み。テクスチャは として使用されdepthTexます。

#version 430

out vec4 outputColor;

uniform sampler2D depthTex;

void main()
{
  vec2 zwMinMax = texelFetch(depthTex, ivec2(gl_FragCoord.xy), 0).rg;
  float zwMin = zwMinMax.r;
  float zwMax = -zwMinMax.g;
  float eps = 0;// doesn't work
  //float eps = 0.0000001; // works
  if (gl_FragCoord.z > zwMin + eps)
    discard;
  outputColor = vec4(1, 0, 0, 1);
}

頂点シェーダーの不変修飾子は役に立ちませんでした。この特定の値が常に機能するかどうか確信が持てないため、使用eps = 0.0000001は大雑把な回避策のように思えます。2 つのシェーダーでまったく同じものを生成するにはどうすればよいgl_FragCoord.zですか? それとも深度テクスチャが問題ですか?間違ったフォーマット?私が気付いていないコンバージョンが発生していますか?

4

2 に答える 2

1

インシェーダー比較アプローチの代わりに glDepthFunc(GL_EQUAL) を試しましたか? 同じパスで同じ深度テクスチャを読み書きしていますか?

gl_FragCoord の形式と精度が深度バッファのものと相関しているかどうかはわかりません。また、ドライバーの不具合かもしれませんが、 glDepthFunc(GL_EQUAL) は期待どおりに動作するはずです。

于 2013-06-23T20:52:52.780 に答える
0

gl_FragCoord.z を深度値として使用しないでください。

頂点シェーダー:

out float depth;

void main()
{
   ...
   depth = ((gl_DepthRange.diff * (gl_Position.z / glPosition.w)) + 
             gl_DepthRange.near + gl_DepthRange.far) / 2.0;
}
于 2013-10-24T12:10:15.607 に答える