front page placeholder1 placeholder2

14/05/2026: Infinite perspective & Reverse-Z

If youve ever used any renderer, or at the very least played any games, you most likely are familiar with z-fighting, most commonly at long distances:

The reason this happens is because of floating points, they can only have so much precision, and because of how they work: the closer a floating point number is to 0, the more precise it is. Since 0 and 1 represent near and far, respectively, you can see where the problem is.

Luckily, there is an old-school projection trick that saves us from this problem, called reverse-z. what this trick does is basically make 0 represent far pixels, and 1 represent near pixels. this gives far objects plenty of room for depth precision, while kind of sacrificing near depth precision. The main steps we need to take is:

* Make use of a floating point depth buffer;
* Set depth testing to greater;
* If using OpenGL, switch to 0-1 depth range with glClipControl. Sadly, this function is only core part of OpenGL in version >=4.5, luckily the extension (GL_ARB_clip_control) covers around 72.64% of all GPUs in case you wish to use an older version of OpenGL;
* Always clear depth buffer to a value of 0 instead of 1;

After these steps, simply take your desired projection matrix, and swap the near and far values. If you have shaders that read/use depth values, you'll have to adjust them accordingly.
This method is not limited to the main camera, you can use it in shadowmaps for example ! it wont fix shadow acne though.

Now, what is infinite perspective? the name is already pretty self explanatory, its basically a perspective projection with an infinite far plane. The math is rather simple for this:
suppose you have the following projection matrix:

-------------------------------------------------------------------------------------
				

(sorry if this is hard to read) [ focallength / aspect, 0, 0, 0 ], [ 0, focallength, 0, 0 ], [ 0, 0 zfar / (znear - zfar), -1 ], [ 0, 0, -(zfar * znear) / (zfar - znear), 0 ]

-------------------------------------------------------------------------------------

And, suppose zfar's limit goes to infinity (lim zfar --> ∞), then we can solve:
∞ / (znear - ∞);
1 / ((znear / ∞) - 1); (we factor out zfar by dividing all znears with it)
1 / (0 - 1); (every real, constant number that is divided by a number of infinite limit, turns into 0)
1 / -1;
-1
and for the other one:
-(∞ * znear) / (∞ - znear)
-znear / (1 - (znear/∞))
-znear / (1 - 0)
-znear
thus, the infinte projection matrix becomes:

-------------------------------------------------------------------------------------
				

[ focallength / aspect, 0, 0, 0 ], [ 0, focallength, 0, 0 ], [ 0, 0 -1, -1 ], [ 0, 0, -znear, 0 ]

-------------------------------------------------------------------------------------

To use reverse-z and infinite perspective together, simply apply the infinite perspective math after reverse-z(aka swapping near and far planes.)

I'll be linking some articles that discuss these tricks more in depth (ha, get it, depth):

>Tom Hulton: Reverse Z (and why it's so awesome)<
>NVIDIA : Depth Precision Visualized<
>SIGGRAPH 2012 for Just Cause 2<
>Research papers : Tightening the Precision of Perspective Rendering<
>Eric Lengyel at GDC 2007: Projection Matrix Tricks<
>Maximizing Depth Buffer Range and Precision<