This is a proof of concept of implementing a reversed z projection matrix, optionally with an infinite far plane. This also changes the depth buffer format from D32 to D32F.
The fabulous graphics mod has been modified to work with rev-z, as such it doesn't it's now broken in vanilla.
In game you can toggle the following using key-binds:
Y- Vanilla Override (Disables all changes)U- Floating Point Depth BufferI- Infinite Far ZO- Zero to One Depth RangeP- Reverse Z
To get the best results, you should enable all of them.
Note: View Bobbing and Nausea won't work correctly because I'm lazy, see FrustumMixin
For demonstration purposes I've also removed all fog.
To see the differences for yourself I recommend using waterlogged leaves at ~128 blocks and looking at them through a spyglass. With vanilla rendering there is obvious z-fighting, with rev-z and inf-z there isn't any.
The implementation in this mod is quite hacky, as it is just a PoC, but a proper implementation woudn't be much different.
These are te changes:
- Uses of
GL_DEPTH_COMPONENT32have been replaced withGL_DEPTH_COMPONENT32F - The depth clip range is changed from
GL_NEGATIVE_ONE_TO_ONEtoGL_ZERO_TO_ONEwithglClipControl(GL45.GL_LOWER_LEFT, GL45.GL_ZERO_TO_ONE) - Orthographic and perspective projection matrices have been adjusted for the zero to one range
- The orthographic projection matrix's near and far z value have been swapped/reversed
- All calls to
glClearDepthhave their depth parameter reversed - All calls to
glDepthFunchave their comparison parameter reversed transparency.fshhas been adjusted to use1.0 - depthfor all depth values.
This PoC shows that the change from normal to reversed Z is relatively simple. But the result is a big improvement to z-fighting.
Further more using an infinite far plane actually improves depth precision even further, and has the obvious added benefit of no far z clipping.
The use of reversed Z is only really sensible when a floating point depth buffer is used and the clip depth range is zero to one.
To change the depth range glClipControl is required. It was added by OpenGL 4.5 but is available with the extension ARB_clip_control.
The availability is sadly still limited, opengl.gpuinfo.org reports a 72.1% coverage.
However, there are two very obvious, simply fallbacks for systems that do not support it:
- Use the -1 to 1 depth range, reverse z, and a fixed point depth buffer, with the same depth distribution as vanilla
- Use the -1 to 1 depth range, reverse z, and a floating point depth buffer, with suboptimal precision distribution
Set farz.fallback to any value to disable zero-to-one depth and the floating point depth buffer, but keep reverse z.
https://developer.nvidia.com/blog/visualizing-depth-precision/
https://iolite-engine.com/blog_posts/reverse_z_cheatsheet
https://tomhultonharrop.com/mathematics/graphics/2023/08/06/reverse-z.html
https://www.terathon.com/gdc07_lengyel.pdf
Sodium also thought about implementing reverse-z, but decided against it because of mod compatibility. This is part of the reason why it would be good to have in the base game.
Waterlogged leaves at a distance of 128 blocks
At 512 blocks away (maximum vanilla view distance) there is also no z-fighting with reversed z.
To see the effects of the infinite far z teleport up (f.e. 1.000.000 blocks), and look down with a spy glass and the smallest fov. You'll still be able to see the clouds. (Set the time to midnight! You can't see them white-on-white at noon.)




