Desenho de objetos em OpenGL -- Computação Gráfica

jSSeção 5.3  

 

 

         5.3. Tipos de Luz

 

Uma fonte de luz pode ter algumas particularidades. Por exemplo, a luz de uma vela interage com os objetos de maneira diferente do que a luz de um holofote, pois enquanto a luz da vela ilumina em todas as direções, a luz de um holofote não ilumina os objetos que estão na parte de trás do mesmo. Essas particularidades devem ser definidas no modelo de iluminação para proporcionar mais realismo as imagens formadas. Iremos descrever os vários tipos de luzes existentes em OpenGL.

Uma luz ambiente pode ser também considerada um tipo de luz. Conforme abordado na seção anterior este modelo propõe que, cada ambiente possui uma pequena quantidade de luz, de origem desconhecida, independente de qualquer fonte de luz, que ilumina todas as faces do objeto de maneira uniforme.

LUZ PONTIFORME

Neste tipo de luz basta definir um ponto que a partir desse haverá uma iluminação em todas as direções. Podemos citar como exemplo uma vela acessa. Veja abaixo na figura:

Para se obter uma luz como essa em OpenGL basta os seguintes comandos:

    >> GLfloat position[] = {X, Y , Z, 1.0 } ;
    >> glLightfv( GL_LIGHT0, GL_POSITION, position );
    >> glEnable(GL_LIGHTING);
    >> glEnable(GL_LIGHT0);

Repare que são quatro os atributos de position . Isto ocorre porque os mesmos são especificados em coordenadas homogenias. Não iremos entrar em detalhes, mas basta sabermos que quando o último parâmetro for 1.0 estamos referindo a um ponto e se for 0.0 estamos referindo a um vetor. Os  três primeiros parâmetros se referem a posição da fonte de luz, sendo que o primeiro se refere a X o segundo a Y e o terceiro a Z. O último parâmetro é 1.0, o que indica que os três primeiros parâmetros se referem a um ponto e partir desse ponto serão emitidos raios de luz em todas as direções.

 

LUZ DIRECIONAL

Neste tipo de luz é necessário especificar apenas uma direção e partir daí  os objetos serão iluminados de acordo com a mesma. Veja a figura abaixo:

Em OpenGL o código seria bastante parecido com o anterior:

    >> GLfloat position[] = {X, Y, Z, 0.0 } ;
    >> glLightfv( GL_LIGHT0, GL_POSITION, position );
    >> glEnable(GL_LIGHTING);
    >> glEnable(GL_LIGHT0);

Repare no exemplo que apenas o quarto atributo de position mudou. O valor zero indica que os 3 primeiros atributos de position formam um vetor que indica a direção da luz. 

 

SPOTLIGHT

Um exemplo típico para este tipo de luz é um holofote. No geral, a luz não é emitida em todas as direções pois objetos que estão atrás não são iluminados. Para definir uma luz como essa é necessário definir a posição e direção da fonte de luz, qual a concentração de luz  e um ângulo que irá indicar qual a área de iluminação. Veja a figura abaixo:

Onde Ps é o ponto.
Ls é o vetor que indica a direção.
Teta é o ângulo que indica a área de iluminação.

Conforme foi dito acima, esse tipo de luz em geral não emite luz em todas as direções. Por exemplo no caso figura, os objetos que estão atrás de Ps não serão iluminados. Entretanto se o ângulo teta for configurado para 180 graus a luz spotlight se torna uma luz pontiforme.

Em OpenGL nós podemos definir uma luz como esta da seguinte forma:

    >> GLfloat position [] = { 1.0, 1.0 , 1.0, 1.0 } ;
    >> GLfloat direction[] = { -2.0, 1.0, -2.0 };
    >> glLightfv( GL_LIGHT0, GL_POSITION, position );
    >> glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, direction);
    >> glLightf ( GL_LIGHT0, GL_SPOT_EXPONENT , 1.0);
    >> glLightf ( GL_LIGHT0, GL_SPOT_CUTOFF, 70.0);
    >> glEnable(GL_LIGHTING);
    >> glEnable(GL_LIGHT0);

Os comandos em azul definem a posição do ponto referente a fonte de luz (aqui foi definido Ps da figura). A direção da Spotlight é definida pelos comandos em vermelho ( aqui foi definido o Ls da figura). A concentração de luz é definida pelo comando em verde e o ângulo é definido pelo comando em cinza ( aqui foi definido o ângulo teta da figura). 

Com isso setamos todos os parâmetros referentes a uma SpotLight. A concentração de luz definida pela constante GL_SPOT_EXPONENT pode variar entre 0.0 e 128.0. Da mesma forma o ângulo especificado pela constante GL_SPOT_CUTOFF pode variar 0.0 a 90.0 e 180.0 .

Conforme já foi dito você pode especificar o tipo de luz no seu modelo de iluminação. Por exemplo vamos pegar o código do modelo geral criado na seção anterior e especificar que a fonte de luz para o mesmo é do tipo SpotLight. O código para realizar essa operação é descrito abaixo:

    >> GLfloat position [] = { 1.0, 1.0 , 1.0, 1.0 } ;
    >> GLfloat direction[] = { -2.0, 1.0, -2.0 };
    >> GLfloat luz_ambiente[]  = { XaR, XaG, XaB, Xa } ;
    >> GLfloat objeto_ambiente[] = { YaR, YaG, YaB, Ya};
    >> GLfloat luz_difusa[]  = { XdR, XdG, XdB, Xd } ;
    >> GLfloat objeto_difusa[] = { YdR, YdG, YdB, Yd};
    >> GLfloat luz_especular[]  = { XeR, XeG, XeB, Xe } ;
    >> GLfloat objeto_especular[] = { YeR, YeG, YeB, Ye};
    >> glLightfv(GL_LIGHT0, GL_AMBIENT, luz_ambiente );
    >> glLightfv(GL_LIGHT0, GL_DIFFUSE, luz_difusa );
    >> glLightfv(GL_LIGHT0, GL_SPECULAR, luz_especular );
    >> glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, a);
    >> glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, b) ;         
    >> glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, c) ;              
    >> glLightfv( GL_LIGHT0, GL_POSITION, position );
    >> glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, direction);
    >> glLightf ( GL_LIGHT0, GL_SPOT_EXPONENT , 1.0);
    >> glLightf ( GL_LIGHT0, GL_SPOT_CUTOFF, 70.0);
    >> glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, objeto_ambiente);
    >> glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, objeto_difusa);
    >> glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, objeto_especular);
    >> glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, n );
    >> glEnable(GL_LIGHTING);
    >> glEnable(GL_LIGHT0);

Repare que somente foi necessário adicionar os comandos que definem uma luz do tipo SpotLight. Se você quiser especificar uma luz pontiforme, direcional ou ambiente no modelo de iluminação, basta adicionar os comandos relativos aos mesmo na definição do modelo de forma semelhante ao exemplo citado acima.

 

[principal]

[anterior]

[próxima]