- The game runs slower the more we depth-test
= "the more overdraw we add"? That would of course be expected, as more pixels = more work, especially for a shitty integrated laptop GPU.
That being said, depth testing with 3D geometry usually improves performance as the depth test can run before the fragment shader, allowing the GPU to avoid running the fragment shader for occluded pixels. This depends on two things to work:
- If the shader writes to gl_FragDepth, the shader implicitly has to run before the depth test as it determines the value used in the comparison. This has VERY significant performance implications.
- If discard; is used, the early depth test's functionality is severely limited as it cannot update the value in the depth buffer until the shader has executed or it would write depth for discarded pixels. This again can have performance implications, but usually not as severe as an early depth test can still be run against previously drawn geometry, potentially avoiding shader execution, but this has to be much more conservative.
You should never write to gl_FragDepth if you can avoid it since it disables so many important optimizations. If your geometry is flat, then simply outputting the depth to the vertices will give you the same result but allow all the optimizations to work as expected. If you however for some reason need non-linear per-pixel depth, there are still things you can do to improve performance. If you are able to calculate the minimum depth (the depth value closest to the camera), you're able to output that as a conservative depth value in the vertex shader. You can then in the fragment shader specify how exactly you will modify the depth value of gl_FragDepth to allow the GPU to run a conservative depth test against the hardware computed depth (the one you outputted from the vertex shader). You always want to modify the depth in the OPPOSITE way that you're testing it. Example:
- You use GL_LESS for depth testing and the depth is cleared to 1.0.
- You output the MINIMUM depth that the polygon can possibly have from the vertex shader.
- In the fragment shader, you specify that the depth value will always be GREATER than the hardware computed value using
layout (depth_greater) out float gl_FragDepth;
This will allow your GPU to run a conservative depth test using the hardware computed depth value, at least giving the GPU a chance (similar to when discard; is used) of culling things before running the fragment shader. This feature requires hardware compatibility though, but GL_ARB_conservative_depth is available on all OGL3 GPUs as an extension, even Intel, plus OGL2 Nvidia GPUs. Additionally, this can be queried in the GLSL shader and be enabled if available, and won't cause any damage if it isn't available at least (at least if you skip computing the minimum depth in vertex shader as well).
Clearing the screen to 0.0 would cause nothing to ever pass the depth test if you use standard GL_LESS depth testing. I'd strongly suggest using GL_LESS and clearing to 1.0 instead as that is the standard way of using a depth buffer, which in some cases could be faster in hardware.
If you could specify some more information about your use case, I could give you better advice and more information.