Pipeline Gráfico consiste em uma sequência de passos utilizados para criar uma representação raster 2D de uma cena 3D. Claramente falando, uma vez que um modelo 3D foi criado, por exemplo, em um jogo ou qualquer outra animação por computador em 3D, o pipeline de gráficos é o processo de transformar esse modelo em 3D no que o computador exibe.
Cada passo de um pipeline, envolve uma mudança de sistema de coordenadas (mudança de espaço). Consequentemente, iremos usar diversas transformações geométricas para gerar novos sistemas de bases, por isso a importância de representar vértices e transformações por meio de matrizes.
Abaixo temos a imagem que mostra as etapas desse pipeline:
Figura 1. Etapas do Pipeline Gráfico |
Etapas do Pipeline Gráfico
Biblioteca de álgebra linear
Primeiramente é essencial para o desenvolvimento do trabalho, a criação de funções que realizem cálculos algébricos envolvendo vetores e matrizes. As funções criadas para esta finalidade são descritas a seguir:
float norm(const vec4f& v) - Normaliza um vetor.
vec4f normalize(const vec4f v) - Retorna o comprimento de um vetor.
float dot(const vec3f& v1, const vec3f& v2); - Retorna o valor do produto escalar (v1∙v2) entre dois vetores.
vec3f cross(const vec3f& v1, const vec3f& v2); - Realiza o produto vetorial entre dois vetores (v1 × v2).
void setIdentity(Matrix M) - Faz uma matriz M virar uma matriz identidade.
A multiplicação de matriz por matriz foi feita similar a utilizada pela biblioteca glm, utilizando o carácter (*), como por exemplo mat4f *mat4f.
Um objeto em seu estado inicial é dito estar no “espaço do objeto”, e o seu centro está sempre localizado na origem. Ao aplicar em seus vértices transformações geométricas como escala, rotação ou translação, dizemos levar os vértices do espaço do objeto para o “espaço do universo”. A transição entre esses espaços é demonstrada na figura abaixo:
Figura 2. Transformação Espaço do Objeto em Espaço do Universo. |
Para chegarmos a etapa mostrada acima na figura 2 é realizada através da multiplicação dos vértices do objeto descrito em coordenadas do objeto pela matriz de modelagem (model matrix). A matriz de modelagem contém as transformações que se deseja aplicar a determinado objeto, onde cada modelo pode ter a sua própria matriz. Esta matriz pode ser composta por translação, rotação, escala e shear. Caso não seja desejado aplicar nenhuma transformação ao objeto, a matriz de modelagem é a identidade.
Abaixo segue o código da implementação das matrizes de rotação, translação, escala.
As funções Scale e Translate é responsável pela transformação de escala e rotação respectivamente. As matrizes que representam essas transformações são mostradas a seguir:
Abaixo segue o código da implementação das matrizes de rotação, translação, escala.
Figura 5. Implementação Matriz Escala e Translação |
A função Rotate é responsável pela transformação de rotação e sua implementação necessitou um pouco mais de atenção que as anteriores. Isso por que o objeto pode ser rotacionado em cada um dos eixos x, y e z. Para cada uma das rotações possíveis, existe uma matriz diferente para representá-la. Essas matrizes são mostradas nas figuras a seguir e posteriormente o código da implementação dessas matrizes:
Figura 6. Matriz de Rotação Eixo X |
Figura 7. Matriz de Rotação Eixo Y |
Figura 8. Matriz de Rotação Eixo Z |
Figura 9. Implementação da Matriz de Rotação nos Eixos X,Y,Z |
O próximo passo é levar o objeto agora no espaço do universo para o espaço da câmera, para isso devemos definir de onde serão visualizados os objetos, ou seja, quais as coordenadas da câmera e para onde ela está olhando. Na verdade a câmera estará sempre localizada na origem olhando para o sentido negativo do eixo z. O que muda são as coordenadas dos vértices dos objetos, que passam por uma mudança de sistema de coordenadas. Quando este processo ocorre, dizemos levar os vértices do espaço do universo paro o “espaço da câmera”.
Para “mudar” a posição da câmera, basta definir o ponto no espaço em que ela deverá estar, e nesse ponto definir uma base ortonormal. Situação mostrada na imagem a seguir:
Figura 10. Definição base da cãmera |
Em seguida, realiza-se sobre as coordenadas dos vértices o processo chamado de “mudança de base”, que irá levar os vértices para o sistema de coordenadas definido pela base da câmera. Ao final, teremos uma situação similar à mostrada na figura a seguir:
Figura 11. Objeto Espaço da Câmera |
O processo de levar os vértices do espaço do universo para o espaço da câmera é realizado multiplicando-os por uma matriz especial chamada view. A função LookAt foi implementada com a finalidade de montar esta matriz, sua implementação é mostrada a seguir:
Figura 12. Implementação da Matriz View |
Agora os vértices serão multiplicados por uma matriz especial chamada projection. Essa matriz leva os vértices do espaço da câmera para o “espaço de recorte”. A multiplicação por essa matriz irá definir o tipo de projeção, podendo ser ortogonal ou perspectiva. A projeção perspectiva permite a sensação de profundidade dos objetos na tela, o mesmo não ocorre com a projeção ortogonal. Outro detalhe é que a projeção ortogonal preserva o paralelismo das retas, já a projeção perspectiva não. A figura abaixo exemplifica estas situações.
Figura 13. Projeção Ortogonal e Projeção Perspectiva |
A matriz de projeção simples leva em consideração somente a distância do view plane, também chamado de far plane. A matriz que representa essa projeção é mostrada a seguir:
A matriz de projeção completa leva em consideração o near plane, o far plane, e também as dimensões do near plane. Esta matriz permite que os pontos estejam no espaço canônico logo após a divisão por w. A matriz utilizada pela opengl para projeção perpectiva é mostrada a seguir:
O valores de n, f, l, r, b e t são como mostrados da figura abaixo:Figura 16. Frustum |
Figura 17. Implementação do Frustum e da Projeção Perspectiva |
Espaço Canônico → Espaço da Tela
No espaço canônico é garantido que todos os vértices da cena visível possui os valores de suas coordenadas entre -1 e 1. Este espaço é obtido quando, após multiplicar os vértices pelas matrizes model, view e projection, dividi-se as coordenadas dos vétices por sua coordenada w (coordenada homogênea).
Após os espaço canônico é preciso preparar os vértices para serem rasteirados na tela. Este processo e feito multiplicando os vértice por uma matriz chamada viewport. Essa matriz leva os vértices do espaço canônico para o “espaço da tela e é formada pela multiplicação da matrizes mostradas na figura abaixo:
Figura 18. Multiplicação de matrizes que gera a viewport |
Na imagem acima, w é o número de colunas de pixels da tela e h o número de linhas de pixel da tela. Estas matrizes consistem em duas escalas e uma translação. Uma das escalas é para inverter as coordenadas y dos vértices, pois na tela o eixo y cresce para baixo. A outra escala é pra fazer com que todo os espaço entre 1 e -1 fique nas mesmas dimensões da tela. E a translação é para levar os objetos para o centro da tela. A função implementada para montar a matriz viewport é mostrada a seguir:
Figura 19. Implementação da viewport |
Por último utilizando conceitos anteriores de rasterização e carregando um objeto, será rasterizado na tela, passando por cada um dos espaços mostrados anteriormente:
Figura 20. Função de Rasterização do Objeto |
Simulações
Dificuldades encontradas:
Uma das dificuldades encontradas foi configurar as bibliotecas a serem utilizadas na IDE onde foi desenvolvido o trabalho.
Referências bibliográficas:
O vídeo 1 mostra a simulação realizada utilizando a matriz de projeção simples que leva somente o far plane em consideração.
Vídeo 1
O vídeo 2 mostra a comparação entre o Pipeline Gráfico implementado com o Pipeline Gráfico utilizado pela OpenGl. A janela da esquerda é a rasterização implementada no trabalho, e a janela da direita, a rasterização da opengl.
Vídeo 2
Uma das dificuldades encontradas foi configurar as bibliotecas a serem utilizadas na IDE onde foi desenvolvido o trabalho.
Referências bibliográficas:
PAGOT, C. A. Geometric Transformations. Universidade Federal da Paraíba. Junho de 2015. Disponível em: <http://presencial.virtual.ufpb.br/pluginfile.php/30803/mod_resource/content/1/6_geometric_transformations.pdf> Acesso em: Junho de 2015.
PAGOT, C. A. Change of Coordinate System. Universidade Federal da Paraíba. Junho de 2015. Disponível em: <http://presencial.virtual.ufpb.br/pluginfile.php/30800/mod_resource/content/1/7_coordinate_system_change.pdf> Acesso em: Junho de 2015.
PAGOT, C. A. Modeling and View Transform. Universidade Federal da Paraíba. Junho de 2015. Disponível em: <http://presencial.virtual.ufpb.br/pluginfile.php/30801/mod_resource/content/1/8_model_view_transform.pdf> Acesso em: Junho de 2015.
PAGOT, C. A. Projection Transform. Universidade Federal da Paraíba. Junho de 2015. Disponível em: <http://presencial.virtual.ufpb.br/pluginfile.php/30805/mod_resource/content/1/9_projection_transform.pdf> Acesso em: Junho de 2015.
PAGOT, C. A. Canonical and Screen Space. Universidade Federal da Paraíba. Junho de 2015. Disponível em: <http://presencial.virtual.ufpb.br/pluginfile.php/31860/mod_resource/content/1/10_canonical_screen_space.pdf> Acesso em: Junho de 2015.