Efectos de luz

Texto: Miquel Barceló


Es bien sabido que obsesionarse demasiado con un tema concreto no es bueno. Esto suele suceder en los programadores de demos, que se especializan excesivamente en un tema muy concreto (reproducción de la música, motores 3D, etc.) y después se encuentran con dificultades a la hora de abordar un problema diferente. En el caso del efecto que explicamos este mes, encontramos precisamente este problema.

EL EFECTO QUE INTENTAMOS CREAR ES PARECIDO AL QUE VERÍAMOS EN UNA HABITACIÓN CON POLVO SUSPENDIDO EN EL AIRE

El efecto a conseguir es el mostrado en la Imagen 1. Para hacerse una idea de lo que se pretende, uno se puede imaginar que se encuentra en una habitación cerrada a oscuras y con polvo o humo flotando en el aire. En una de las paredes habría una obertura con una forma determinada (en este caso un texto) a través de la cual se colaría la luz difundiéndose con el aire, cosa que hace visible los rayos de luz.

La implementación de este efecto puede abordarse desde muchos puntos de vista diferentes, dependiendo de la inventiva que posea cada uno, y muy probablemente la experiencia acumulada definirá una opción u otra. En muchas ocasiones esta situación puede llevar a un callejón sin salida; en tal caso, es muy aconsejable saber reconocer que uno se puede equivocar y que quizás sea mejor volver atrás y reconsiderar otras alternativas.

La primera impresión no es siempre la correcta

En el caso de este efecto, y después de habernos introducido en el apasionante mundo del raytracing, la primera idea que surge es utilizar una técnica semejante.

Se trataría de simular un montaje como el que se ve en la Figura 1, cuyos componentes serían un plano (con el que se utilizaría un dibujo de la obertura como textura), una fuente de luz situada detrás del plano y una cámara delante, donde se sitúa el punto de vista. Para simplificar un poco los cálculos se supone que la cámara se encuentra fija en el origen y orientada en la dirección del eje Z, mientras que el plano es perpendicular a dicho eje. Para simular la obertura se utilizará una imagen del mismo tamaño de la pantalla, y el color de cada punto indicará la cantidad de luz que pasa.

Después de barajar varias posibilidades lanzamos rayos de luz desde la fuente que se encuentra detrás de la obertura y buscamos intersecciones con el plano de la obertura. Obviamente, sólo haría falta calcular los rayos que realmente pasen a través de la obertura, utilizando un dibujo como patrón (si es blanco la luz pasa, si es negro no).

Así, en la Figura 2 sólo el rayo A se calcularía, ya que el B no pasa a través de la obertura, el C corta con el plano fuera de los límites del dibujo (que coinciden con los de la pantalla) y el D se va en la dirección opuesta. Si quisiésemos ser totalmente rigurosos tendríamos que considerar todos los rayos, pero se trata de conseguir un efecto que funcione lo bastante rápido para ser ejecutado en una demo, por lo que habrá que simplificar bastante la situación.

Una vez obtenidos los rayos que pasan, se podrían proyectar en 2D y dibujarlos como simples líneas rectas. Llegados a este punto, se observa que la cosa no marcha tan bien como se pensaba en un principio. Efectivamente, las primeras pruebas revelaron que el resultado obtenido no era el esperado: por un lado, el tiempo de cálculo era demasiado largo (si tenemos la pantalla a 320x200 esto suponen unas 64,000 líneas/rayos a calcular) y por el otro, visualmente no se conseguía el efecto perseguido. Ante esta situación uno puede plantearse varias cosas:

- Dar por imposible el efecto.

- Intentar optimizar al máximo los cálculos e inventarse "algo" para que quede bien.

- Reconocer que se ha empezado incorrectamente e intentar otro planteamiento.

Haremos precisamente esto último.

UNA PRIMERA APROXIMACIÓN, CALCULANDO LOS RAYOS DE LUZ QUE PASAN POR LA APERTURA, ES BASTANTE SEMEJANTE A LA REALIDAD, PERO DIFÍCIL DE LLEVAR A LA PRÁCTICA

El plan B

