Infografia I: Práctica 9: Iluminación - Javi Agenjo at UPF

Infografia I: Práctica 9: Iluminación

Última actualización 25/05/2010

En esta práctica aprenderemos a sombrear objetos para dar más realismo y profundidad a la escena usando los algoritmos de Goureud y Phong. Además servirá para aprender cómo sacar toda la potencia de las nuevas tarjetas gráficas mediante el uso de Shaders.

Material

Enlaces útiles

Requisitos

  • Codigo en C/C++ y GLSL de una aplicación que pinte una mesh con el modelo de iluminación Gouraud y Phong.
  • Se os da un shader con una versión simplificada de Goureud sin especular (light.ps + light.vs), que tiene lo justo para hacer el cálculo del ángulo que forma la luz con la normal (y ademas el color del foco).
  • Teneis que modificar el código del shader y de la práctica para que soporte un modelo de iluminación realista, es decir, que el objeto tenga propiedades y los focos de luz tambien, y despues usar estas propiedades en la ecuación de la luz que pinta el objeto.
  • Para ello teneis que programar dos shaders diferentes, uno para Gouraud y otro para Phong. Recordad que cada shader se compone de un Vertex Shader y un Pixel Shader.
  • No teneis que programar ningun tipo de interpolación, la tarjeta ya se encarga de interpolar los valores que llegan al pixel shader enviados desde el vertex shader en funcion de la distancia a cada vertice (usando las variables varying).
  • En vuestros shaders es necesario que tengais en cuenta las siguientes variables que afectan a la ecuación de la luz, estas variables definen las propiedades del material y de la luz y deben ser enviadas desde la aplicación al shader:
    • Color Ambiente del objeto (si es un objeto muy afectado por la luz ambiente, por lo general usad (1,1,1)
    • Color Difuso del objeto (color del material del objeto)
    • Factor de Specular del objeto (si programais la luz especular)
    • Glossiness del objeto (Shininess), define si un objeto es metalico o mate usad un factor entre 1.0 (plastico) y 20.0 (metalico) solo si programais la luz especular.
    • Color ambiente de la escena (luz que viene del cielo en general, ponedla baja o quemará la escena) (0.1,0.1,0.1)
    • Color de la luz (difuso) normalmente se trabaja con luz blanca (1,1,1)
    • Posicion de la luz (vector que define donde está el foco de luz en espacio de mundo)
  • Recordad, teneis que implementar los siguientes modelos de iluminacion (shaders) que utilicen las propiedades anteriores:
    • Modelo Gouraud todo el calculo se hace desde el Vertex Shader y solo se le pasa al Pixel Shader el color final.
    • Modelo Phong desde el vertex shader computamos los vectores importantes, y los pasamos al pixel shader, allí se normalizan los que deban estar normalziados (ya que al haber sido interpolados se pierde la normalizacion) y se usan para calcular el color final.
  • Para la ecuación de la luz os recomiendo usar la de estos slides
  • Sugerencias opcionales:
    • Ampliar el modelo de iluminación para que soporte reflexion especular. Necesitareis el vector Eye que es el que va desde el centro de la cámara al punto en cuestión.
    • Soportar más de una luz. Basta subir los parametros de la luz dos veces y sumar los resultados del calculo de iluminacion para cada foco.

Fallos comunes

  • No configurar correctamente el visual para que sepa cual es la carpeta de donde tiene que cargar coger los archivos con el codigo de los shaders. Cuando cargas un archivo desde codigo usando una ruta relativa (p.e.: “shaders/light.ps” en lugar de “c:/my_folder/shaders/light.ps”) el sistema lo busca desde la carpeta donde se ejecuta la aplicación, en el visual es la carpeta donde se encuentra el proyecto. Si quereis cambiarla vais a propiedades del proyecto y en Depuración, donde sale Directorio de trabajo, puedes poner la carpeta que querais usar como raiz (por ejemplo la carpeta donde descomprimisteis el codigo).
  • No instalar glew. Necesitais instalar glew para que funcione en OSX o Linux (en windows viene con las librerias que hay colgadas en la web).
  • User un ordenador con una tarjeta que no soporte shaders (cualquier tarjeta Nvidia o ATI soportará shaders), incluso algunas tarjetas integradas los soportan. Si no lo soporta saldrá un error en consola indicando que tu tarjeta no soporta shaders.
  • Utilizar vectores que estan en diferentes sistemas de coordenadas. Recordar, un punto en espacio local se convierte a espacio de mundo cuando se multiplica por la model, y se convierte a espacio de pantalla si se multiplica por la MVP. Suele ser cómodo trabajar en espacio de mundo todo el tiempo (aunque el Vertex Shader tiene que retornar siempre el vertice en espacio de pantalla).
  • No normalizar los vectores que lo requieran o normalizar los que no lo necesitan. Teneis que entender la ecuación.
  • Asumir que las intensidades de la ecuación son un solo valor. Las intensidades nos dicen cómo se comporta en diferentes colores, por lo tanto son colores, un objeto puede tener una componente de intensidad muy roja o muy azul o muy verde, con lo cual no es un unico float, son vectores de tres componentes, es decir, colores.
  • Hacer producto vectorial o escalar entre vectores que contienen colores. No tiene ninguna logica multiplicar vectorialmente colores, lo que sí que tiene logica es multiplicar cada componente de un color por la de otro, a ese proceso se le llama modular, y sirve para por ejemplo saber cual sería el color resultante si un objeto de un color fuese iluminado por una luz de cierto color.
  • Multiplicar vectores geométricos por vectores con colores o sumarlos. No tiene sentido, la componente X de un vector que hace referencia a una posición no tiene nada que ver con el color rojo, etc. Los vectores geométricos (normales, front, etc) se usan para calcular un escalar (cuanta luz afecta) y ese escalar es el que multiplica luego a las componentes de color para definir su intensidad (si le afecta mucho será 1.0, si no le afecta nada será 0.0).
  • Pasar variables uniform desde el Vertex Shader al Pixel Shader usando Varying. No hace falta, esas variables no necesitan interpolarse, ya que desde el Pixel Shader podemos acceder igualmente a las variables uniform, estas no son exclusivas del vertice, son genericas de la mesh por lo tanto es indiferente desde donde las leamos.
Valor: 16 puntos