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
ですか? それとも深度テクスチャが問題ですか?間違ったフォーマット?私が気付いていないコンバージョンが発生していますか?