Volvemos a encontrarnos como al principio, pero ahora al menos sabemos por dónde no queremos ir. Así que en lugar de empezar a imaginarnos rayos de luz que salen de la fuente, intersecciones con planos y cosas por el estilo, intentaremos centrarnos en lo que tendría que verse en la pantalla. Dada la simetría concreta del efecto no se puede empezar por una esquina de la pantalla sino que hay que comenzar por el punto en el que se vería la fuente de luz en la pantalla. A partir de este punto hay que avanzar en línea recta hasta los bordes de la pantalla y analizar lo que nos vamos encontrando. Aunque durante la explicación nos referiremos a la fuente de luz, al plano y a la cámara, en realidad en el algoritmo final esto no se tiene en cuenta.

CON EL SEGUNDO MÉTODO SIMPLEMENTE DIBUJAMOS LÍNEAS DESDE UN PUNTO DE LA PANTALLA HASTA LOS BORDES DE ÉSTA. ES EN EL MOMENTO DE DIBUJAR EL PUNTO, EN EL QUE SE HACE EL EFECTO

Para conocer cómo funcionaría el tema, imaginaremos un caso bastante simple, como el mostrado en la Figura 3. En esta imagen se representan otra vez la fuente de luz, el plano y la cámara, y unas líneas rectas, señaladas como (A,B,C). Estas líneas corresponden cada una a un punto de la pantalla (X,Y) y vienen a representar lo que se vería si lanzamos un rayo que va desde la cámara a un punto (X,Y) del plano. En esta imagen se representan tres casos significativos de lo que nos vamos a encontrar en el efecto.

A: En este caso, la línea no atraviesa el plano de la obertura (ni ninguna zona iluminada), es decir, que a este punto de la pantalla no llegará luz, por lo que se verá oscuro.

B: La línea atraviesa la apertura, por lo que se vería lo que hay detrás. Para simplificar, vamos a suponer que la iluminación detrás de la abertura es constante, por lo que el punto correspondiente tendrá un color determinado. A esto le hay que añadir que la línea también atraviesa una zona iluminada por la luz que atraviesa la apertura (marcado en verde en el dibujo) que también contribuye. Habría que tener en cuenta la anchura de la zona iluminada para saber cómo contribuye al color final, pero nosotros lo simplificaremos de forma que sea proporcional a la anchura de la apertura que atraviese.

C: La línea sigue sin atravesar la abertura, como en el caso anterior A, pero ahora cruza una zona iluminada por la fuente de luz de detrás del plano (en verde en el dibujo), por lo que sólo tendremos que contar esta contribución.

En la Figura 4 quizás se vea esto más claro. Esta figura representa la intensidad de luz que se vería en la pantalla en función de la distancia a la posición de la "fuente" en la pantalla. Está dividida en zonas que se corresponden con lo comentado en el párrafo anterior. Así, la intensidad se mantiene casi a cero hasta que llegamos a la abertura, entonces se incrementa súbitamente (debido a la luz de "detrás" de la abertura) y sigue creciendo linealmente mientras ésta sea visible. Después de la abertura, la intensidad vuelve a decrecer, pero no se va a cero, sino que se mantiene el valor acumulado.

Antes de continuar, convendría advertir que se han hecho ciertas suposiciones que no tienen por qué ser ciertas, dependiendo de lo que uno quiera complicarse la vida:

- La iluminación que se ve a través de la abertura es uniforme (d).

- La intensidad de luz difundida es directamente proporcional al tamaño de la abertura.

- No se tiene en cuenta que el haz que atraviesa la abertura se ensancha y que pueda haber atenuación dependiendo de la distancia recorrida.

Este es el efecto que intentamos conseguir. En este caso, la imagen que sirve de patrón es un texto en blanco y negro, pero se podría utilizar cualquier imagen en color. (Imagen 1)
Así es como nos imaginamos el montaje que produce el efecto. Aparte del plano de la apertura, podemos ver la fuente de luz (separada una distancia ‘a’) y la cámara (separada ‘b’). (Figura 1)
Los rayos de luz que saldrían de la fuente los podríamos clasificar en varios tipos, aquí marcados con las letras A, B, C y D. Sólo los rayos tipo "A" nos interesan. La línea discontinua indica la parte que queda fuera de la pantalla. (Figura 2)
Siguiendo el segundo método que explicamos en este artículo, puede ser que en un punto de la pantalla no veamos nada de luz ("A"), que podamos ver a través de la apertura ("B") o que veamos sólo la luz que pasa por la apertura y es dispersada por el ambiente ("C"). (Figura 3)
Diagrama de intensidad de la luz que pasa por la apertura, correspondiéndose con la figura anterior. (Figura 4)
  Siguiente