4 Pipeline gráfico

O pipeline gráfico ou pipeline de renderização é um modelo conceitual de descrição da sequência de passos que a GPU utiliza para transformar um modelo matemático em uma imagem digital. O termo “pipeline” é utilizado porque o processamento é realizado em uma sequência de etapas alimentadas por um fluxo de dados, sendo que cada etapa processa novos dados tão logo tenha enviado a saída à etapa seguinte.

Algumas etapas de processamento do pipeline podem ser programadas por shaders. Outras etapas são fixas e não podem ser programadas.

A aplicação é responsável por configurar previamente os dados gráficos na memória acessada pela GPU antes de dar início ao processamento do pipeline. Em geral, os dados gráficos descrevem elementos de uma cena tridimensional tais como representações dos objetos da cena, descrição de materiais e fontes de luz, além de transformações geométricas que podem ser utilizadas para definir como os objetos serão dispostos no espaço e projetados no plano de imagem de uma câmera virtual.

As superfícies dos objetos de uma cena são geralmente representadas por malhas de triângulos. Para cada superfície podem ser associados atributos que descrevem suas propriedades, como por exemplo as propriedades físicas do material que a superfície pretende simular. Os shaders podem ler esses atributos e simular a interação entre cada superfície com a luz emitida pelas fontes de luz ou refletida de outras superfícies.

Além dos dados que descrevem a cena, a aplicação também é responsável por inicializar o pipeline com os shaders que serão utilizados durante a renderização. O pipeline é iniciado pela aplicação através de um ou mais comandos de desenho (draw calls). Esse processamento do pipeline na GPU é realizado de forma assíncrona com a CPU.

O pipeline típico especificado pelas APIs gráficas envolve etapas que compreendem o processamento geométrico, a rasterização e o processamento de fragmentos (figura 4.1):

Etapas de um pipeline gráfico.

Figura 4.1: Etapas de um pipeline gráfico.

  1. Processamento geométrico: envolve operações realizadas sobre vértices, como transformações afins e transformações projetivas que serão abordadas em capítulos futuros. O processamento geométrico pode envolver também a criação de geometria e o refinamento de malhas. Ao final desse processamento é feito o recorte ou descarte das primitivas geométricas que estão fora de um volume de visualização.

  2. Rasterização: compreende a conversão matricial das primitivas. O resultado é um conjunto de amostras de primitivas. Durante o processamento no pipeline, o termo fragmento é frequentemente utilizado para designar essas amostras no lugar de pixel. Cada fragmento é uma coleção de valores que inclui atributos interpolados a partir dos vértices e a posição \((x,y,z)\) da amostra em coordenadas da janela (o valor \(z\) é considerado a “profundidade” do fragmento). O pixel é o valor final da cor no buffer de cor, que pode ser uma combinação da cor de vários fragmentos.

  3. Processamento de fragmentos: envolve operações realizadas sobre cada fragmento para determinar sua cor e outros atributos. A cor pode ser determinada através da avaliação de modelos de iluminação que levam em conta os atributos de iluminação fornecidos pela aplicação, tais como atributos das fontes de luz, e descrições de detalhes das superfícies através de mapas de bits chamados de texturas. Após essas operações são realizados testes de descarte de fragmentos e combinação de cores entre os fragmentos processados e os pixels já existentes no framebuffer. O resultado é armazenado em diferentes buffers do framebuffer: buffers de cor, buffer de profundidade e buffer de estêncil.