2.1 El Renderizado Pipeline

El proceso completo de visualización de una escena 3D se conoce como pipeline de rendering. Hay muchos tipos de renderizado según la tecnología que se utilice: ray-tracing, Z-buffer, etc., e incluso soluciones mixtas. El tipo que se presenta aquí es el implementado en el hardware gráfico actual, y que está basado en el algoritmo Z-buffer y en una parte de la especificación de la librería OpenGL, cuyo sistema de rendering en tiempo real ha sido el más popular desde su aparición. Las distintas etapas en las que puede dividirse el pipeline de rendering pueden agruparse en tres grandes grupos funcionales: el procesamiento geométrico, la rasterización y las operaciones finales sobre pixels. La forma en que se implementa el pipeline de rendering depende del hardware y en cierta medida del software que lo utiliza.

La aplicación 3D envía a la GPU una secuencia de vértices y una secuencia de primitivas geométricas, normalmente puntos, líneas y polígonos. Cada vértice tiene una posición en el espacio y una serie de atributos como color, coordenadas de textura, vector normal, etc. Hay que recordar que el vector normal indica la dirección perpendicular a la superficie en el vértice asociado, y suele utilizarse para cálculos de iluminación.

Pipeline

 

La etapa de procesamiento geométrico se encarga de calcular las transformaciones lineales de los vértices que componen los elementos geométricos de la escena. Esto incluye las rotaciones, traslaciones, escalados y proyecciones de los vértices. En esta etapa se incluyen cálculos adicionales como la iluminación a nivel de vértice. A esta etapa se la conoce como de transformación e iluminación o T&L (Transform and Lighting). Los pasos ordenados son: creación de primitivas, transformación de entidades, transformación de perspectiva, transformación de la vista, recorte de primitivas con el volumen de visión e iluminación.

 

En la etapa de rasterización se obtiene una lista de fragmentos por cada primitiva enviada al pipeline gráfico y que utiliza vértices ya procesados en la fase anterior. Cada fragmento ocupa una posición en el buffer donde se almacena la imagen resultado, y puede considerarse como un futuro pixel. Cada primitiva (puntos, líneas y triángulos principalmente) ocupa una serie de posiciones en el buffer y genera los correspondientes fragmentos. Para cada uno de ellos hay asociadas propiedades como colores, profundidad, coordenadas de texturas, etc., que son obtenidas a partir de los datos de los vértices de la primitiva mediante interpolación.

 

La etapa final del proceso se encarga de operar sobre los fragmentos para calcular las propiedades de los pixels que componen el resultado del rendering. Estas operaciones son una parte estándar de OpenGL y Direct3D. Durante esta fase se eliminan las superficies ocultas mediante la comparación de profundidad (deplh test).

 

Las operaciones realizadas durante esta etapa modifican las propiedades de cada fragmento, como el color, la profundidad, la posición del pixel final y otros valores asociados. Si alguno de los tests falla, como el de profundidad o el de recorte, el fragmento es descartado y no se genera un pixel en el framebuffer. Funciones como el blending, el dithering o las operaciones lógicas implican una modificación de la imagen en función de los valores acumulados en este. Tras esta etapa, cada fragmento que ha pasado los tests pertinentes genera un pixels que es almacenado en la imagen final (framebuffer).