Páginas

quinta-feira, 5 de maio de 2016

Pipeline Gráfico

Pipeline gráfico na computação gráfica é a sequência de passos que deve ser seguida para criar uma representação 2D de uma cena 3D, ou seja, uma vez que um modelo 3D foi criado, o pipeline gráfico é o processo de transformar esse modelo 3D no que o computador exibe.


Espaço objeto  para o Espaço universo (Model)

Esta etapa é responsável pela transição do sistema de coordenadas do objeto para o sistemas de coordenadas 3D e contem todos os objetos para formar a cena,  para posicionar o modelo no universo é necessário que ocorram transformações geométricas e para que isso ocorra será utilizada uma matriz model.



A matriz model é composta pelas transformações de translação, rotação e escala, onde sua matriz é a multiplicação das matrizes dessas transformações geométricas.



Espaço universo  para o Espaço câmera ( View)


Essa etapa é responsável por modificar e carregar os objetos para atender as configurações da câmera. Para isso utilizaremos a matriz view que é responsável pela posição da câmera e para onde ela aponta, para isso devemos armazenar algumas informações da câmera:


Posição da Câmera (Camera Position): está é a posição da câmera ainda no espaço do Universo, pois lembre-se que ela sempre está na origem no espaço da Câmera. Este posicionamento, será composto por valores dos eixos coordenados x, y e z.

Pos=(Px,Py,Pz)

Direção da Visão (View Direction): vai ser para informar para qual lugar a visão da camera está direcionada, assim, como na posiçã oda camera, considramos que a câmera ainda esteja no espaço universo. Desta forma, caso o objeto a ser visualizado esteja na origem, a direção de visualização da câmera será (0, 0, 0).

LookAt=(Dx,Dy,Dz)

VetorUp: ele informa qual é a parte de cima da cena, ou seja o up, então geralmente esse vetor terá valor (0, 1, 0).

Up=(Ux,Uy,Uz)




Espaço da Câmera para o Espaço Recorte (Projection)

Com os vértices no espaço da câmera, será utilizada uma matriz projeção para trazer os pontos para o espaço recorte. Sabemos que a câmera aponta para um ponto especifico da cena, então, teremos duas opções de  visualização, uma ortogonal(paralela) e uma perceptiva. A câmera também tem um ângulo de visão, chamado de abertura da câmera, que significa que posicionamos uma câmera, ela registrará um volume da cena.Então o que queremos é trazer seu sistema de coordenadas para o espaço recorte e para isso utilizamos a matriz projeção que faz com que os vértices do espaço da câmera sejam projetados em um plano de projeção, o View Plane. Aqui a coordenada homogênea é alterada.




Espaço da Recorte para o Espaço canônico (divisão por w)

Depois que é realizado a projeção perspectiva será necessário dividir todos pela coordenada homogênea w, isso faz com que toda cena tema uma distorção perspectiva, onde os objetos mais proximo da câmra ficam maiores, e os mais afastados ficam menores.



Espaço canônico para o Espaço de tela 



Para passar os objetos para o espaço de tela temos que fazer alguma transformações, é necessário fazer primeiramente um espelhamento na cena para que a cena não fique invertida.



 Depois  temos que escalar a cena de modo que ela ocupe toda tela, então, iremos utilizar os coeficientes de escala com o valores de W(largura de tela)/2 e H(altura de tela)/2.


Após isso, já teremos a posição correta do objeto e ocupando a tela em um espaço considerável, mas não tratamos daqueles vértices que são menores que 0 e se eles não se tornarem positivos não vão ser rasterizados na tela, por isso temos que transladar os vértices ate que todos fiquem maiores que 0.







Resultado:

Comparação do meu resultado com o do professor:



Principais Dificuldades: 

Uma dificuldade foi carregar o objeto no windows utilizando o codeblocks ou devc++, então tive que usar o linux. Também tive dificuldade no entendimento do pipeline.



Referencias Bibliográficas:

<https://en.wikipedia.org/wiki/Graphics_pipeline> Acesso em dia 02 de maio.
PAGOT, Christian Azambuja. Material de aula.


quarta-feira, 9 de março de 2016

Rasterização de Primitivas: Pontos, Linhas e Triângulos


Rasterização de Pontos:

Como os sistemas operacionais atuais não permitem que se escreva diretamente na memoria, vamos utilizar um framework disponibilizado pelo professor Christian Azambuja Pagot para simular a escrita no ColorBuffer.

A função PutPixel():  Essa função tem como objetivo "desenhar" um pixel na tela, recebendo coordenadas x e y e cor RGBA (red, green, blue, alpha) . Essa função será necessário na criação das outras funções: DrawLine e DrawTriangle.

Para facilitar na criação da função foram criadas duas estruturas (color, vertice), uma para cor e outra para as coordenadas. A estrutura color  contem as variáveis r,g,b,a e a vertice contem as variaveis x e y.

A posição do pixel na coordenada x e y é calculada através da seguinte função:


