INFORMÁTICA GRÁFICA Máster en Informática Gráfica, Juegos y Realidad Virtual PRÁCTICA 3 Color e Iluminación. Carlos Garre del Olmo
Índice: 1. Color 2. Iluminación y Materiales 2.1. Fuentes de luz 2.2. Materiales 2.3. Sombreado 2.4. Elementos opcionales 3. Bibliografía
1. Color Este primer apartado lo único que aporta frente a la práctica anterior es el uso de sombreado plano y sombreado suave, ya que en la anterior práctica ya se aplicaba el test de profundidad. Pirámide: La pirámide debe tener un sombreado suave, mediante la función: glshademodel (GL_SMOOTH); He tratado de optimizar a la hora de pintar la pirámide, ya que en lugar de definir uno por uno los triángulos que forman sus caras, he utilizado la primitiva GL_TRIANGLE_FAN, y he lanzado así todas las aristas partiendo de la punta de la pirámide. Para hacer la base cuadrada de la pirámide he tenido que crear un único cuadrado con la primitiva GL_QUADS. A cada vértice se le ha asignado un color diferente, para apreciar el efecto del sombreado suave. Cubo: El cubo utiliza un sombreado plano, mediante: glshademodel (GL_FLAT); Para dibujar el cubo he utilizado la primitiva GL_QUADS, que permite dibujar facetas de 4 vértices, generando así una por una las 6 caras del cubo. A cada faceta se le ha asignado un color diferente, para apreciar el efecto del sombreado plano.
2. Iluminación y Materiales Esta práctica en principio tiene una complejidad similar a las anteriores, ya que los elementos nuevos a incorporar son pocos y relativamente sencillos (fuentes de luz y materiales). Como aquí se da cierta libertad en las modificaciones que se pueden realizar, he dedicado el tiempo sobrante (que ha sido muy poco) a implementar algunos otros elementos también interesantes, como la texturización, o los movimientos del observador (o cámara) dentro de la escena. En esta memoria me centraré sobre todo en lo que se pide en el enunciado, y mencionaré sólo de pasada los elementos opcionales que he añadido. El código fuente es demasiado grande como para comentarlo línea a línea como hice en las memorias anteriores, por lo que me centraré únicamente en comentar los aspectos relacionados con la iluminación. 2.1. Fuentes de luz He incorporado tres fuentes de luz a mi escena. Luz ambiental: Aunque este tipo de luz apenas existe en el Sistema Solar (salvo por la despreciable iluminación de la galaxia), he incorporado un leve factor de luz ambiental para suavizar un poco los contrastes, mediante la función gllightmodelfv: GLfloat model_ambient[] = {0.1, 0.1, 0.1, 1.0}; gllightmodelfv (GL_LIGHT_MODEL_AMBIENT, model_ambient); Luz solar: Es una fuente de luz puntual, posicionada en el interior del Sol, y orientada a los valores negativos del eje Z. El ángulo de apertura es máximo (180º), por lo que puede iluminar a todos los planetas que tiene a su alrededor. Sus características específicas son: Color de luz ambiental = negro (no aporta luz ambiental). Color de luz difusa = blanco. Color de luz especular = blanco. Posición = (0.0, 0.0, 0.0). Dirección = (0.0, 0.0, -1.0) (hacia dentro de la escena). Exponente de apertura = 180º Luz lunar: He incorporado una fuente de luz puntual en la cara iluminada de la Luna, para representar la luz de Luna que baña a la Tierra por la noche. Esta luz está ubicada no en el interior, sino en la superficie de la Luna, concretamente en su cara iluminada. Su ángulo de apertura es bastante cerrado (20º) para que sólo ilumine a la Tierra. Se trata de una luz bastante más tenue que la del Sol, ya que su componente de luz difusa es más suave.
Sus características específicas son: Color de luz ambiental = negro (no aporta luz ambiental). Color de luz difusa = gris suave (más tenue que el Sol). Color de luz especular = blanco (no va a incidir en ningún material reflectante). Posición = (centro_luna.x + radio_luna, centro_luna.y, centro_luna.z). Dirección = (1.0, 0.0, 0.0) (hacia la izquierda de la Luna, donde está la Tierra). Exponente de apertura = 20º En la siguiente imagen se muestra el efecto conjunto de las tres fuentes de luz. La luz solar se aprecia en la cara izquierda tanto de la Tierra como de la Luna, gracias a su reflejo difuso. La luz lunar se aprecia en la cara derecha de la Tierra, gracias a su reflejo difuso. La luz ambiental se aprecia en la cara derecha de la Luna, ya que gracias a ella se puede apreciar sutilmente la curvatura de la cara no iluminada. Además de luces puntuales existen luces direccionales, pero estas no se han utilizado ya que no tienen sentido en este contexto. Una luz direccional habría servido para representar la luz del Sol si éste se encontrase fuera de la escena (y lejos de ella).
2.2. Materiales Se han utilizado diferentes tipos de material para cada astro, aunque la Tierra y la Luna tienen las mismas características, por lo que se ha incorporado un cuarto astro al que he llamado Europa. Material del Sol: El Sol tiene un material muy interesante, ya que emite luz propia. Esta luz no se va a ver reflejada en los planetas, pero sí que sirve para crear el efecto de que es un objeto brillante. Como es la fuente de luz principal, el resto de características de este material no son importantes, ya que el Sol no va a recibir luz de ninguna fuente externa. Sus características específicas son: Color de luz emitida = blanco (emite luz propia). Color de luz ambiental y difusa reflejadas = blanco (no va a afectar). Color de luz especular = negro (no va a afectar). Brillo especular = ninguno (no va a afectar).
Material de la Tierra y la Luna: La tierra y la Luna han sido considerados objetos mate, es decir, sin reflejos especulares. En realidad, gran parte de la superficie terrestre tiene un importante factor especular, ya que es agua, pero para representar los materiales con reflejos especulares he preferido incorporar un planeta adicional (Europa). Sus características específicas son: Color de luz emitida = negro (no emiten luz propia). Color de luz ambiental y difusa reflejadas = blanco (reflejo difuso de la luz solar, y también la lunar para el caso de la Tierra). Color de luz especular = negro (no reflejan la componente especular de la luz). Brillo especular = ninguno (no tienen brillo especular).
Material de Europa: El cuarto astro ha sido llamado Europa en honor al satélite joviano del mismo nombre, que está compuesto en su práctica totalidad de hielo. Inspirándome en esta idea de un astro que presenta grandes brillos al reflejar la luz solar por estar compuesto de hielo, he ubicado un planeta que en realidad poco tiene que ver con el satélite Europa (ya que ni orbita en torno a Júpiter, ni está a la distancia adecuada, ni tiene el tamaño adecuado). Este material tiene un reflejo difuso más tenue que el de la Tierra y la Luna, para apreciar mejor el contraste entre el reflejo difuso y el especular. Además, he configurado el reflejo especular de modo que el planeta absorba la mitad de la componente azul de la luz. De esta forma, el reflejo especular se aprecia mejor, ya que tiene un tono verde-amarillento. Al tener un reflejo difuso inferior da la sensación de que el astro está más lejos, aunque en realidad la forma correcta de representar la atenuación de la luz con la distancia es utilizar la función gllightf con los parámetros GL_CONSTANT_ATTENUATION (atenuación constante) y GL_LINEAR_ATTENUATION (atenuación inversamente proporcional a la distancia). También existe un factor cuadrático GL_QUADRATIC_ATTENUATION (atenuación inversamente proporcional al cuadrado de la distancia), pero esto produce luces muy irreales sobre todo si tenemos en cuenta que la luz solar se transmite en el vacío, donde no hay atmósfera que la frene. Sus características específicas son: Color de luz emitida = negro (no emiten luz propia). Color de luz ambiental y difusa reflejadas = gris (reflejo difuso tenue de la luz solar) Color de luz especular = amarillento (absorbe parte de la componente azul en su reflejo especular). Brillo especular = 50 (fuerte brillo especular).
2.3. Sombreado En toda la escena se utiliza el modelo de sombreado suave. Si se hubiese utilizado sombreado plano, se apreciarían claramente las facetas que forman los poliedros que aproximan las esferas de los planetas, por lo que la escena perdería mucho realismo. Si activásemos el sombreado plano mediante la función glshademodel (GL_FLAT), éste sería el aspecto que presentaría el planetario: Si vemos de cerca la Luna apreciamos claramente la diferencia entre el sombreado plano (izquierda) y el suave (derecha):
2.4. Elementos opcionales A partir de esta idea simple se pueden incorporar infinidad de elementos adicionales, como vemos en el ejemplo del programa Celestia. Debido a la falta de tiempo sólo he podido incorporar algunos elementos sencillos, pero al final comentaré algunas otras ideas que no he implementado. Texturas La texturización de los planetas no es un asunto trivial, ya que hasta ahora los estábamos pintando mediante las primitivas básicas de GLUT (glutwiresphere o glutsolidsphere). Con estas primitivas no podemos profundizar en cada uno de los vértices para mapear la textura, por lo que hay que buscar una forma alternativa para crear las esferas. Para ello me he servido de un algoritmo que forma las esferas faceta por faceta mediante la primitiva GL_QUAD_STRIP. Este algoritmo fue diseñado por Paul Bourke, y su explicación detallada se puede encontrar en su página web (ver bibliografía). En esta página se incluye además un código para deformar las texturas de forma que se ajusten exactamente a la forma de la esfera. Como los resultados son razonablemente satisfactorios, no he implementado este otro algoritmo, aunque he tenido que editar algunas texturas utilizando un software de retoque fotográfico (IrfanView). En la siguiente imagen se ven las texturas utilizadas: Para la carga de las texturas se ha utilizado la librería GLAUX, por lo que es importante que ésta se incluya en el proyecto (mediante la opción de linkado lglaux).
Movimientos de la cámara: El observador o cámara se puede mover por todo el escenario utilizando el teclado: Tecla W : Avanzar. Tecla S : Retroceder. Tecla Q : Mirar arriba. Tecla A : Mirar abajo. Tecla O : Mirar a la izquierda. Tecla P : Mirar a la derecha. Tecla C : Movimiento lateral a la izquierda (strafe). Tecla V : Movimiento lateral a la derecha (strafe). Para estos movimientos he incluido en mi proyecto la librería camera.h, proporcionada en los tutoriales de la web CodeColony (ver bibliografía). Backface Culling: Como optimización he activado el algoritmo de backface culling, para no representar las caras no visibles de los polígonos. Esto se hace simplemente mediante dos llamadas a OpenGL: glcullface(gl_back); glenable(gl_cull_face); Una vez activado este algoritmo, hay que tener cuidado con la forma en la que se construyen los polígonos, ya que el orden de colocación de los vértices es el que determina si se trata de una cara frontal o trasera (es decir, determina el sentido de la normal de esa faceta).
Otras ideas no implementadas: Fondo estrellado: a pesar de que lo implementé (tal y como se puede ver en algunas capturas de pantalla), el aspecto final no me pareció satisfactorio, por lo que en la versión final no lo he incluido. Eclipses: se podría simular el efecto de un eclipse solar (tanto sobre la Tierra como sobre la Luna), ubicando en la zona del eclipse un simple plano con una textura que mostrase únicamente una circunferencia negra, y como color de fondo una transparencia (componente alfa).
Detección de colisiones: sería interesante implementar una sencilla detección de colisiones para el movimiento de la cámara, no sólo para evitar que atraviese los planetas, sino también para evitar que la escena se salga fuera del volumen de visualización (colisión entre la cámara y los bordes del frustum). Fuego solar: se podría utilizar el sistema de partículas incluido en el tutorial Particle Engine de la web CodeColony. Cometa: Se podría incluir una cuarta fuente de luz sobre un cometa, que consistiría en una esfera que emite luz blanca (o azulada) y una cola creada con otro sistema de partículas del mismo tutorial.
Modo telescopio: Sería muy fácil incorporar una tecla que nos diese una vista desde la superficie de la Tierra, pudiendo incluso utilizar diferentes lentes cambiando el ángulo en la función gluperspective.
3. Bibliografía Páginas web más utilizadas para el desarrollo de la práctica: Sitio oficial de OpenGL: http://www.opengl.org Página web de Paul Bourke: http://local.wasp.uwa.edu.au/~pbourke/ Tutoriales de CodeColony: http://www.codecolony.de/opengl.htm Tutoriales de Nehe: http://nehe.gamedev.net Google Images (para las texturas): http://images.google.com Libros más utilizados: OpenGL SuperBible, Second Edition. Richard S. Wright, Jr. and Michael Sweet Waite Group Press 2000 3D Computer Graphics: A Mathematical Introduction with OpenGL Samuel R. Buss Cambridge University Press 2003