You are on page 1of 13

Gráficas Interactivas

Iluminación en OpenGL

ITESM-CEM Departamento de Ciencias Computacionales

Contenido

z Introducción a las funciones de


iluminación de OpenGL

z Introducción a los materiales usados en


superficies en OpenGL

z Frente y reverso de polígonos

Pasos para Iluminar en OpenGL

1. Habilitar el uso de luces


2. Especificar el Modelo de Sombreado
(plano o suave)
3. Especificar las normales de las
superficies
4. Especificar las luces
5. Especificar las propiedades de los
materiales

1
1. Habilitar el uso de luces
z Se habilita el uso de luces con:
{glEnable(GL_LIGHTING);

z Se habilita cada luz de manera individual:


{glEnable(GL_LIGHT0);
{glEnable(GL_LIGHT1);
{…
{glEnable(GL_LIGHT7);

z Nota: si se habilita el uso de iluminación,


glColor() es ignorado

2. Especificar el Modelo
z Los cálculos se hacen para cada
vértice

z Por definición (default), los colores de


los vértices se interpolan a lo largo de
los polígonos:
{glShadeModel(GL_SMOOTH);

z Pero también se puede especificar


que sea el primer vértice el que
determine el sobreado de todo el
polígono:
{glShadeModel(GL_FLAT);

Sombreado Plano
z Cada polígono tiene una sola normal

z La normal especificada para el primer


vértice se utiliza para todo el polígono

z El sombreado de cada polígono es


constante (plano) porque se maneja
una normal constante para todo el
polígono

2
Sombreado Suave

z Cada polígono tiene varios


vértices

z Cada vértice tiene una normal

z El sombreado se interpolará a lo
largo del polígono como antes
se hacía con los colores y por lo
tanto será suave

Sombreado Suave

z Cómo se calculan las normales en cada vértice?

z La normal en cada vértice es el promedio de de


las normales de los polígonos vecinos

Sombreado Suave en OpenGL

z Se necesita:
{Calcular las normales de los polígonos
{Calcular las normales en los vértices a partir de
las normales de los polígonos

z Posteriormente:
{Interpolar las normales de los vértices a lo largo
de las aristas
{Calcular la iluminación en las aristas
{Interpolar las aristas a lo largo de los polígonos

3
3. Especificar las normales de las
superficies
z Asigna cada normal con glNormal*()
{ glNormal3f(x, y, z);
{ glNormalfv(p); // donde p es un vector

z En OpenGL el vector normal es parte del


estado
{ usar antes de cada polígono
z (sombreado plano)
{ usar antes de cada vértice
z (sombreado suave)

Normal para Polígonos

z Tienes que calcular la normal a


la superficie:

n = (p2 – p1 ) × (p0 – p1 )

Normal para Polígonos

z Hay que recordar la regla de la mano


derecha para determinar hacia donde
está apuntando la normal

4
Normales Unitarias

z Necesitamos que las normales tengan


como longitud 1, de modo que el cálculo
de la iluminación sea correcta

z Puede llamarse a
glEnable(GL_NORMALIZE) para que los
vectores automáticamente se hagan
unitarios

Normales Unitarias

z Todo esto es importante porque


transformaciones como escalas pueden
afectar la longitud de las normales

z Nota: El método
glEnable(GL_NORMALIZE) no calcula la
normal, sólo la normaliza

4. Especificar luces
z Para cada fuente de luz, se asigna un conjunto
de valores RBG para los términos difuso,
especular y ambiental

GLfloat diffuse[ ] = {1.0, 0.0, 0.0, 1.0};


GLfloat ambient[ ] = {0.0, 1.0, 0.0, 1.0};
GLfloat specular[ ] = {1.0, 1.0, 1.0, 1.0};

glLightv(GL_LIGHT0, GL_AMBIENT, ambient);


glLightv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightv(GL_LIGHT0, GL_SPECULAR, specular);

5
Luces Puntuales vs.
Direccionales
z La posición está dada por coordenadas
homogéneas y el cuarto elemento determina el
tipo de luz
{Si w = 1.0 entonces se especifica una luz puntual
{Si w = 0.0 entonces se especifica una luz direccional

z Ejemplo w
Glfloat position[ ] = {1.0, 2.0, 0.0, 1.0};
glLightv(GL_LIGHT0, GL_POSITION, position);

Luces Puntuales

z Si w = 1.0 entonces se especifica una luz puntual


w
Glfloat position[ ] = {1.0, 2.0, 0.0, 1.0};
glLightv(GL_LIGHT0, GL_POSITION, position);

z Estas instrucciones colocarán la fuente de luz


puntual en la posición P = (1,2,0)

Luces Direccionales
z Si w = 0.0 entonces se especifica una luz
direccional
w
Glfloat position[ ] = {1.0, 2.0, 0.0, 0.0};
glLightv(GL_LIGHT0, GL_POSITION, position);

z Estas instrucciones colocarán la fuente de luz


direccional apuntando de la posición P = (1,2,0)
al origen

6
Luces tipo “spot”
z La dirección se define con:
Glfloat direction[ ] = {1.0, 2.0, 2.0};
glLightv(GL_LIGHT0, GL_SPOT_DIRECTION,
direction);

z El ángulo del cono se define con:


Glfloat theta[ ] = 45.0;
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, theta);

z La posición de una luz de este tipo está sujeta a


cualquier transformación (traslación, escala y
rotación)

Luces Ambientales (globales)

z De manera adicional a la luz que llega de


diferentes fuentes, OpenGL permite agregar una
iluminación general:

GLfloat globalAmbient[ ] = { 0.4, 0.0, 0.0, 1.0 };


glLightModelfv(GL_LIGHT_MODEL_AMBIENT,
globalAmbient);

z La diferencia con otras luces es que no se ve


afectada por la distancia

5. Especificar las propiedades


de los materiales
z Una vez que las luces se han definido no se
puede usar glColor( )

z En lugar de colores, se especificarán materiales


para las superficies

z Las propiedades de los materiales son parte de


el estado en OpenGL y permanecen iguales
hasta que se hace un cambio explícito

7
Propiedades de los Materiales
z Se asignan los valores para los términos difuso,
especular y ambiental con las siguiente líneas:

GLfloat ambient[ ] = {0.2, 0.2, 0.2, 1.0};


GLfloat diffuse[ ] = {1.0, 0.0, 0.0, 1.0 };
GLfloat specular[ ] = {1.0, 1.0, 1.0, 1.0};

glMaterialv(GL_FRONT, GL_AMBIENT, ambient);


glMaterialv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialv(GL_FRONT, GL_SPECULAR, specular);

Materiales Transparentes

z Las propiedades de los materiales están


especificadas con valores RGBA

z El cuarto valor corresponde al nivel de


transparencia del objeto

z Se debe recordar habilitar “blending” para


que se pueda usar esta característica

Propiedades de los Materiales


z Se determina la transparencia con el cuarto
parámetro:

GLfloat ambient[ ] = {0.2, 0.2, 0.2, 1.0}; transparencia


GLfloat diffuse[ ] = {1.0, 0.0, 0.0, 1.0 };
GLfloat specular[ ] = {1.0, 1.0, 1.0, 1.0};

glMaterialv(GL_FRONT, GL_AMBIENT, ambient);


glMaterialv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialv(GL_FRONT, GL_SPECULAR, specular);

8
Propiedades de los Materiales
z Se determina el brillo del material con las
siguientes líneas:

GLfloat ambient[ ] = {0.2, 0.2, 0.2, 1.0};


GLfloat diffuse[ ] = {1.0, 0.0, 0.0, 1.0 };
GLfloat specular[ ] = {1.0, 1.0, 1.0, 1.0};

GLfloat shine = 100.0;

glMaterialv(GL_FRONT, GL_AMBIENT, ambient);


glMaterialv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialv(GL_FRONT, GL_SPECULAR, specular);

glMaterialf(GL_FRONT, GL_SHININESS, shine);

Materiales Emisores
z Se puede dar el efecto de un objeto emisor de
luz (como una estrella) especificando un valor
para GL_EMISSION

z Esta propiedad del objeto es independiente de


las fuentes de luz que existan, incluso en una
escena obscura el objeto brillará

z Sin embargo, un material emisor no ilumina a


otros porque no es una fuente de luz

Materiales Emisores

z De la misma manera en que se especifica


los términos difuso, especular y ambiental
para los materiales, se puede añadir un
término emisor:

GLfloat emission[] = (0.0, 0.0, 0.3, 1.0);

glMaterialv(GL_FRONT, GL_EMISSION,
emission);

9
Caras Frontales

z Por definición (default) se dibuja sólo


caras frontales, lo que funciona
correctamente para objetos sólidos:

Caras Frontales

z Cada lado de una cara puede tener sus


propias características o propiedades

z Se pueden hacer cambios utilizando:

GL_FRONT, GL_BACK o
GL_FRONT_AND_BACK

Al llamar a la función glMaterial

Caras Frontales
z Para sombrear las dos caras:

glLightModeli(GL_LIGHT_MODEL_TWO_SIDED,
GL_TRUE);

z Para sombrear sólo la cara del frente:

glLightModeli(GL_LIGHT_MODEL_TWO_SIDED,
GL_FALSE);

10
Distancia a la Fuente de Luz

z La cantidad de luz que llega a una


superficie es inversamente proporcional al
cuadrado de la distancia entre la fuente de
luz y la superficie:

Atenuación de la Luz
z En el mundo real, la luz es inversamente
proporcional al cuadrado de la distancia entre la
fuente y el objeto (1/d2)

z Pero en OpenGL podemos agregar factores (a,


b, c) en la forma (1/a+bd+cd2)

z Si se tiene c=1 y a=b=0 entonces se produce


una atenuación como en el mundo real

z Si se tiene a=1 y b=c=0 entonces no hay


atenuación

Atenuación de la Luz

z Los coeficientes por default tienen los


siguientes valores:
{A=1 (término constante)
{B=0 (término lineal)
{C=0 (término cuadrático)

z Por lo tanto, por definición (default) no hay


atenuación

11
Atenuación de la Luz

z Pueden cambiarse los valores


escribiendo:

glLightf(GL_LIGHT0,
GL_CONSTANT_ATTENUATION, 0.0);
glLightf(GL_LIGHT0,
GL_LINEAR_ATTENUATION, 0.0);
glLightf(GL_LIGHT0,
GL_QUADRATIC_ATTENUATION, 1.0);

Aminación de la luz

z Las fuentes de luz son objetos como


cualquier otro

z Por lo tanto, la fuentes de luz pueden


sufrir toda clase de transformaciones:

{ Traslaciones, rotaciones y escalas


{ Cambios de color e intensidad

Material elaborado por:

z Isaac Rudomín
{ rudomin@itesm.mx

z Erik Millán
{ emillan@itesm.mx

z Ma.Elena Melón
{ mmelon@itesm.mx

12
Expositor y revisor:

z José Luis Gordillo


{ JLGordillo@itesm.mx

13

You might also like