sexta-feira, 12 de agosto de 2016

Interpolação de cores e Triângulos

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

Álbum da vez: 

Nenhum comentário:

Postar um comentário