onde x e y são as coordenadas e IMAGE_WIDTH a largura da tela.

Abaixo temos a função PutPixel com o calculo implementado na variável p, que recebe o valor da posição do pixel no ColorBuffer e o ponteiro FBptr que acessa o pixel do FrameBuffer, que possui 4 bytes, e em cada byte guarda um componente da cor RGBA.



Compilando e executando esse código, temos esse resultado:

Rasterização da Função PutPixel


Rasterização de Linhas: 

Algorítimo de Bresenham: Esse algorítimo realiza a rasterização de segmentos de reta empregando apenas operações de aritmética de inteiros e , portanto, permite um maior desempenho. Esse algorítimo utiliza o método do ponto médio.

Na figura 1 tem uma linha reta que intersepta duas colunas de pixels. Em cada coluna encontra-se dois pixels que se encontram mais próximos da reta, um abaixo e outro em cima. Se o ponto médio se encontrar em baixo da reta (M2) deverá ser pintado o pixel acima, caso ao contrario (ponto M1) o pixel a ser selecionado será o abaixo da reta.

Figura 1.

A função DrawLine(): Função para rasterizar linhas a partir de dois pontos, recebendo dois paramentos de coordenadas dos pixels e dois para as cores. Será utilizado o algorítimo de Bresenham.

As variações de dx e dy terão os seguintes valores:

dx = x2 - x1
dy = y2 - y1


A função da reta tem valor zero para pontos sobre ela, os positivos são os valores acima dela e os negativos abaixo dela. Então temos que fazer o teste do ponto médio, basta calcular a função d e verificar o seu sinal. Para calcular a função d temos:




A partir do valor de d, verifica-se, se d>0 o pixel escolhido será o acima da reta, caso d<0 o pixel será o abaixo dela.

Após verificação do pixel escolhido,agora atualizaremos o valor de d, se o pixel acima da reta foi o ultimo escolhido então a incrementação será apenas no eixo x.



Também temos que verificar o valor inicial de d:


Caso o pixel abaixo da reta foi o escolhido:


Caso o pixel acima da reta foi o escolhido:


O algorítimo de Bresenham é limitado a apenas um octante. Porém é possível modifica-lo para implementa-lo para os outros octantes da seguinte forma:



Se o ponto médio estiver entre 0 e 1, o d inicial  será (d= 2dy -dx), para d>=0 o valor de d  será (d+=2(dy-dx) ) e então x++ e y++, caso o d<0 o valor de d será (d+=2dy) e então apenas x++.

Se o ponto médio estiver entre -1 e 0, o d inicial  será (d= 2dy +dx), para d>=0 o valor de d será  (d+=2dy) e então x++, caso o d<0 o valor de d será(d+=2(dy+dx) ) e então x++ e
 y--.

Se o ponto médio for maior que zero, o d inicial  será (d= dy - 2dx), para d>=0 o valor de d será  (d+=-2dx) e então y++, caso o d<0 o valor de d será(d+=2(dy-dx) ) e então x++ e
 y++.

Se o ponto médio for menor que zero, o d inicial  será (d= dy + 2dx), para d>=0 o valor de d será  (d+=2(dy+dx)) e então x++ e y--, caso o d<0 o valor de d será(d+=2dx ) e então
 y--.


Obtive o seguinte resultado:


Rasterização de linha



Interpolação de Cores:

Foi criada uma função que a partir do primeiro ponto desenhado calcula a distancia desse ponto ate o ponto final, e outra função que recebe a divisão entre a distância parcial(distP) com a distancia total(distT) e as cores inicial(cor1) e final(cor2), e essa porcentagem (p) será multiplicado pela cor do ponto inicial, somado a esse p subtraído por 1 e multiplicado pelo valor da cor final, retornando a nova cor do ponto final, esse processo será repetido para cada pixel desenhado ate chegar ao pixel final.

O calculo da distância entre dois pontos é feita a partir da seguinte equação:


e para descobrir a cor do ponto p é através da seguinte equação: 


Abaixo você pode conferir uma linha com interpolação de cores:





Rasterização do Triângulo:

A função DrawTriangle(): É uma função bem simples que recebe três vértices que forma um triângulo, como já foi criado funções para rasterização de pontos e linhas, basta apenas chamar a função DrawLine() três vezes.  Abaixo está o resultado dessa função:


Rasterização do Triângulo


Principais Dificuldades: A maior dificuldade foi na implementação do algorítimo de Brasenham.

Referências Bibliográficas:
 <http://pt.wikipedia.org/wiki/Algoritmo_de_Bresenham>Acesso 4 de Março.
<http://www.sabereletronica.com.br/artigos/2605-algoritmo-de-bresenham-o-uso-de-microcontroladores-para-traar-retas-em-lcds> Acesso em 4 de Março.
<http://disciplinas.ist.utl.pt/leic-cg/textos/livro/Rasterizacao.pdf> Acesso em 6 de Março.