I have trouble applying early depth test in my engine, to prevent fragment shader to be (fully) executed for fragments that will be overwritten anyway, because other fragments, drawn later, will be in front of them.
First, I do a depth only pass and write its result to a texture. This step seems correct (I already use it for SSAO).
Second, I do the main rendering pass. Here, each fragment shader begins by comparing the current depth value to the early depth test value, every fragment being further than the early depth test value being discarded.
My implementation (see below) makes me loose performance, and wrongly discards fragments depending of the epsilon used to compare the depth values. Any idea of what I do wrong?
I use OpenGL 3.3, in a forward rendering engine.
Relevant fragment shader code:
float linearize_depth(float depth,float near,float far)
{
float ndc = depth * 2.0 - 1.0;
float linearDepth = (2.0 * near * far) / (far + near - ndc * (far - near));
return linearDepth;
}
void earlyDepthTest(vec2 fragPos, vec2 screenRes)
{
vec2 res = gl_FragCoord.xy / vec2(800, 800);
float earlyDepthNormalized = linearize_depth(texture(cameraDepthMapTexture, res).r, 0.1, 1024.0);
float currentDepthNormalized = linearize_depth(gl_FragCoord.z, 0.1, 1024.0);
float depthDifference = currentDepthNormalized - earlyDepthNormalized;
if(depthDifference > 0.1)
discard;
}
void main()
{
earlyDepthTest(gl_FragCoord.xy, vec2(800, 800));
// All fragment shader processing
}