sábado, 4 de mayo de 2013

OpenGL desde 0. Capitulo 4: Luces y Materiales

Capítulo perteneciente al tutorial de opengl desde cero

Hola a todos,

Este capítulo tal vez es de lo más complicados de la teoría necesaria para aprender OpenGL. Si entendéis bien este capítulo no tendréis ningún problema con el resto de OpenGL. Si no lo entendeís a la primera, tranquilos, es un tema denso,  daos tiempo y lo ireis pillando.

El tema de hoy se llama luces y materiales (dos conceptos a priori bastante alejados para un profano) debido a que si llego a poner como titulo "composición de color mediante openGL" todavía se me habría entendido menos :). En el mundo real, los colores que percibimos dependen de muchos factores pero principalmente de las características físicas del objeto que estamos mirando y del tipo e intensidad de luz que le llega.  OpenGL, como ya deberíais saber a estas alturas, no es más que un sistema que simula lo mejor posible la realidad, así que en el tema de la iluminación hace lo mismo. Nos permite definir las características físicas de los materiales y de las luces que tenemos en la escena.

OpenGL modela la luz en tres componentes diferentes:

- Luz Ambiental: Aquella que proviene de un lugar indeterminado y que rebota en los objetos en todas direcciones. Es aquella luz que no tiene un punto de inicio. Es lo más parecido a la luz del Sol o a la iluminación en una sala grande. Es lo que nos permite ver los objetos con claridad.

-Luz difusa: Es aquella que proviene de un foco cuyo inicio podemos determinar. Es la típica que nos va a generar zonas iluminadas y de sombras en un objeto. Se la conoce también como iluminación suave.

-Luz especular: Conceptualmente es muy parecida a la luz difusa, solo que es aquella que nos genera "brillos" en el objeto. Se la conoce como iluminación fuerte.

A modo de ejemplo, una bombilla generará luz ambiente y difusa (casi nada de especular) mientras que un láser generará  solamente luz especular.

Como ya sabemos como trata la luz OpenGL tendremos que definir como queremos que nos interpole el color en nuestro modelo. Hay dos modos:    GL_FLAT y GL_SMOOTH y se activan mediante glShadeModel (ejemplo:  glShadeModel(GL_SMOOTH);  ). La opción FLAT calcula el color medio del poligono y lo pone todo con el mismo color plano, la opción SMOOTH realiza una suavizado del color de todos los vertices. La que queda mejor es la SMOOTH ya que queda mucho más suave y realista. La opción FLAT no tiene mucho sentido ya que la mayoria de tarjetas gráficas actuales son lo suficientemente potentes para realizar los cálculos que exige la opción SMOOTH. En todo caso, probad ambas opciones y decidid vosotros mismos.

Materiales
Para los materiales hay dos funciones básicas para setear sus características "lumínicas":
glMaterialfv (GLenum face, GLenum name, GLfloat vector_param);
glMaterialf (GLenum face, GLenum name, GLfloat param);

- face hace referencia a que cara se han de aplicar los cambios (frontal o trasera, generalmente será la frontal = GL_FRONT)
 - name hace referencia a que propiedad vamos a modificar
- param (o vector_param) hace referencia al valor  (o vector de valores) que utilizaremos para cambiar las características de nuestro material

Las características que se pueden cambiar de los materiales són:
GL_AMBIENT: Respuesta del material a la luz ambiental
GL_DIFFUSE: Respuesta del material a la luz difusa.
GL_SPECULAR: Respuesta del material a la luz especular.
GL_EMISSION: Cantidad de luz que "emite" el objeto. Cuidado que realmente no emite luz y no ilumina al resto de objetos de la escena. solo es una especie de brillo que habrá en su superficie,
GL_SHININESS: Brillo del material
GL_AMBIENT_AND_DIFFUSE: Este parametro sirve para setear de manera rápida la respuesta ambiental y difusa del material (suponiendo que sea la misma).
GL_COLOR_INDEXES: Por ahora no nos preocuparemos de este parámetro. En posteriores capitulos trabajaremos con el.

Aquí teneís un código de ejemplo de como se pueden usar estos parámetros:
GLfloat mat_ambient[] = {0.1, 0.1, 0.1, 1.0f}; 
GLfloat mat_diffuse[] = {0.0, 0.0, 0.8, 1.0f};
GLfloat mat_specular[] = {0.9, 0.9, 0.9, 1.0f};


glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf (GL_FRONT, GL_SHININESS, 100.0f);




Luces
Para las luces hay un poco más de teoria que no un par de funciones como en el caso de los materiales.

OpenGL es capaz de manejar 8 luces a la vez (nombradas como GL_LIGHT0,GL_LIGHT1...GL_LIGHT7) . La manera de activarlas es mediante glEnable.

Así pues si quisieramos activar dos luces en la escena se debería hacer algo de este estilo:

glEnable(GL_LIGHTING); //Para activar la iluminación
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);

Todos los parámetros de las luces se pueden modificar mediante la función glLightfv( GL_LIGHTn, modo, valores) 
GL_LIGHTn : Identificador de luz
modo: El parámetro que estamos modificando
valores: Los valores de los parámetros que estamos seteando.

Los parámetros que se pueden modificar con esta función son:
GL_AMBIENT: Contribución de esta luz a la luz ambiental total.
GL_DIFFUSE: Luz que rebotará en los objetos proviniente de este foco.
GL_SPECULAR: Luz que rebotará solo en las partes más cercanas del objeto al foco.
GL_POSITION: Posición de la luz. Acepta como parámetros x,y,z,w. Si w es 0 es una luz direccional. 
GL_SPOT_DIRECTION: Dirección en la que ilumina el foco.
GL_SPOT_CUTOFF: Apertura del foco.
GL_SPOT_EXPONENT: Concentración de la luz. Cuanto más alto sea el valor más concetrada estará la luz en el centro del foco.

Factor de atenuación de la luz:  Con la misma función se puede seleccionar como queremos que vaya decreciendo la luz:
GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION. 

Dependiendo de vuestras necesidades os va a ir mejor una u otra , así que os recomiendo que vayaís probandolas todas.

Aparte de todo esto, si queremos, podemos modificar la luz ambiental directamente sin tener que tocar ninguna luz de la siguiente manera:
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, color)

Existen más funciones y parámetros, pero ya elevan demasiado el nivel de complejidad. Por ahora, con ir trasteando con lo que tenemos ya tenemos mucho. En breve os colgaré código de una escena sencilla para que veais todo esto como funciona.

Mis disculpas por el tocho-post, pero era un capítulo ineludible que más tarde o más temprano se tenía que abordar. A partir de ahora el resto será bastante más liviano (espero :) )

Espero que os haya gustado.

Nos vemos.
LordPakusBlog

2 comentarios :

  1. Exelente material muy bien explicado el tema, me saco de muchas dudas, muchas gracias por el material.

    ResponderEliminar
    Respuestas
    1. Gracias a ti por leerlo. No obstante piensa que este artículo se escribió hace años y no tiene más utilidad que la didáctica ( que no es poco). Si miras en webs specializadas de OpenGL verás las cosas más actuales que aprovechan mucho mejor el hardware.

      Nos vemos!

      Eliminar

Entradas populares