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

jSSeção 5.5  

 

 

         5.5. Exemplos



A partir de agora iremos criar vários exemplos, especificando sempre um modelo de iluminação(ambiente, difuso, especular, atenuação atmosférica) diferente, com métodos para iluminação de malhas poligonais também diferente, para que você entender como realmente isso funciona em OpenGL. Os objetos presentes nos exemplos são um cubo e uma esfera, ou seja, um objeto de representação fiel da superfície e um objeto de superfície aproximada. 

 
EXEMPLO 1. ILUMINAÇÃO CONSTANTE USANDO SOMENTE LUZ AMBIENTE 

Primeiramente é necessário verificarmos como estão declarados os objetos. A esfera é definida na GLU. Você não precisa preocupar em especificar as normais no caso da esfera. O procedimento da GLU utilizado, já declara as normais quando necessárias. Quando o modelo utilizar somente luz ambiente automaticamente o procedimento não calcula as normais para a esfera. Porém para o cubo você precisa se preocupar em especificar as normais. No caso do modelo de iluminação somente utilizando luz ambiente elas não devem ser especificadas. Os objetos são definidos nos procedimentos make_sphere() e make_cube() do exemplo. Esses procedimentos também definem a cor da esfera e do cubo através do comando glColor.

O modelo de iluminação utilizado já foi citado. Os comandos que definem este modelo estão descritos abaixo:

   L1 >> GLfloat ambiente[] = { 1.0, 1.0, 1.0, 1.0};
   L2 >> glShadeModel(GL_FLAT);
   L3 >> glEnable(GL_COLOR_MATERIAL);
   L4 >> glLightfv (GL_LIGHT0, GL_AMBIENT, ambiente);
   L5 >> glEnable(GL_LIGHTING);
   L6 >> glEnable(GL_LIGHT0);
   L7 >> glEnable(GL_DEPTH_TEST);

Em L1 definimos os atributos da luz ambiente a ser criada. Em L2 definimos o método de iluminação constante como sendo o método escolhido para iluminação de malhas poligonais. Em L3 habilitamos o comando ColorMaterial, isso nos garante que a  somente reflexão ambiente foi setada, ou seja, o coeficiente de reflexão ambiente do os objetos serão definidos pelos parâmetros do comando glColor referentes aos mesmos. O comando glColor é encontrado nas funções make_cube() e make_sphere(). Em L4 criamos uma fonte de luz ambiente, cujas as características da mesma foram definidas em ambiente. Em L5 habilitamos os efeitos de luz e em L6 habilitamos a luz definida como GL_LIGHT0. Em L7 habilitamos a remoção de superfícies escondidas. 

No procedimento void TestGLCanvas::Render(), é ordenado o desenho do cubo e da esfera. A o tipo de projeção é paralela e é definido no procedimento static void Reshape(int width, int height)

Veja abaixo o efeito do exemplo:

 

Iluminação constante usando somente luz ambiente

 

Comentários:Veja como a cor é constante em todo o objeto. Esse é o efeito da luz ambiente. A luz ambiente é bastante utilizada em iluminação de salas, cozinhas entre outros ambientes. Repare também no detalhe da remoção de linhas escondidas. 

  

EXEMPLO 2. ILUMINAÇÃO CONSTANTE USANDO REFLEXÃO DIFUSA 

A diferença desse exemplo para o outro é que agora as normais serão especificadas e o modelo de iluminação mudará de ambiente para difuso. Para o cubo serão especificadas uma normal para cada face. A declaração das normais do cubo podem ser observadas no procedimentos TestGLCanvas::make_cube() .A declaração das normais (uma normal para cada vértice de cada polígono que compõe a superfície) da esfera será trabalho do procedimento da GLU utilizado para desenhar a esfera, portanto não é necessário se preocupar. 

Abaixo segue a criação de um modelo de iluminação difusa com utilização do método de iluminação constante:

   C1 >> GLfloat difusa[] = { 1.0, 1.0, 1.0, 1.0};
   C2 >>GLfloat position [] = { 0.0, 3.0, 1.0, 0.0 };

   L1 >> glShadeModel(GL_FLAT);
   L2 >> glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
   L3 >> glEnable(GL_COLOR_MATERIAL);
   L4 >> glLightfv (GL_LIGHT0, GL_DIFFUSE, difusa);
   L5 >> glLightfv (GL_LIGHT0, GL_POSITION, position);
   L6 >> glEnable(GL_LIGHTING);
   L7 >> glEnable(GL_LIGHT0);
   L8 >> glEnable(GL_DEPTH_TEST);

