# How to understand Z-Fighting?

I searched for Z Buffer on Google and I discovered that's a 2 dimensional array used by the graphical card and whose aim is to enable the handling of two pixels' depth in order to display one of these pixels in front of the other.

To illustrate my words, let an image which has only 1 pixel.

# What is a Z-Buffer? What is its utility?

## Introduction

Let $P_1$ be the pixel we want to draw in front of $P_2$ (thus, $P_1$ will hide $P_2$ at drawing). So $P_1$ and $P_2$ have the same $X$ and $Y$ coordinates.

We decide that the $Z$ coordinate of $P_1$ (ie. its depth) is less than $P_2$'s one (it means $P_1$ is closer to the computer's user than $P_2$): $Z(P_1) = 1$, and $Z(P_2) = 2$.

Our Z-Buffer has, by definition, the same size as our image: 1 case. Each case of the Z-Buffer contains one pixel's depth and each case is associated with one image's pixel.

First, we initialize the (only one) case of our Z Buffer at the maximum value we can store in its cases (depending on the Z Buffer's type, on the OS, etc.: double/float/integer).

## $P_1$

Now, we want to first draw $P_1$. The Z Buffer is used: the depth of the $(X(P_1); Y(P_1))$ case's value is compared to the $P_1$'s depth. Of course, $Z(P_1)$ is lesser than $Z( (X(P_1) ; Y(P_1)) )$. The results of this comparison are: first, we replace the old case value with the new $Z$ value (which is: $Z(P_1)$ ); then, $P_1$ is drawn.

# $P_2$

Finally, we want to draw $P_2$. Again the Z Buffer is used. $(X(P_2); Y(P_2))$ case's value is compared to $Z(P_2)$ (note that: $X(P_2) = X(P_1)$ and $Y(P_2) = Y(P_1)$ - cf. "So $P_1$ and $P_2$ have the same $X$ and $Y$ coordinates."). The results of this comparison are: $(Z(P_2) = 2)$ is superior to $( Z( (X(P_2); Y(P_2)) ) = 1)$; first, we don't replace any case; then, $P_2$ is not drawn.

That's how a Z Buffer is used to display a pixel in front of another.

## Example of application

http://raphaello.univ-fcomte.fr/IG/ZBuffer/Images/ZBuffer-03.gif

# Z-Fighting

## What is Z-Fighting?

If two polygons are very closed AND (note the "AND") if the camera is moving, Z-Fighting phenomenon appears: https://icculus.org/neverball/mapping/zfighting.png

## How to reproduce Z-Fighting (ie. how does it work? why does it appear?)

I know Z Fighting is caused by the resolution in depth of the Z Buffer, due to some conversion/casts mathematical and precision errors. But I don't understand it...

In particular, I don't understand why the camera must move.

My question is: could you explain this please?

• What is with all that mathematics that nobody understands
– user11352
Oct 22 '19 at 21:19

The camera does not need to move for this problem to exist. You can see the mixed polygons as in your linked image even with a static camera.

Things are worse with a moving camera because it makes the position of the polygons change, which can lead to different rounding. This means it may not be the same polygon which comes up in front at a given location for every frame. Even a very small change in the camera could swap which polygon is visible. So you get flickering which is visually a lot worse because it draws attention.

One possible solution is to progressively blend surfaces together when their Z values become too similar. However, I'm not certain how easily that can be implemented in traditional Z-buffer rendering.

Z-fighting is not related with camera movement. But this issue can be avoided by moving the near plane of the view frustum a little further away from the viewer. As you know, depth testing is the stage in the graphics pipeline which is used to determine whether one pixel is in front or back of the other pixel. It is done by having a buffer known as the z-buffer which stores z values (distance from the viewer) for each fragment. Z-fighting happens when the depth buffer doesn't have enough enough floating point precision to compare two very close z values. Sometimes two z values are so close to each other that they need higher precision to be compared. This tutorial explains everything in a simple way about Depth testing and Z-fighting and also discusses about the solutions to avoid them.

As others mentioned, z-fighting/stiching occurs even if the camera is not moving. However, when the camera is moving and you're getting z-fighting, it will appear as though the polygons are flickering.

This link helped me to understand the depth buffer much better. Here he generates depth values and simulates the different kinds of precision errors you would get depending on your depth buffer format (graphics APIs usually let you request a depth buffer format). "indist" and "swaps" are both precision errors, and can cause the z-fighting to appear.