Skip to content
Depth Test & Z-Buffer
step 1/5

Reading — step 1 of 5

Read

~2 min readRasterization

Depth Test & Z-Buffer

Multiple triangles cover the same pixel. Which one to draw? The one CLOSEST to the camera.

Z-buffer (depth buffer): per-pixel depth value.

Algorithm:

  1. Initialize Z-buffer to ∞ (or 1 in NDC).
  2. For each triangle, for each covered pixel:
    • Compute interpolated depth.
    • Compare to Z-buffer.
    • If closer: update both Z-buffer and pixel.

Memory:

  • Z-buffer: same dimensions as frame buffer.
  • Per pixel: 16-32 bit depth value.
  • 1920x1080x24 bits = ~6 MiB.
python

Convention: usually z=0 near plane, z=1 far plane. Smaller z = closer.

Hidden surface removal:

  • Z-buffer is "image-space" approach: per-pixel.
  • "Object-space" alternatives exist (BSP trees) but are more complex.
  • Z-buffer is simple + parallelizable.

Z-fighting:

  • Two surfaces at exactly same depth → flickering.
  • Numerical precision issue.
  • Solutions:
    • Higher precision Z-buffer.
    • Polygon offset (slight push).
    • Sort opaque vs transparent properly.

Reverse Z:

  • Modern: use 1/z for better precision distribution.
  • Allows huge view distances without z-fighting.

Early Z:

  • GPU optimization: reject pixels by depth before running fragment shader.
  • 2-3x speedup for occluded geometry.

Depth pre-pass:

  • Render scene with only depth (no color).
  • Then render again with color, using early Z.
  • Skip fragment shader for occluded pixels.
  • AAA optimization.

Occlusion culling:

  • Higher level: don't even submit hidden objects to GPU.
  • Frustum culling: reject objects outside view.
  • Hierarchical Z-buffer (HiZ).
  • Used in modern engines.

Test:

python

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…