Em L1 especificamos o método de iluminação constante. Em L2 especificamos que o coeficiente de reflexão difusa para as faces da frente e de trás dos objetos serão determinados pelos parâmetros do comando glColor. Em L3 habilitamos o comando de GL_COLOR_MATERIAL. Em L4 , criamos uma luz difusa com as características definidas em C1. Em L5 estamos dizendo que a luz será direcional e o vetor que indica esta direção está definido em C2. L6,L7,L8 já foram descritos anteriormente.


Veja abaixo o efeito do exemplo:

 

Iluminação constante com reflexão difusa

 

Comentários: Repare que luz é direcional e ilumina as partes superiores do cubo e da esfera. O resultado da reflexão difusa no cubo foi bom, pois ficou claro que a parte de cima está mais iluminada que as outras faces. Porém o resultado da esfera ficou muito ruim e não condiz com a realidade. Veja que cada polígono da esfera é destacado pela variação das intensidades o que dificulta o reconhecimento da esfera pela observador. 

 

EXEMPLO 3. ILUMINAÇÃO CONSTANTE USANDO REFLEXÃO ESPECULAR 

Neste exemplo, as normais serão declaradas de maneira idêntica ao exemplo anterior. O que muda neste exemplo será o modelo de iluminação que passará de difuso para especular. Veja os comandos abaixo:

    C1 >> GLfloat especular[] = { 1.0, 1.0, 1.0, 1.0};
    C2 >> GLfloat position [] = { 0.0, 3.0, 1.0, 0.0 };

    L1 >> glShadeModel(GL_FLAT);
    L2 >> glEnable(GL_COLOR_MATERIAL);
    L3 >> glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, especular);
    L4 >> glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 20.0);
    L5 >> glLightfv (GL_LIGHT0, GL_SPECULAR, especular);
    L6 >> glLightfv (GL_LIGHT0, GL_POSITION, position);
    L7 >> glEnable(GL_LIGHTING);
    L8 >> glEnable(GL_LIGHT0);
    L9 >> glEnable(GL_DEPTH_TEST);

