Finalmente, vamos falar sobre a interpolação linear de cores em linhas e a função de rasterizar triângulos, que na verdade nada mais é que uma função que rasteriza três linhas em ordem.
A interpolação de cores em uma linha significa começar a rasterização da linha utilizando uma cor e, pouco a pouco, modificar essa cor para que no fim da rasterização da linha tenhamos outra cor. É como um degradê, basicamente.
Para isso, precisamos primeiramente passar para a função de rasterizar linhas nossa cor inicial e final. Utilizaremos as cores que definimos anteriormente por praticidade, mas podemos, sem problema nenhum, utilizar qualquer cor do sistema RGBA.
Já que o algoritmo de rasterização funciona em etapas de pixel por pixel, só podemos modificar nossa cor a cada pixel, ou ciclo, do algoritmo. Então, temos que definir qual será nosso incremento de cor para cada canal de cor da linha por ciclo de rasterização. O cálculo do incremento do canal vermelho, por exemplo, é dado por:
dr = (color1.r = color0.r)/dx ou dy
onde dr é o incremento do canal vermelho, color1.r é o valor do canal vermelho no fim da linha, color0.r é o valor do canal vermelho no início da linha, e dx ou dy refere-se ao comprimento da linha projetada no eixo com o qual a função de rasterização trabalha. dx ou dy também é o número de vezes que o algoritmo de rasterização roda. Agora entendemos como e porque utilizamos este valor de dr. Para os outros canais de cores, a definição do incremento é análogo.
No final de cada ciclo do algoritmo, a cor que está sendo utilizada para o pixel atual recebe os respectivos incrementos, aproximando pouco a pouco da cor final. Abaixo temos o código da função de rasterização no primeiro quadrante com as modificações para a interpolação de cores:
void DrawLine1O(int x0, int y0, int x1, int y1, cor color0, cor color1){ int dx = x1 - x0; int dy = y1 - y0; cor color = color0; float dr = (color1.r - color0.r)/dx; float dg = (color1.g - color0.g)/dx; float db = (color1.b - color0.b)/dx; int d = 2*dy - dx; //valor inicial de d int incE = 2*dy; //valores iniciais para incrementos E e NE int incNE = 2*(dy - dx); int x = x0; //valores iniciais para rasterizacao int y = y0; PutPixel(x, y, color); // bota primeiro pixel while(x < x1){ if(d<=0){ d += incE; x++; }else{ d +=incNE; x++; y++; } color.r = color.r+dr; // incrementa cor por pixel ate a cor final no ultimo pixel color.g = color.g+dg; color.b = color.b+db; PutPixel(x, y, color); } }
Inicialmente, quando utilizava os canais de cores como tipo inteiro, a interpolação não funcionava corretamente. Se eu tentasse rasterizar uma linha que começava azul e terminava vermelha, por exemplo, a cor azul ia aos poucos esmanhecendo enquanto o canal vermelho não era incrementado corretamente. Trocando os tipos dos canais para float, o problema foi corrigido. Outros bugs psicodélicos ocorreram, mas somente quando tentava utilizar outro cálculo de incremento.
| Linhas com interpolação de cores! |
Por último, vamos entender como funciona a rasterização de triângulos. A função recebe três coordenadas(os vértices do triângulo) e três cores, uma para cada vértice. Aí são chamadas as funções de rasterização de linha: do ponto 1 ao ponto 2, começando com a cor 1 e terminando com a cor 2; do ponto 2 ao ponto 3, começando com a cor 2 e terminando com a cor 3; e do ponto 3 ao ponto 1, começando com a cor 3 e terminando com a cor 1. Dessa forma, as cores sempre se unem nas vértices. É nesse momento que vemos outra vantagem de utilizar funções de rasterização "de trás para frente", que é essa coincidência de cores nos vértices.
| Três (3) triângulos rasterizados! |
Concluindo, o projeto foi um sucesso. Os conceitos foram entendidos completamente e implementations em código. Mal posso esperar para aprender mais sobre OpenGL. PS: Este programa contém GLUT.
REFERENCIAS:
Slides do professor Christian
http://stackoverflow.com/questions/25878029/smooth-color-interpolation-along-a-bresenham-line
http://stackoverflow.com/questions/13488957/interpolate-from-one-color-to-another

Nenhum comentário:
Postar um comentário