# Z-buffer

En los gráficos por computadora, el z-buffering es la parte de la memoria de un adaptador de video encargada de gestionar las coordenadas de profundidad de las imágenes en los gráficos en tres dimensiones (3-D), normalmente calculados por hardware y algunas veces por software. Es una de las soluciones al problema de visibilidad, que es el problema de decidir qué elementos de una escena renderizada son visibles y cuáles ocultos. El algoritmo del pintor es otra solución común, aunque menos eficiente, también puede manejar escenas con elementos no opacos. El Z-buffering también se conoce como buffering de profundidad.
Cuando un objeto es dibujado por una tarjeta gráfica 3D, la profundidad del píxel generado (coordenada z) se almacena en un búfer de datos (el z-buffer). Este búfer se suele distribuir como un array de 2 dimensiones (x-y) con un elemento por cada pixel de la pantalla. Si algún otro objeto de la escena se tiene que renderizar en el mismo pixel, la tarjeta gráfica compara las dos profundidades y elige el más cercano al observador. La profundidad elegida es entonces salvada en el z-buffer, reemplazando a la antigua. Al final, el z-buffer permitirá a la tarjeta gráfica reproducir correctamente la percepción de la profundidad normal: los objetos cercanos ocultan a los más lejanos. Este efecto se denomina Z-Culling.
La granuralidad de un z-buffer tiene una gran influencia en la calidad de la escena: un z-buffer de 16 bits puede producir un Artefacto (llamado "Z-fighting") cuando dos objetos están muy próximos. Un z-buffer de 24 bits o 32 bits se comporta mucho mejor. Un z-buffer de 8 bits no se utiliza casi nunca ya que tiene muy poca precisión.

## Desarrollos

Incluso con suficiente granularidad, los problemas de calidad pueden aparecer cuando la precisión en los valores de distancia del z-buffer no se distribuye por igual. Los valores más cercanos son más precisos (y así pueden mostrar objetos próximos mejor) que los más lejanos. Normalmente esto es deseable, pero puede causar artefactos pareciendo que los objetos parezcan más distantes. Existe una variación del z-buffer cuya precisión de los resultados están mejor distribuidos, esta se llama w-buffer (ver debajo).
Al dibujar una nueva escena, el z-buffer debe limpiarse a un valor definido, normalmente 1.0, porque este valor es el límite superior de profundidad para una escala del 0 al 1. Esto significa que no hay objetos más alejados en ese punto en el frustum de visión.
La invención del concepto de z-buffer se le suele asignar a Edwin Catmull. Realmente también Wolfgang Straßer describió esta idea en su tesis doctoral de 1974.
En las tarjetas gráficas de los PC recientes (1999-2005), la gestión del z-buffer utiliza una porción significativa del ancho de banda de la memoria disponible del sistema. Se han empleado varios métodos para reducir este impacto, tales como compresión sin pérdida (los recursos del ordenador para comprimir y descomprimir son más baratos que el ancho de banda) y hardware ultra-rápido z-clear que utiliza el truco obsoleto de "un frame positivo, un frame negativo" (saltando los frame intermedios utilizando números con signo para comprobar la profundidad inteligentemente).

## Z-Culling

En renderización, la Z-Culling es la eliminación temprana de un píxel basada en la profundidad, un método que provee un incremento en el rendimiento cuando la renderización de superficies ocultas es costosa. Es una consecuencia directa del Z-buffering, donde la profundidad de cada píxel candidato es comparada con la profundidad de la geometría existente detrás de la cual puede estar oculto.
Cuando se utiliza el z-buffer, un pixel puede ser seleccionado (descartado) tan pronto como sea conocida su profundidad, lo que hace posible saltar el proceso completo de alumbrar y calcular la textura de un pixel que no sería visible de todas formas. También, se reducirá el consumo de tiempo del shader que generalmente no se ejecutará para los píxeles descartados. Esto hace que el z-culling sea un buen candidato a optimización en situaciones donde la tasa de frames, la luz, el cálculo de texturas o el sombreador de píxeles son el principal cuello de botella.
Mientras el z-buffering permite que la geometría no está clasificada, los polígonos clasificados por profundidad creciente (así se utiliza un algoritmo del pintor inverso]]) permite a cada píxel de la pantalla ser renderizado sólo una vez. Esto puede aumentar el rendimiento en escenas con tasa de frames limitada con grandes sumas de descubiertos.

## Modelo matemático

El rango de los valores de profundidad en el espacio de referencias de la cámara (Proyección 3D) a ser renderizado está normalmente definido entre un valor cercano, ${\mathit {near}}\,$ y otro lejano ${\mathit {far}}\,$ de $z\,$. Después de una transformación de perspectiva, el nuevo valor de $z\,$, o $z'\,$, está definido por:
$z'={\frac {{\mathit {far}}+{\mathit {near}}}{{\mathit {far}}-{\mathit {near}}}}+{\frac {1}{z}}\left({\frac {-2\cdot {\mathit {far}}\cdot {\mathit {near}}}{{\mathit {far}}-{\mathit {near}}}}\right)$
Donde $z\,$ es el valor antiguo de $z\,$ en el espacio de la cámara y a veces llamado $w\,$ o $w'\,$.
Los valores resultantes de $z'$ están normalizados entre los valores -1 y 1, donde el plano cercano ($near\,$) está en -1 y el lejano ($far\,$) en 1. Los valores fuera de este rango corresponden a puntos que no están en el frustum de visión y no serán pintados.
Para implementar un z-buffer, los valores de $z'\,$ son interpolados linealmente Linear_interpolation a lo largo del espacio de la pantalla entre los vértices de los polígonos. Estos valores intermedios se suelen almacenar en el z-buffer en coma flotante. Los valores de $z'\,$ se agrupan más densamente cerca del plano cercano ($near\,$) y más esparcidos en el resto de la escena, resultando una precisión mayor cerca de la cámara. Cuanto más cerca está el plano cercano a la cámara, menor precisión hay en el resto de la escena.

### W-buffer

Para implementar un w-buffer, los valores antiguos de $z$ en el espacio de la cámara, o $w$, se almacenan en el buffer, generalmente en formato de coma flotante. Sin embargo, estos valores no se pueden interpolar linealmente en el espacio de la cámara desde los vértices ya que normalmente deben invertirse, interpolarse e invertirse de nuevo. Los valores resultantes de $w$ son los opuestos de $z'$ que están equiespaciados entre $near$ y $far$. Hay implementaciones del W-buffer que evitan la inversión.
Dependiendo de la aplicación se obtendrán mejores resultados con un z-buffer que con un w-buffer y viceversa.