Em L1 especificamos o método de iluminação constante. Em L2 funciona de maneira semelhante ao exemplo 1. Quando habilitamos o comando glColorMaterial (glEnable (GL_COLOR_MATERIAL) e não definimos nenhum desses comandos automaticamente será o coeficiente de reflexão ambiente do objeto será definido pelo comando glColor na descrição do objeto. No caso da reflexão difusa, nós habilitamos o comando glColorMaterial e também especificamos o mesmo para reflexão difusa. Nesse caso somente o coeficiente difuso será especificado para o material do objeto. Em L3 definimos os coeficientes especulares do material. Em L4 definimos o quanto a luz deve ser concentrada. Em L5 criamos uma luz especular com as características definidas em C1. E L6 estamos dizendo que a luz é  do tipo direcional e tem a direção especificada pelo vetor definido em C2.

Veja o resultado do exemplo:

 

Iluminação constante com reflexão especular

 

Comentários: Assim como na reflexão difusa, o cubo apresentou resultados satisfatórios. Porém a esfera ficou um desastre, pois a tentativa de mostrar a área preferencial de reflexão ficou muito ruim. Você não deve usar iluminação constante em objetos que têm sua superfícies formadas por aproximação. 

 

EXEMPLO 4. MÉTODO DE GOURAUD USANDO SOMENTE LUZ AMBIENTE 

O exemplo é praticamente idêntico ao exemplo 1, mudando somente a especificação do método de iluminação para malhas poligonais. Basta você ir até o procedimento TestGLCanvas::ONPaint do código fonte do exemplo 1 e trocar o comando:

    >> glShadeModel (GL_FLAT) por glShadeModel (GL_SMOOTH)

Veja o resultado do exemplo:

 

Método de Gouraud usando somente luz ambiente

 

Comentários: Veja que mesmo com Gouraud, quando se usa somente iluminação ambiente o efeito é o mesmo de quando se usa iluminação constante. (Vide exemplo 1). Isso nos leva a concluir que se estiver criando um modelo que utiliza somente iluminação ambiente, posso configurar o método de iluminação constante,  pois a imagem gerada será de boa qualidade e que não preciso usar o método de Gouraud para isso.

 

EXEMPLO 5. MÉTODO DE GOURAUD USANDO REFLEXÃO DIFUSA 

Da mesma forma que o exemplo anterior, este exemplo é praticamente idêntico ao exemplo 1, mudando somente a especificação do método de iluminação para malhas poligonais. Basta você ir até o procedimento TestGLCanvas::ONPaint do código fonte do exemplo 1 e trocar o comando:

    >> glShadeModel (GL_FLAT) por glShadeModel (GL_SMOOTH)

Veja o resultado do exemplo:

 

Método de Gouraud usando Reflexão Difusa

 

Comentários: Veja a diferença de realismo entre os métodos de Gouraud e iluminação constante (vide exemplo 2). A esfera nesta figura parece "bem mais uma esfera" do que no exemplo 2. O cubo continuou praticamente com as mesmas propriedades. O que importante aqui é a sensação de realismo causado pela imagem, que é muito superior a sensação causada quando se está utilizando iluminação constante.

 

EXEMPLO 6. MÉTODO DE GOURAUD USANDO REFLEXÃO ESPECULAR 

Da mesma forma que o exemplo anterior, este exemplo é praticamente idêntico ao exemplo 1, mudando somente a especificação do método de iluminação para malhas poligonais. Basta você ir até o procedimento TestGLCanvas::ONPaint do código fonte do exemplo 1 e trocar o comando:

    >> glShadeModel (GL_FLAT) por glShadeModel (GL_SMOOTH)

Veja o resultado do exemplo:

 

Método de Gouraud usando Reflexão Especular

 

Comentários: O realismo entre iluminação constante e Gouraud nesse caso é incomparável. Repare que na esfera que região preferencial de reflexão é bem concentrada. Mas apesar de apresentar um resultado bem melhor que o método de iluminação constante, o método de Gouraud ainda não consegue imitar a região do brilho com a mesma qualidade do método de Phong.  

 

EXEMPLO 7. DUAS FONTES DE LUZ UTILIZANDO O MÉTODO DE GOURAUD COM REFLEXÃO ESPECULAR 

O exemplo é bem semelhante ao anterior, somente diferenciando no número de fontes de luz utilizados. No caso deste exemplo foi configurado uma segunda fonte de luz que também é direcional e especular.

Veja o código abaixo:

    >> GLfloat especular[] = { 1.0, 1.0, 1.0, 1.0};
    >> GLfloat position [] = { 0.0, 3.0, 1.0, 0.0 };
    >> GLfloat position2[] = { 1.0, -2.0, 1.0, 0.0 };

     >> glShadeModel(GL_SMOOTH);
    >> glEnable(GL_COLOR_MATERIAL);
    >> glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, especular);
    >> glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 120.0);
    >> glLightfv (GL_LIGHT0, GL_SPECULAR, especular);
    >> glLightfv (GL_LIGHT0, GL_POSITION, position);
    >> glLightfv (GL_LIGHT1, GL_SPECULAR, especular);
    >> glLightfv (GL_LIGHT1, GL_POSITION, position2);
    >> glEnable(GL_LIGHTING);
    >> glEnable(GL_LIGHT0);
    >> glEnable(GL_LIGHT1);
    >> glEnable(GL_DEPTH_TEST);

Os comandos destacados definem a segunda fonte de luz. Ela é um luz direcional que possui os atributos configurados em position2. Além disso ela é especular de forma semelhante a primeira fonte de luz. 

Veja o resultado do exemplo:

 

Duas Fontes de Luz utilizando Gouraud com Reflexão Especular

 

Comentários: Este exemplo é bem semelhante ao anterior somente diferenciando no número de fontes de luz existentes. Repare que a segunda fonte de luz causa uma outra região preferida para a reflexão na esfera. Essa região nos vem mais uma vez mostrar que Gouraud tem problemas quando se diz a respeito desse tipo de reflexão.

 

CONCLUSÕES

Para gerar imagens de boa qualidade em OpenGL é necessário que você tenha os seguintes cuidados:

  • Caso a cena só possua objetos cuja superfície é uma representação fiel (cubos, pirâmides)  utilize o método de iluminação constante, independente do tipo de reflexão.

  • Caso a cena seja iluminada somente com uma luz ambiente, utilize o método de iluminação constante, independente das superfícies dos objetos que formam a cena.

  • Caso a cena possua objetos na qual sua superfície é uma aproximação (cones, esferas) utilize o método de Gouraud.

  • Para objetos como cubos, pirâmides declare uma normal para cada face, exceto se o modelo de iluminação for somente o de luz ambiente.

  • Para objetos como cones, esferas declare uma normal para cada vértice de cada polígono que forma a superfície,exceto se o modelo de iluminação for somente o de luz ambiente.

 

 

[principal]

[anterior]