Вы находитесь на странице: 1из 102

Visualizacin de escenas 3D fotorrealistas mediante hardware grfico programable (GPU)

Federico Jorge Marino


fedemarino@gmail.com

Tesis de Grado en Ingeniera Informtica

Director: Ing. Horacio Abbate

Facultad de Ingeniera, Universidad de Buenos Aires

Resumen
El trabajo comienza exponiendo los fundamentos de las tcnicas de iluminacin global para la sntesis de imgenes partir de un modelo 3D y su base fsico-matemtica. Se resean los diferentes algoritmos entre los que se encuentran: Ray Tracing, Path Tracing, Radiosity y Photon Mapping. Luego se analizan las plataformas disponibles para implementar sistemas de rendering en tiempo real como ser clusters de PCs o GPUs (Graphics Processing Unit). Se analiza en detalle la arquitectura de las GPU y las tcnicas para computar algoritmos de propsito general en ellas (GPGPU). A continuacin se propone un caso de estudio que consiste en implementar el algoritmo de Photon Mapping sobre una GPU utilizando OpenGL y el lenguaje Cg. Para ello, se diseo una capa de software orientada a objetos basada en los conceptos del paradigma Streaming Programming Model y la extensin de OpenGL, Framebuffer Object para implementar kernels y streams utilizando los mecanismos de cmputo del hardware grfico. Sobre esa base se construyo un motor de Photon Mapping adaptando una estructura de aceleracin de trazado de rayos denominada BVH (Bounding Volumen Hierarchy) y la tcnica de Photon Splatting para computar la iluminacin indirecta. Finalmente se evala el desempeo, escalabilidad de la implementacin en relacin a varios parmetros, y se analizan diferentes imgenes generadas a partir de un modelo de caja de Cornell (Cornell Box).

Agradecimientos
Debo comenzar agradeciendo especialmente a Horacio, por sus consejos, su dedicacin y su paciencia durante el extenso desarrollo de este proyecto. Siguiendo por los docentes de la Facultad de Ingeniera que me orientaron en mi bsqueda de un proyecto interesante para investigar. Tambin tengo que agradecer a mi familia, por su colaboracin en la redaccin y revisin de varios puntos que integran este trabajo. Siguiendo por mi madre, sin cuya asistencia logstica/gastronmica no hubiera podido dedicar el tiempo suficiente a esta tarea. Por ltimo, a mis amigos y conocidos que creyeron que algn da este proyecto estara concluido.

Federico J. Marino Octubre de 2007

II

ndice General
Resumen Agradecimientos 1. Introduccin 2. Fundamentos de la iluminacin global 2.1. La fsica de la luz 2.2. Terminologa de iluminacin 2.3. Tcnicas 2.4. La ecuacin del Rendering 2.5. Interaccin luz-superficie 2.5.1. La funcin BSSRDF 2.5.2. La funcin BRDF 2.5.3. Reflectancia 2.5.4. Reflectancia difusa 2.5.5. Reflexin especular 2.5.6. Refraccin 3. Algoritmos de iluminacin global 3.1. Ray Tracing clsico 3.1.1. Estructuras de aceleracin 3.1.2. Ventajas 3.1.3. Desventajas 3.2. Path Tracing 3.2.1. Ventajas 3.2.2. Desventajas 3.3. Bidirectional Path Tracing 3.3.1. Ventajas 3.3.2. Desventajas 3.4. Metropolis Light Transport 3.4.1. Ventajas I I II 1 2 2 2 6 6 7 7 8 9 9 10 11 12 12 14 14 14 14 16 17 17 18 18 18 18

3.4.2. Desventajas 3.5. Radiosity 3.5.1. Etapa 1, determinacin de los factores de forma 3.5.2. Etapa 2, resolucin del sistema de ecuaciones 3.5.3. Etapa 3, sntesis de la imagen 3.5.4. Ventajas 3.5.5. Desventajas 3.7. Photon Mapping 3.7.1. Motivacin y antecedentes 3.7.2. El mtodo 3.7.3. Fase 1, trazado de fotones 3.7.4. Fase 2, rendering 3.7.5. Desempeo y mejoras 4. Plataformas de Rendering de alto desempeo 4.1. Clusters de PCs 4.2. Hardware grfico programable 5. GPU (Graphics Processing Unit) 5.1. El pipeline grfico 5.2. El pipeline grfico programable 5.3. Modelo de memoria de la GPU 5.4. El procesador de vrtices 5.5. El rasterizador 5.6. El procesador de fragmentos programable 5.7. Stream Programming Model 5.8. GPGPU 5.9. Computando con un programa de fragmentos 6. Implementacin de un caso de estudio 6.1. Proyeccin perspectiva de la escena 6.2. Fuente de luz 6.3. Geometra de la escena 6.4. Modelo de iluminacin II

19 19 20 21 22 22 22 22 22 23 23 26 27 29 29 30 32 33 35 37 38 38 39 39 40 41 45 45 46 46 47

6.5. Marco de trabajo basado en Kernels y Streams 6.5.1. Clase FpKernel 6.5.2. Clase FpStream 6.5.3. Ejemplo de uso 6.6. Trazador de fotones y rayos en la GPU 6.6.1. La estructura de aceleracin BVH 6.6.2. Clase Tracer 6.6.3. El trazado de fotones 6.7. Photon Splatting 6.8. Motor de Rendering basado en Photon Mapping 6.8.1. La clase SceneLoader 6.8.2. La clase PhotonMapper 6.8.3. La clase Raytracer 7. Evaluacin de la implementacin 7.1. Entorno de hardware y software 7.2. Mediciones del desempeo 7.3. Imgenes 8. Conclusiones 8.1. Trabajos Futuros A Publicaciones B Cdigo Fuente Referencias

48 48 49 51 51 52 54 55 56 59 60 60 62 64 64 64 70 74 74 76 77 94

III

Captulo 1 - Introduccin
Los grficos generados por computadora son cada vez una parte ms fundamental de la vida cotidiana. Desde mbitos como el cine en donde mediante tcnicas sofisticadass casi cualquier produccin con un presupuesto mediano, puede realizan complejas simulaciones que derivan en la creacin de personajes o escenarios virtuales de extremo realismo. Pasando por la industria de los videojuegos, en donde una audiencia cada vez ms exigente y demandante de efectos y simulaciones ms reales, impulsan el desarrollo de la tecnologa de semiconductores, dotando a los dispositivos de juego de un poder de cmputo extraordinario. Llegando a aplicaciones de CAD y animacin 3D para computadores personales que permiten disear y modelar objetos o escenas que pueden ser navegadas virtualmente en tiempo real. La creacin o sntesis de imgenes fotorrealistas se refiere al proceso de generar imgenes artificiales capaces de engaar al ojo humano al tal punto que resulten casi indistinguibles de fotografas tomadas del mundo real. Hace ms de dos dcadas surgieron las primeras tcnicas, como Ray Tracing (1980) y Radiosity (1984), que utilizaron por primera vez simulaciones basadas en principios fsicos. Dichos mtodos tienen su origen en otros campos anteriores a la computacin grfica como la ptica y los problemas de transferencia de calor. Tras aos de evolucin, se han logrado modelar muchos de los efectos de la interaccin entre la luz y las superficies. Sin embargo para lograr altos niveles de realismo an se requieren recursos computacionales importantes. En el caso de la industria cinematogrfica los tiempos que demanda la generacin de un cuadro de animacin no son un factor fundamental (aunque puedan demandar horas o das). Si, en cambio, lo es la calidad del resultado obtenido. Cuando se trata de emplear estos algoritmos de sntesis de imgenes realistas en aplicaciones de tiempo real generalmente se llega a una solucin de compromiso entre una menor calidad a cambio de una mayor velocidad de generacin. La rpida evolucin en el hardware de procesamiento grfico disponible para PCs, ha renovado el inters en investigar nuevas formas de utilizarlo ya sea para implementar algoritmos de iluminacin mas complejos o para el cmputo de otros tipos de aplicaciones no grficas que impliquen procesar grandes volmenes de datos. En este trabajo se busca conocer el estado de arte en cuanto a las tcnicas de iluminacin fotorrealistas, analizar que plataformas estn disponibles para construir aplicaciones de tiempo real que implementen ese tipo de mtodos y disear una solucin que reuna aspectos de los ltimos trabajos en la materia.

Captulo 2 - Fundamentos de la iluminacin global


2.1 La fsica de la luz
La luz tiene una naturaleza dual ya que posee las propiedades de una onda y de una partcula. La luz visible es radiacin electromagntica con longitudes de onda en el rango de los 380 a los 780 nanmetros. A lo largo de la historia, la luz intent ser explicada mediante diversos modelos: ptica de rayos: explica efectos como reflexin y refraccin. ptica de ondas: explica todos los fenmenos de la ptica de rayos y adems explica el efecto de interferencia y de difraccin. ptica electromagntica: incluye a la ptica de ondas y agrega explicaciones a los fenmenos de dispersin y polarizacin. ptica de partculas: explica la interaccin entre luz y materia.

En computacin grfica se usa casi exclusivamente la ptica de rayos, o tambin llamada ptica geomtrica. El proceso que determina el color que tendr la luz que entra al ojo proveniente de una superficie, es dinmico y complejo. Este proceso est regido por las propiedades fsicas de la luz y de los materiales que componen las superficies. Si se observa la luz, desde su aspecto corpuscular, se la puede considerar como una serie de paquetes de energa que viajan a la velocidad de la luz, denominados fotones. Cuando un fotn interacta con una superficie pueden suceder tres casos: Reflexin: si el fotn rebota en una superficie perfectamente suave, el ngulo es determinado por la ley de reflexin, la cual especifica que el mismo, es igual y opuesto al ngulo de incidencia respecto de la normal (reflexin especular). En el caso de superficies irregulares o rugosas, el ngulo de reflexin es mas difcil de predecir ya que la normal en el punto de impacto solo puede determinarse en forma probabilstica (reflexin difusa). Refraccin (o tambin conocido como transicin): el fotn viaja a travs de una superficie. La direccin se determina segn la ley de refraccin o ley de Snell que tiene en cuenta los ndices de refraccin de los dos medios que comparten la superficie. Absorcin: el fotn genera la excitacin de los tomos de la superficie convirtiendo la energa lumnica en calor o reemitindola.

La intensidad o brillo de la luz es proporcional al nmero de fotones y su color depende de la energa contenida en el fotn.

2.2 Terminologa de iluminacin


La energa de un fotn e vara de acuerdo a su longitud de onda y est definida por:

e =

hc

(2.1)

Donde h 6,63 1034 J s es la constante de Planck y c es la velocidad de la luz. La energa radiante espectral Q, en n fotones con longitud de onda se define como:
Q = n e = n hc

(2.2)

La energa radiante Q es la energa de un conjunto de fotones que se calcula integrando la energa espectral sobre un espectro de longitudes de onda, dada por:

Q = Q d
0

(2.3)

El flujo radiante , es la cantidad de energa irradiada por diferencial de tiempo definido como:
= dQ dt

(2.4)

La densidad de flujo radiante por unidad de rea, se define como el diferencial de flujo d por diferencial de rea dA , sobre una superficie determinada y su expresin es:
d d 2Q = dA dt dA

(2.5)

La exitancia radiante M o radiosidad B, se refieren a la densidad de flujo radiante por unidad de rea, saliendo de una superficie en un punto x y est definida por:
M ( x) = B( x) = d dA

(2.6)

La irradiancia E es la densidad de flujo radiante por unidad de rea, llegando o incidiendo en el punto x de una superficie es:
E ( x) = d dA

(2.7)

r La intensidad radiante, es el flujo radiante por unidad de ngulo slido dw , definida por:

r d I ( w) = r dw

(2.8)

r La radiancia, es el flujo radiante por unidad de ngulo slido dw por unidad de rea proyectada dA (ver figura 2.1):

r L( x, w) =

d 2 d 4 n hc d r = 0 r cos dA dw cos dw dA dt d

(2.9)

Representa la radiancia expresada como la integral sobre las longitudes de onda del flujo de energa en n fotones por diferencial de rea dA por diferencial de ngulo r r slido dw por unidad de tiempo, donde es el ngulo entre la direccin dw y la r normal n de la superficie. Esta cantidad es la que representa de modo ms cercano el color de un objeto. Puede pensarse como el nmero de fotones llegando por unidad de tiempo a un rea pequea desde una direccin determinada y puede usarse para describir la intensidad de luz en un punto dado y una direccin determinada.

Figura 2.1: La radiancia, L, r definida como el flujo radiante por unidad de ngulo slido dw , por unidad de rea proyectada dA. Cuando se trabaja con iluminacin que proviene de cierta direccin no tiene sentido tener en cuenta un solo rayo que sera infinitamente delgado porque virtualmente ningn fotn viajara en l. En cambio tiene mas sentido hablar del rea que rodea a cierta direccin. Tambin conocido como ngulo cnico, el ngulo slido, es la porcin de cielo que abarca un objeto visto desde un punto dado. Se puede decir que representa simultneamente el tamao angular y la direccin (expresada en coordenadas esfricas) de un haz. Su unidad es el estereoradin (sr) y es equivalente a un radin al cuadrado. r El tamao de un diferencial de ngulo slido, dw (ver figura 2.2) en coordenadas esfricas es:
r dw = (d ) * (sin d ) = sin d d (2.10)

Donde, es el ngulo entre la direccin y la normal de la superficie S1 y es el ngulo entre la direccin proyectada sobre el plano tangente a la superficie y el eje x. El lado derecho de la ecuacin (2.10) expresa el rea infinitesimal en la esfera unitaria como un producto del largo del arco de longitud d y la longitud del arco de latitud sin d .

Figura 2.2: El ngulo slido. r La direccin w del ngulo slido se puede calcular como:

x = sin * cos y = sin * sin z = cos

(2.11)

2.3 Tcnicas
Las tcnicas de iluminacin pretenden simular o aproximar los fenmenos fsicos de distribucin de la luz (reflexin, refraccin, absorcin, etc.) sobre una escena 3D, con el objetivo de calcular la intensidad lumnica en cualquier punto del modelo. Las tcnicas de iluminacin directa son aquellas que tienen en cuenta solamente la luz que llega a las superficies en forma directa, desde las fuentes. En cambio, las de iluminacin global, permiten capturar la iluminacin indirecta (la que proviene de reflexiones y refracciones en otras superficies), lo cual aporta una gran cuota de realismo a las imgenes generadas aunque a un costo de cmputo mayor. Sin ella, las imgenes obtenidas tienen un aspecto plano y sinttico. Estos algoritmos se alimentan de datos como: Descripcin geomtrica de la escena (vrtices, caras, normales, etc.). Descripcin de materiales de las superficies (coeficientes de brillo, transparencia, color, rugosidad, etc.). Descripcin de fuentes de luz (color, direccin, potencia, etc.).

Existen numerosas tcnicas de iluminacin global, pero sin duda las ms famosas son Ray Tracing y Radiosity. Analizndolas en detalle la mayora se pueden incluir en uno de estos dos grupos:

Mtodos de muestreo de puntos: por ejemplo Ray Tracing, donde se toman gran cantidad de muestras de la iluminacin en diferentes puntos de la escena. Mtodos de elementos finitos: por ejemplo Radiosity. La distribucin de luz se calcula resolviendo un sistema de ecuaciones lineales que representa el intercambio de luz entre parches de las superficies.

Adems hay tcnicas hbridas que combinan aspectos de ambos mtodos.

2.4 La ecuacin del Rendering


La ecuacin, que fue presentada por Kajiya [1], surgi como una forma abstraccin o generalizacin de los distintos algoritmos de iluminacin global. Provee un contexto unificado para analizar cada mtodo particular y describe matemticamente el transporte de luz en cada punto de una escena. Los distintos algoritmos de iluminacin global producen resultados que definen flujos de energa mediante la aproximacin numrica de esta ecuacin, que se basa en la ley de conservacin de energa. r Bsicamente dice que toda la luz emitida en la direccin w por el punto x, Lo, es la r suma de la luz reflejada por el punto, Lr y dispersada en la direccin w mas la luz emitida por el punto Le (es no nula solo si el punto es emisor de luz).
r r r Lo( x, w) = Le ( x, w) + Lr ( x, w)

(2.12)

Desarrollando el trmino de la radiancia reflejada (Lr) obtenemos:

r r Lo ( x, w) = Le( x, w) +

r w '

f ( x, w' , w) L ( x, w)(w'n )dw'


r i

r r

r r r

(2.13)

r Donde es el conjunto de todas las direcciones posibles, n es la normal de la superficie, Li es la radiancia incidente para cada direccin y fr es la denominada funcin BRDF (Bidirectional Reflectance Distribution Function) que para un punto x, da la r fraccin de la luz total proveniente de la direccin w' que es reflejada en la direccin r saliente w . El valor de la funcin BRDF vara entre 0 (no hay reflexin) y 1 (reflexin especular r perfecta) y adems para cada par x, w' se cumple que:

r w '

fr ( x, w' , w) 1

r r

(Cada punto no refleja ms que la luz que recibe) (2.14)

Algunas caractersticas a destacar de la ecuacin son:

Es lineal (solo est compuesta por sumas y multiplicaciones). Homogeneidad espacial (es la misma para todas las posiciones y orientaciones). Depende de la longitud de onda de la luz, por lo tanto la ecuacin debera ser resuelta para cada posible. En la prctica se resuelve para un solo valor (obteniendo la luminancia) o para las tres componentes RGB.

Debido a que, la radiancia incidente Li en un punto, es la radiancia saliente Lo de r otro punto x en la direccin w' , la integral se convierte en recursiva; lo cual la hace imposible de resolver por mtodos analticos, excepto para casos muy simples. Es por ello, que los mtodos disponibles llevan a una solucin aproximada. Existen algunos fenmenos naturales que no pueden ser modelados por esta ecuacin como ser:

La fluorescencia (la luz es reflejada con una longitud de onda diferente). La fosforescencia (la luz es reflejada un instante mas tarde). La polarizacin. La interferencia.

2.5 Interaccin luz-superficie


El fenmeno de dispersin es aquel donde algunas formas de radiacin como en este caso la luz se desvan de su trayectoria original ya sea porque encuentran un obstculo o cambios en el medio que atraviesan.

2.5.1 La funcin BSSRDF


Esta funcin, presentada por Nicodemus et al. [2], segn sus siglas en ingls Bidirectional Scattering Surface Reflectance Distribution Function, describe el proceso por el cual un haz de luz que ingresa en un material, se dispersa en su interior para luego abandonar la superficie en una ubicacin diferente (ver figura 2.3). Esto es comn especialmente en materiales traslucidos como la piel, el mrmol o la cera, donde solo un bajo porcentaje se refleja directamente desde el punto de impacto en la superficie. Este comportamiento ocurre en cierta medida, en la mayora los materiales no metlicos.

Figura 2.3: Funciones BRDF y BSSRDF. La funcin BSSRDF (ecuacin 2.15) [2], S, relaciona un diferencial de radiancia r reflejada, dLr, en x en la direccin w , con el diferencial de flujo incidente di , en x en r la direccin w' . Dado que tiene de ocho dimensiones, es muy costosa su evaluacin.

r r r dLr ( x, w) S ( x, w, x' , w' ) = r di ( x' , w' )

(2.15)

2.5.2 La funcin BRDF


La funcin BRDF (Bidirectional Reflectance Distribution Function), fue presentada por Nicodemus et al. [2] y describe las caractersticas reflectivas de las superficies o tambin se dice que describe un modelo local de iluminacin. Surge de simplificar la BSSRDF, condicionando a que el punto en el que la luz impacta y en el que se refleja sea el mismo (x=x), reduciendo as la dimensionalidad de la funcin a seis.

r r r r dLr ( x, w) dLr ( x, w) fr ( x, w' , w) = r = r r r r dEi ( x, w' ) Li ( x, w' )( w'n )dw'

(2.16)

Esta funcin fr, define que porcentaje de la irradiancia se convierte en radiancia r reflejada y donde n es la normal en x. Partiendo del conocimiento del campo de radiancia incidente en un punto de la superficie, es posible calcular la radiancia reflejada (ecuacin 2.17) en todas las direcciones, integrando la radiancia incidente Li:

r r r r r r r r r r Lr ( x, w) = fr ( x, w' , w)dE ( x, w' ) = fr ( x, w' , w) Li ( x, w' )( w'n )dw'


(2.17)

r Aqu n es la normal en el punto x de la superficie, y es el hemisferio de r r direcciones incidentes en x (cabe notar que w n = cos donde es el ngulo entre la r r normal n y la direccin w ). La funcin BRDF posee las siguientes propiedades:

Invariancia posicional: en general la funcin es invariante respecto de la posicin si se trata de superficies homogneas. Por el contrario, no es invariante en superficies rugosas o heterogneas. Reciprocidad: que establece que la funcin es independiente de la direccin en la que fluye la luz, por lo tanto es posible trazar los recorridos de la luz en ambas direcciones. Conservacin de energa: una superficie no puede reflejar ms luz de la que recibe.

Existen dos clases de funciones BRDF:

Isotrpicas: se refiere a aquellas en donde propiedades de reflectancia no varan segn la direccin. Ocurre en superficies muy suaves. Anisotrpicas: por el contrario, se refiere a esos casos en donde las propiedades son diferentes o dependen de la direccin.

La mayora de los materiales tienen principalmente un comportamiento isotrpico, y exhiben en un grado menor comportamiento anisotrpico.

2.5.3 Reflectancia
Esta cantidad representa la relacin entre el flujo de luz incidente y reflejado en un punto x. La reflectancia , es un valor entre 0 y 1. La fraccin de luz que no es reflejada es absorbida o refractada.

( x) =

d r ( x ) d i ( x )

(2.18)

En la prctica, para la mayora de los materiales, la distribucin de la energa reflejada en las diferentes direcciones, puede modelarse como la suma de dos componentes:

Reflexin difusa. Reflexin especular.

2.5.4 Reflectancia difusa


Tpicamente ocurre en superficies rugosas o materiales que dispersan la luz dentro de sus superficies como por ejemplo tierra, piedra o tela. Las pinturas del tipo mate tienen una alta proporcin de reflexin difusa. Tambin se conoce con el nombre de superficies lambertianas a aquellas que exhiben este comportamiento. La luz incidente es reflejada en todas las direcciones del hemisferio de manera uniforme (ver figura 2.4). La direccin de reflexin es perfectamente aleatoria, por lo r tanto la funcin BRDF, fr,d, es constante respecto de la direccin saliente w y se define como:

r r Lr ( x, w) = fr , d ( x) dEi ( x, w' ) = fr , d ( x) Ei ( x)

(2.19)

Luego trmino, d , conocido como reflectancia difusa, se define como:

d ( x ) =
Dado que

d r ( x ) = d i ( x )

r Lr ( x)dA dw

r fr , d ( x) Ei ( x)dA dw =

Ei ( x)dA

Ei ( x)dA

= fr , d ( x )

(2.20)

dw =

(2.21)

Figura 2.4: Reflexin difusa ideal o lambertiana (izquierda), reflexin difusa (derecha).

2.5.5 Reflexin especular


Sucede cuando un haz de luz choca con una superficie suave, tpicamente metlica o de un material dielctrico (vidrio o agua). En el caso ideal (reflexin especular perfecta o reflexin tipo espejo) de una superficie perfectamente suave, toda la luz incidente se reflejara en una direccin que forma un ngulo igual y opuesto al ngulo de incidencia respecto de la normal de la superficie (segn la ley de reflexin), tambin conocida como direccin de reflexin del espejo (ver figura 2.5). Pero la mayora de las superficies son imperfectas, por lo tanto en estos casos, la luz es reflejada alrededor de un pequeo cono centrado en la direccin de reflexin del espejo. Este tipo de materiales se denominan glossy (ver figura 2.5). El grado de imperfeccin es un parmetro habitual del material llamado comunmente rugosidad usado en los modelos de reflexin. La radiancia debido a la reflexin especular est definida como: r r Lr ( x, ws ) = s ( x) Li ( x, w' ) (2.22)

r r Donde w , es la direccin incidente, ws es la direccin de reflexin del espejo, s , es la reflectancia especular y Li la radiancia incidente. r En el caso de una reflexin especular perfecta, ws es:

10

r r r r r w s = 2( w n ) n w

(2.23)

r r Donde ws = 1 y w = 1

Figura 2.5. Reflexin especular perfecta o tipo espejo (izquierda), reflexin especular tipo glossy (derecha).

2.5.6 Refraccin
Es el efecto de cambio en la direccin de una onda debido a un cambio en su velocidad. Sucede cuando una onda pasa de un medio a otro. En ptica ocurre cuando un haz de luz pasa de un medio con un cierto ndice de refraccin a otro con un ndice diferente.

Figura 2.6: Refraccin de un haz de luz. La ley de Snell o ley de refraccin se utiliza para calcular la direccin del rayo r refractado wr , en funcin de los ndices de refraccin de los dos medios 1 y 2, la r r direccin incidente w y la normal de la superficie n (ver figura 2.6). La relacin entre los ngulos est dada por:

1 sin 1 = 2 cos 2
Y la direccin del rayo refractado se define como:
r r r r 1 r r r r 1 wr = ( w ( w n )n ) ( 1 ( ) 2 (1 ( w n ) 2 ) )n

(2.24)

(2.25)

11

Captulo 3 - Algoritmos de iluminacin global


3.1 Ray Tracing clsico
Fue una de las primeras tcnicas que propuso una solucin de iluminacin global, ya que mediante un algoritmo recursivo incorpora efectos de reflexin, refraccin y sombras. Fue presentada por Whitted en 1980 [3]. Se basa en la observacin que los rayos de luz que importan son solo aquellos que llegan al ojo del observador. En la naturaleza las fuentes de luz emiten fotones que se dispersan por la escena y solo una pequea fraccin de ellos alcanza al ojo, pero simular el proceso de esa manera, no es prctico. La idea principal es trazar el camino recorrido por la luz en sentido inverso, desde el ojo hacia las fuentes de luz, utilizando el hecho de que los fotones se mueven en lnea recta a travs del espacio vaco y que la dispersin de la luz en las superficies es simtrica. Los parmetros de entrada del algoritmo de Ray Tracing son: La posicin del observador. Un plano de vista (direccin y campo de visin). La descripcin de la geometra y los materiales de la escena. Las caractersticas de las fuentes de luz.

Un rayo r se define por un origen x y una distancia d que es la recorrida en la r direccin w , y se resume en la siguiente frmula: r r r ( x, w) = x + d w (3.1)

El algoritmo pretende calcular el color (la radiancia promedio) de cada uno de los pxeles que conforman el plano de vista. Esto se logra trazando uno o ms rayos por cada pxel (ver figura 3.1) y promediando los valores obtenidos.

Figura 3.1: Trazado inverso del recorrido de un haz de luz.

12

El recorrido completo de un haz de luz se conforma de varios segmentos. Cada vrtice del recorrido representa una interaccin con las superficies que hace cambiar su direccin. En la figura 3.1 se observa que el primer segmento o rayo del recorrido (ojo del observador a x1) se denomina rayo primario y es aquel que atraviesa el plano de proyeccin. Luego en los puntos x1, x2 y x3 se generan rayos secundarios producto de la reflexin especular y refraccin en las respectivas superficies. Para calcular la radiancia del rayo primario debemos hallar la menor distancia (el menor valor de d) a la cual el rayo interseca un objeto, dicho de otro modo, hay que encontrar el objeto visto a travs del pxel. Hallado el punto de interseccin x, debemos calcular la radiancia saliente en la direccin del rayo. Para tal fin, debemos conocer la normal de la superficie y la funcin BRDF, fr en x. Con esos datos podemos computar la iluminacin aportada por cada fuente de luz estimando la irradiancia en x. Por ejemplo, la radiancia reflejada, Lr, debido a una fuente puntual con potencia l en el punto p se puede calcular como: r r r r r w n l Lr ( x, w) = fr ( x, w, w' ) V ( x, p ) 2 4 px (3.2)

r Donde w = ( p x) / p x es el vector unitario en la direccin de la fuente de luz. La funcin de visibilidad, V, se evala trazando un rayo de sombra desde el punto x hacia la luz. Si el rayo de sombra interseca un objeto entre x y la luz entonces V=0, de lo contrario V=1. Para superficies especulares o traslcidas el algoritmo debe evaluar la reflexin especular o refraccin trazando rayos secundarios y sumar su aporte a la radiancia total del recorrido, utilizando el mismo procedimiento usado para el rayo primario. A continuacin se detalla una versin simplificada del algoritmo:
Para cada pxel de la imagen crear un rayo desde el ojo a travs de un pxel Color de pxel=trazar(rayo) trazar(rayo) encontrar interseccin mas cercana con la escena computar punto de interseccin y normal color = sombrear(punto, normal) return color sombrear(punto,normal) color=0 para cada fuente de luz trazar rayo de sombra hacia la luz si rayo de sombra interseca luz color=color + iluminacin directa si es especular color = color+ trazar(rayo reflejado/refractado) return color

Dada la naturaleza recursiva de mtodo, la complejidad computacional crece rpidamente a medida que el rbol de recorridos y rayos aumenta en su profundidad. Es

13

por ello que se han propuesto numerosas estrategias para mejorar el desempeo de Ray Tracing, como por ejemplo la del control adaptativo del nivel mximo de recursin a alcanzar en el trazado segn las caractersticas de la escena. Otras estrategias, buscan aprovechar la coherencia existente entre rayos paralelos, cercanos en el plano de vista, que probablemente tendrn interacciones similares con las superficies, para ahorrar u optimizar las ciclos de trazado.

3.1.1 Estructuras de aceleracin


En las primeras implementaciones de Ray Tracing se iteraba sobre todos los objetos para verificar su interseccin con cada rayo. Esto genera un problema de bsqueda lineal de orden O(N) en una escena con N objetos, lo cual resultaba muy ineficiente. En cambio, es conveniente subdividir el modelo en regiones ms pequeas y solo verificar la interseccin de cada rayo con los objetos de las regiones que este atraviesa. De este modo se logran tiempos de bsqueda sub-lineales. Este concepto se materializa en lo que se conoce como estructura de aceleracin, que es una estructura de datos ordenada y construida mediante un preproceso, a fin de reducir la cantidad de verificaciones de interseccin entre rayos y objetos. Ests estructuras pueden clasificarse en dos grandes grupos:

De subdivisin espacial: el espacio de la escena se particiona en regiones. Luego conociendo que regiones atraviesa el rayo, se prueba la interseccin nicamente con los objetos que estn contenidos en ellas. Algunos ejemplos son las grillas uniformes (regiones de igual tamao)[4], grillas jerrquicas [5], los KD-trees o la BSP (Binary Space partition) [7]. De agrupamiento de objetos: los elementos de geometra forman grupos que a su vez conforman una jerarqua de volmenes simples. Entonces, si no hay interseccin entre un volumen y el rayo, se evita probar la interseccin con todos los objetos incluidos en dicho volumen. Un ejemplo de esta estructura es BVH (Bounding Volumen Hierachy) que se detalla en el punto 6.6.1.

Adems, existen numerosas estructuras hbridas que combinan aspectos de las principales.

3.1.2 Ventajas
Simplicidad de implementacin.

3.1.3 Desventajas
No puede calcular la iluminacin indirecta en superficies difusas. No permite computar sombras suaves. No permite computar efectos de enfoque debido a los lentes de cmara. Es dependiente del punto de vista de la escena. No puede simular inter-reflexin difusa entre superficies.

3.2 Path Tracing


Es una tcnica que extiende el mtodo de Ray Tracing, como una solucin a la ecuacin del rendering y fue presentada por Kajiya en 1986 [1]. Incorpor conceptos

14

propuestos por Cook et al. en 1984 [9] en su algoritmo conocido como Distribution Ray Tracing. Est ltimo utiliza el muestreo estocstico para computar efectos como motion blur, profundidad de campo y sombras suaves. Path Tracing hace posible calcular los efectos que requieren evaluar los problemas de integracin recursiva trazando rayos en forma aleatoria en el dominio de integracin para calcular el valor de la integral, mtodo al cual se lo conoce como Monte Carlo. El concepto principal de la teora de Monte Carlo es que la integral i puede ser aproximada evaluando la funcin f sobre un nmero de muestras xi (i=1..N). Obteniendo un valor estimado para I expresado como I :
i = f ( x)dx

I =

1 N

p( x )
i =1 i

f ( xi )

(3.3)

Donde p(xi) es la probabilidad de elegir xi . Lo general del mtodo lo hace aplicable a integrales de varias dimensiones o a funciones arbitrarias. Sin embargo, aunque el estimador de I converge a I cuando N , la convergencia es lenta. El error estndar es proporcional a 1 N por lo tanto para reducir el error a la mitad se necesitan cuatro veces mas muestras. Aplicndolo a Path Tracing, la funcin desconocida es la distribucin de luz. Aqu el mtodo de Monte Carlo busca resolver la ecuacin del rendering completa, por medio de la generacin de todos los posibles recorridos de los rayos comenzando en el ojo y terminando en las fuentes de luz (ver figura 3.2).

Figura 3.2: Trazado de mltiples recorridos de rayos por cada pxel. Con cada impacto sobre una superficie, se suma la radiancia emitida desde el punto y se enva un nuevo rayo en una direccin aleatoria seleccionada de un hemisferio alrededor del punto, de acuerdo con la BRDF de la superficie. Si el rayo impacta en otra superficie, el algoritmo se hace recursivo, el resultado es multiplicado por la probabilidad de elegir esa direccin y agregado al estimador actual.

15

Para estimar con precisin la radiancia en un punto, se debe muestrear y promediar un gran nmero (varios miles) de recorridos de rayos por cada pxel. Un detalle importante de Path Tracing es que utiliza un solo rayo reflejado/refractado para estimar la iluminacin indirecta. Si utilizara varios rayos en cada evento de dispersin de luz, provocara un crecimiento exponencial en el nmero total de rayos requeridos, dada su naturaleza recursiva. Adems, el autor seal que era conveniente concentrar esfuerzos en los eventos que son resultado de pocas reflexiones. Al trazar un solo rayo por evento (reflexin, refraccin, etc.) se asegura que el mismo esfuerzo es invertido en todas las superficies que son vistas directamente por el observador. Para evitar que el algoritmo genere recorridos de rayos de longitud infinita hay que fijar un criterio de terminacin. Una opcin sera trazar todos los recorridos hasta una longitud mxima fija, lo cual resulta ineficiente y generara errores considerables en el resultado de la estimacin al truncar recorridos que podran aportar a la radiancia del pxel en cuestin. La solucin alternativa y elegante es incorporar la idea del muestreo probabilstico al problema de determinar la longitud del recorrido, sin agregar un sesgo al resultado de la estimacin. Esta tcnica conocida como Ruleta Rusa, introducida al rea de computacin grafica por Arvo et al. [26], es una forma de muestreo que tiene en cuenta la distribucin probabilstica de la funcin a estimar para eliminar partes no importantes del dominio. En este hace posible trazar un haz a travs de un nmero finito de rebotes y an as obtener un resultado comparable al que se hubiera logrado trazndolo un nmero infinito de rebotes. Dado que el proceso de generacin de cada recorrido depende de variables aleatorias (la direccin de reflexin al intersecar una superficie difusa es escogida al azar) y que en pxeles cercanos el valor de iluminacin estimado puede variar considerablemente, es comn que se produzca un efecto de ruido (varianza del estimador) en la imagen final. Para reducir dicho efecto es necesario trazar muchos recorridos por pxel y promediar su valor. Hay mtodos para reducir la varianza de los mtodos de Monte Carlo. Uno de ellos es conocido como muestreo por importancia, se fundamenta en tratar de tomar las muestras en aquellas zonas en donde la funcin desconocida tiene valores elevados (usando algn conocimiento a priori de la funcin) para lograr as que el mtodo converja ms rpido. Por ejemplo, una forma de lograr esto es concentrar las muestras en zonas ms iluminadas, las cuales probablemente estn cerca de las fuentes de luz. Aplicando esta idea a Path Tracing, se suelen trazar recorridos secundarios desde cada nodo de un recorrido principal hacia las zonas brillantes. Otro mtodo que funciona muy bien especialmente en escenas de exteriores que incluyen luz de cielo (la cual vara suavemente) es el mtodo de muestreo estratificado. La idea es dividir el espacio de muestreo en celdas, de manera de tratar de cubrir de manera uniforme dicho espacio.

3.2.1 Ventajas

No requiere etapas de preprocesamiento. Maneja cualquier tipo de funcin BRDF. Maneja cualquier tipo de geometra.

16

No requiere demasiado espacio de memoria.

3.2.2 Desventajas

La varianza del estimador de radiancia (el ruido que resulta de usar pocos recorridos por pxel y por lo tanto pocas muestras para estimar la iluminacin). Convergencia lenta (sobre todo en escenas complejas en donde la probabilidad de que un recorrido alcance una zona de alta iluminacin, es muy baja).

3.3 Bidirectional Path Tracing


El trmino bidireccional, se refiere a que los recorridos de los rayos se originan desde dos puntos: el ojo del observador y la fuente de luz. Este cambio logra captar mas fcilmente los efectos de refraccin (vaso de vidrio o una lupa) o de reflexin que producen concentraciones de luz sobre superficies difusas. Este efecto tiene una baja probabilidad de ser captado por el Path Tracing tradicional, ya que implicara que el rayo pasara por una serie de reflexiones que terminen en la fuente de luz. La tcnica fue presentada por Lafortune y Willems [10] en 1993 e independientemente por Veach y Guibas [11] en 1994 como una extensin del algoritmo de Path Tracing. La idea del mtodo es comenzar trazando dos recorridos parciales iniciados respectivamente en la fuente de luz y el ojo del observador. Luego se intenta conectarlos mediante segmentos para los cuales se evala una funcin de visibilidad V. Dicha funcin define si los segmentos o caminos aportan o no iluminacin segn estn o no obstruidos por alguna superficie de la escena. La figura 3.3 ilustra un ejemplo en donde cada nodo Ei (vrtices del recorrido originado en el ojo) se intenta conectar con todos los Li (vrtices del recorrido originado en la fuente de luz). Del resultado de estas combinaciones surgirn una serie de recorridos vlidos que capturarn de forma mas eficiente efectos de inter-reflexin o iluminacin indirecta.

Figura 3.3: Combinacin de recorridos parciales en Bidirectional Path Tracing.

17

3.3.1 Ventajas

Se requieren evaluar menos recorridos por pxel.

3.3.2 Desventajas

La varianza o el ruido de la imagen final es un problema al igual que en el mtodo tradicional. Cada recorrido de luz implica mayor trabajo ya que hay que evaluar las conexiones entre ambos recorridos parciales E y L.

3.4 Metropolis Light Transport


Fue presentado por Veach y Guibas [28] en 1997. En realidad, el mtodo tiene sus orgenes en la dcada de 1950 para la resolucin de problemas de fsica computacional. La estrategia que utiliza es concentrar el trabajo de muestreo en las zonas que ms aportan a la imagen ideal final o en regiones de alta radiancia. En lugar de hacer un muestreo aleatorio de la funcin a integrar, a medida que se generan recorridos (se crean de modo similar que en Bidirectional Path Tracing), estos son clasificados segn su aporte. Luego a partir de los recorridos que ms contribuyen, se aplican mutaciones de segmentos o de pequeos conjuntos de vrtices, para generar nuevos recorridos. Luego del proceso de mutacin, se analiza si el nuevo recorrido es aceptado o descartado dependiendo de si est obstruido por alguna superficie y segn una funcin de aceptacin cuidadosamente definida. Si no se cumplen las condiciones, el recorrido es descartado como invlido. La funcin de aceptacin permite que los cambios a un recorrido sean aceptados siempre en una direccin, mientras que algunas veces son rechazados en la direccin opuesta. Para las mutaciones se usan dos diferentes estrategias:

Permutaciones: la idea es que produciendo cambios pequeos (corrimiento de los vrtices) a un recorrido con alta contribucin a la iluminacin, se producir un nuevo recorrido con alta probabilidad de aceptacin. Estas estrategias de mutacin se enfocan a capturar efectos especficos como el efecto caustics (concentracin de luz debido a la reflexin o refraccin en superficies curvas, como el que produce una lupa o un vaso de vidrio). Se dividen en permutaciones de lentes, permutaciones de caustics y permutaciones de cadenas mltiples. Mutaciones bidireccionales: consisten en reemplazar aleatoriamente tramos del recorrido por nuevos segmentos, pudiendo modificar su longitud total.

3.4.1 Ventajas

Muy efectivo en escenas difciles. Esto es en aquellas donde el aporte a la iluminacin viene de un rea reducida (como por ejemplo un agujero en la pared) que conduce a un rea muy iluminada. Una vez que logra encontrar un camino a travs del agujero, generar mediante mutaciones nuevos recorridos que capturarn la iluminacin de esa zona. No es sesgado.

18

3.4.2 Desventajas

No es eficiente en escenas simples (aquellas escenas donde la luz se encuentra distribuida de manera uniforme). No es aplicable a fuentes de luz puntuales. El nivel de ruido generado en la imagen final es afectado por numerosos parmetros del algoritmo y escoger los valores ptimos a fin de reducirlo no resulta trivial y es altamente dependiente de la escena particular.

3.5 Radiosity
Fue presentado por Goral et al. [12] en 1984 y luego mejorado por Cohen et al. [13,14]. Tiene su origen en los principios fsicos de transferencia de radiacin trmica. La tcnica solo es capaz de computar la iluminacin global de escenas con superficies difusas y que puedan ser subdivididas en pequeas superficies planas (denominadas parches, ver figura 3.4) sobre las cuales la radiancia reflejada y emitida se considera constante. Tpicamente, solo tiene en cuenta aquellos recorridos de luz que salen de la fuente y se reflejan en forma difusa un cierto nmero de veces hasta alcanzar el ojo del observador. Incluyendo ests restricciones se logra simplificar la ecuacin del rendering y la funcin BRDF ya no depende de la direccin incidente, quedando de la siguiente forma.

Lo = Le + fr Li cos dwi

(3.4)

Donde Lo la radiancia reflejada es la suma de la radiancia emitida Le ms la BRDF por la integral sobre el hemisferio, de la radiancia incidente Li por el coseno del ngulo de incidencia .

Figura 3.4. Escena subdividida en parches.

19

La radiosidad Bi para cada parche se define como la suma de la luz auto-emitida Ei (no nulo solo para fuentes de luz) ms la luz reflejada, donde i es la constante de reflectancia del parche (es parte de la descripcin de la escena) y Fij el denominado factor de forma.

Bi = Ei + i BjFij
j =1

i 0..1

(3.5)

El factor de forma es una cantidad sin unidad, que representa la fraccin de la energa total saliendo del parche i que alcanza al parche j. Su cmputo se realiza a partir del tamao, la orientacin y posicin de ambos parches. Dado que depende solo de las caractersticas geomtricas, el factor es vlido para cualquier longitud de onda. Si aplicamos la ltima ecuacin (ecuacin 3.5) sobre todos los parches de la escena, obtenemos un sistema de N ecuaciones con N trminos (B1...BN), el cual puede ser resuelto numricamente por el mtodo de Gauss-Seidel.

1 1F 11 1F 12 ... 1F 1N B1 E1 2 F 21 1 22 F 22 ... 2 F 2 N B 2 E 2 = ... ... ... ... ... NFN 2 ... 1 NFNN BN EN NFN 1
El algoritmo consta de tres etapas: determinacin de factores de forma, calculo de radiosidad (resolucin del sistema de ecuaciones) y rendering de la imagen final.

3.5.1 Etapa 1, determinacin de los factores de forma


Para que el clculo de factores de forma sea preciso es necesaria una subdivisin en parches suficientemente fina como para obtener sombras de buena resolucin.

Figura 3.5: Factor de forma. Su expresin matemtica es la siguiente (ver figura 3.5): Fij = 1 Ai V (i, j ) cos(i ) cos(j )dAidAj r 2 Ai Aj

(3.6)

Donde Ai es el rea del parche i, i es el ngulo entre su normal y el diferencial de rea del parche j, pur tlimo, la funcin V(i,j) determina la visibilidad entre ambos puntos y puede valer 0 o 1.

20

Hay que destacar que el factor de forma Fij tiene carcter recproco, o sea que Fij=Fji. Por lo tanto basta con calcular la mitad de los factores y adems Fii es obviamente nulo. Existen dos maneras de calcularlo: con el mtodo del hemicubo y con el mtodo de trazado de rayos. El mtodo del hemicubo fue propuesto por Cohen et al. en 1985 [14]. La idea es que el rea de la proyeccin del parche sobre un hemisferio que envuelve al parche receptor dividida por el rea total del hemisferio da el factor de forma (ver figura 3.6).

Figura 3.6: cmputo de factor de forma por el mtodo del hemicubo. En la prctica se utiliza un hemicubo en lugar de un hemisferio, ya que aunque es posible proyectar los parches analticamente sobre el hemisferio, esto es mucho ms complejo. El hemicubo y sus 5 caras est subdividido en pxeles, para los cuales se precalcula un factor de forma delta. Luego, el algoritmo consiste en proyectar todos los parches de la escena sobre el hemicubo. En caso de encontrar que dos o mas parches se proyectan sobre el mismo pxel se almacena la informacin del mas cercano. Para finalizar, el factor de forma de un parche i se obtiene sumando todos los factores delta de los pxeles asociados al parche i. Este proceso es fcilmente implementable por hardware. La precisin del clculo se puede ajustar modificando la cantidad de pxeles del hemicubo. El resultado tambin depende de la distancia entre los parches y el tamao de estos.Si el parche es muy pequeo respecto de la distancia puede directamente desaparecer del clculo. Por otra parte, el mtodo de trazado de rayos, consiste en aplicar el mtodo de Monte Carlo, trazando estocsticamente rayos desde el parche i y contabilizando cuantos de ellos alcanzan el parche j. Entonces, el factor de forma se aproxima mediante el cociente entre la cantidad de los rayos que llegaron a j y el nmero total de rayos trazados N. Cuando N tiene infinito el valor del conciente converge al de la integral que se pretende estimar.

3.5.2 Etapa 2, resolucin del sistema de ecuaciones


El sistema de ecuaciones puede ser resuelto en forma completa o iterativa. El primer modo requiere que la matriz principal permanezca en memoria, lo cual no es prctico en escenas con miles de parches (una escena con N parches genera un sistema de N2 trminos) y adems puede llevar mucho tiempo. 21

El otro modo es utlizando el algoritmo denominado Progressive Radiosity, que consiste en calcular una solucin inicial gruesa o aproximada (que puede ser visualizada) la cual luego ser refinada hasta alcanzar un criterio de convergencia establecido. Este mtodo solo requiere la presencia en memoria de una sola fila o columna de la matriz principal.

3.5.3 Etapa 3, sntesis de la imagen


La informacin de iluminacin indirecta obtenida en la etapa 2, puede ser utilizada por un Ray Tracer estndar o un algoritmo de Scan-Line para computar la imagen final. Tpicamente, los valores de radiosidad aplicados a los vrtices, pueden ser interpolados usando sombreado de Gouraud [31] y ser visualizados interactivamente.

3.5.4 Ventajas

Informacin de iluminacin indirecta puede ser precalculada y reutilizada mientras no cambie la informacin geomtrica. Solucin de iluminacin global independiente de la vista (no depende de la posicin del observador).

3.5.5 Desventajas

Solo resuelve iluminacin para superficies difusas. Obliga a subdividir la geometra en pequeos elementos (parches) y la calidad de la solucin depende de esta subdivisin. Requerimientos de memoria se incrementan con parques mas chicos. No captura efectos de iluminacin de alta frecuencia (de rpida variacin sobre un rea reducida), como ser sombras con bordes bien definidos (hard shadows).

3.6 Photon Mapping


3.6.1 Motivacin y antecedentes
Existen mtodos hbridos de varias pasadas que combinan las tcnicas de elementos finitos con las basadas en Monte Carlo, utilizando una fase inicial de preprocesamiento donde se computa una solucin preliminar gruesa de la iluminacin indirecta por el mtodo de Radiosity y luego una segunda fase que calcula la imagen final usando mtodos de Monte Carlo Ray Tracing como Path Tracing. Estas combinaciones son ms rpidas y de mejor calidad que los dos mtodos en su variante ms pura, pero sufren de las limitaciones de los mtodos de elementos finitos, que no pueden manejar geometra compleja. Otra alternativa son los mapas de iluminacin (illumination maps), donde un mapa de texturas (mapas de bits) se utiliza para representar la irradiancia del modelo. Aqu el problema es determinar la resolucin adecuada de estas texturas y cmo mapearlas en superficies complejas. Los nicos mtodos que pueden lidiar con la simulacin de iluminacin global completa en modelos complejos y funciones BRDF arbitrarias son los mtodos basados en Monte Carlo Ray Tracing. Sus ventajas son que no requieren convertir la geometra en un mallado de parches, consumen poca memoria, y dan un resultado correcto excepto por la varianza o ruido, lo cual constituye su mayor problema.

22

Un defecto comn de los algoritmos de estimacin de densidad es que su representacin de los impactos de las partculas de luz est directamente acoplada a la descripcin geomtrica de la escena, condicionando el nivel de detalle de la iluminacin a la definicin del modelo. En casos extremos puede ocurrir que algunos elementos geomtricos no reciban ningn impacto y por ende sean visualizados en negro. Est claro a partir de anlisis de ventajas y desventajas de mtodos mencionados previamente, que un buen algoritmo de iluminacin global debe realizar el muestreo desde ambos puntos de vista, las fuentes de luz y desde el observador para captar todos los efectos. Otra observacin importante es que la iluminacin en general vara suavemente en grandes reas y tiene variaciones grandes en otras reas ms pequeas.

3.6.2 El mtodo
De todas las consideraciones anteriores surge el mtodo de Photon Mapping desarrollado por Jensen [15]. El trmino fotn en este contexto se utiliza para denominar una partcula que transporta una cantidad discreta de energa lumnica en una direccin especfica. El mtodo se clasifica como un algoritmo de estimacin de densidad (de fotones por unidad de rea) de dos fases: distribucin de fotones y recopilacin de estadsticas de iluminacin (sntesis de la imagen). La caracterstica principal de la tcnica es que la estructura de datos que almacena la distribucin de fotones est desvinculada de la representacin geomtrica de la escena y se denomina mapa de fotones (Photon Map). Este mapa es una versin multidimensional de un rbol de bsqueda binaria llamado rbol KD, donde todos los nodos son fotones. Es similar a los rboles BSP, donde cada nodo subdivide el espacio en dos sub-espacios (dos nodos hijos) excepto por las hojas. Photon Mapping consiste de dos fases:

Trazado de fotones: construccin del mapa de fotones trazndolos desde las fuentes de luz. Rendering: utilizando la informacin del mapa de fotones se sintetiza la imagen final.

La estimacin de densidad usando el mapa de fotones presenta errores de baja frecuencia a diferencia del Monte Carlo Ray Tracing tradicional, lo cual es una gran ventaja desde el punto de vista perceptivo ya que este ruido de baja frecuencia es mucho menos notorio que el de alta frecuencia. El precio que se paga es que el mtodo es sesgado (no converge al valor de la integral que se pretende aproximar).

3.6.3 Fase 1, trazado de fotones


Es el proceso que construye el mapa de fotones (Photon Map). Estos se crean en las fuentes de luz que pueden tener una diversidad de formas o distribuciones particulares (ver figura 3.7). Cada fuente posee una potencia que es repartida en sus fotones (cada uno transporta una cantidad fija de energa).

23

Figura. 3.7: Emisin de fotones desde distintas fuentes de luz. En una fuente de luz puntual, los fotones son emitidos uniformemente en todas las direcciones. La emisin se puede realizar de dos maneras: por muestreo explcito, que consiste en mapear variables aleatorias en coordenadas esfricas para cubrir la superficie de una esfera muestreo por rechazo que consiste en generar puntos al azar en un cubo unitario y descartar aquellos que no estn incluidos en la esfera de dimetro unitario. En una fuente esfrica, primero se escoge un punto de origen en la superficie de la esfera y luego se escoge una direccin al azar (siempre que apunte hacia el exterior de la misma). En el caso de una fuente cuadrada, el proceso es similar al de una fuente esfrica. En una fuente direccional, que se caracteriza por emitir rayos de luz paralelos, se debe generar primero un volumen que envuelva a todo el modelo, luego proyectarlo en la direccin de la fuente de luz y escoger un punto sobre esa superficie para determinar el origen de cada rayo (ver figura 3.8). Para las fuentes de luz complejas con formas arbitrarias, se deben generar los fotones con una densidad acorde al perfil de la fuente. Cuando hay ms de una fuente en una escena, la cantidad de fotones emitidos por cada fuente debe ser proporcional a la potencia de la misma (todos los fotones transportan la misma cantidad de energa lumnica).

Fig. 3.8. Fuentes de luz direccionales. 24

Es importante diferenciar un aspecto del proceso de trazar fotones del de trazar rayos. Mientras que los rayos pretenden capturar radiancia, los fotones propagan flujo lumnico, es por ello que la interaccin de los rayos con las superficies es diferente a la de los fotones. Cuando un fotn impacta sobre una superficie, puede ser absorbido, reflejado o refractado. En el caso de la reflexin, si el fotn impact una superficie especular, se reflejar en la direccin de reflexin del espejo. En cambio si impact una superficie difusa, se reflejara en una direccin aleatoria escogida de un hemisferio ubicado por encima el punto de impacto con una probabilidad proporcional a la BRDF. Cabe aclarar que usualmente los materiales de las superficies se modelan como la suma de una componentes: difusa o especular y ante el impacto de un fotn, se tiene en cuenta uno de los dos comportamientos de acuerdo a su respectiva probabilidad En el caso de la refraccin, la nueva direccin ser determinada por las leyes de refraccin. Finalmente en el caso de la absorcin, si la superficie es no-especular, la informacin del fotn es almacenada en el Photon Map (posicin, direccin, etc.). Dado que los fotones almacenados en superficies especulares no aportan informacin til porque la probabilidad de encontrar uno que coincida en forma exacta con cierta direccin de reflexin especular es muy pequea. La decisin sobre cual de los eventos debe suceder, es determinado mediante la tcnica de Ruleta Rusa y el material de la superficie. Utilizando una variable aleatoria uniforme [0..1] y comparando su valor contra las probabilidades de que suceda cada evento:

[0..d ] Reflexin especular [ d ..d + s ] Reflexin difusa [ d + s..d + s + r ] Refraccin [ d + s + r ..1] Absorcin

(3.7)

Donde d , s , r representan la probabilidad de reflexin difusa, especular y de refraccin respectivamente. El Photon Map es una estructura de datos esttica, utilizada para computar densidades de fotones en puntos del modelo 3D. Concretamente es una estructura de rbol KD diseada con el fin de resolver bsquedas de fotones cercanos a determinado punto del espacio 3D de una manera rpida y a la vez eficiente. Debe ser capaz de almacenar millones de fotones que se distribuyen en forma no uniforme por la escena. Cada nodo del rbol particiona una de las dimensiones (X, Y o Z) en dos sub-rboles que contienen los fotones a un lado y otro del plano divisorio. La estructura permite encontrar los k fotones mas cercanos de un conjunto de N para una posicin dada del espacio, en un tiempo promedio del orden de O(k + log N). Del proceso de construccin puede resultar un rbol de fotones desbalanceado. Por eso usualmente se agrega un paso adicional de balanceo que permite luego representar el rbol por un arreglo plano evitando as el almacenamiento de dos punteros a los nodos hijos. El paso de balanceo toma un tiempo adicional del orden de O(N log N) donde N es el nmero de fotones del rbol. Algunos trabajos recientes como el de Wald et al. [16] muestran que un rbol cuidadosamente desbalanceado puede superar en desempeo a uno balanceado, con un costo en tiempo de precmputo mayor y con requerimientos de almacenamiento adicionales.
25

El algoritmo de bsqueda es una directa extensin del de bsqueda en un rbol binario estndar. Se establece un rango mximo de bsqueda (un radio alrededor de un punto), de lo contrario el mtodo se hara muy lento obligando a recorrer zonas con escasos fotones. Se mantiene una lista ordenada de los fotones que van siendo hallados segn su cercana al centro del volumen de bsqueda, de modo que si hay n fotones encontrados y se encuentra uno nuevo, se puede eliminar el ltimo de la lista que es el que estaba ms lejos.

3.6.4 Fase 2, rendering


Durante esta fase, se pretende aproximar la ecuacin del rendering para computar la radiancia reflejada en posiciones de las superficies. La imagen final se obtiene promediando un nmero de estimaciones por cada pxel, trazando rayos desde el ojo del observador hacia la escena. Si consideramos que la BRDF fr es usualmente la combinacin de dos componentes: especular fr,S y difusa fr,D y que la radiancia incidente es en realidad la suma de tres componentes: iluminacin directa Li,l, iluminacin indirecta por reflexin especular o refraccin Li,c, e iluminacin indirecta por reflexin difusa (al menos una vez) Li,d, podemos descomponer la radiancia reflejada de la siguiente manera:

r r r r r r r Lr ( x, w) = fr ( x, w' , w) Li ( x, w' )( w'n )dw' r Lr ( x, w) = D + E + C + I r r r r r r D = fr ( x, w' , w) Li , l ( x, w' )( w'n )dw'


r r r r r r r E = fr , S ( x, w' , w)( Li , c ( x, w' ) + Li , d ( x, w' ))( w'n )dw'

(3.8)

r r r r r r C = fr , D ( x, w' , w) Li , c ( x, w' )( w'n )dw'

r r r r r r I = fr , D( x, w' , w) Li , d ( x, w' )( w'n )dw'

El trmino de la iluminacin directa D, corresponde al clculo de la radiancia reflejada debido a la luz que proviene directamente de la fuente y se calcula de manera precisa del mismo modo que en el Ray Tracing tradicional, ya que es uno de los trminos ms importantes porque genera por ejemplo el efecto de sombra. En el caso de fuentes de luz no puntuales, se utilizan varios rayos de sombra para estimar apropiadamente las zonas de penumbra. Para el trmino de reflexiones especulares E, no se utiliza el Photon Map, en cambio, se utiliza la tcnica de Monte Carlo Ray Tracing. El trmino C se puede calcular de manera aproximada evaluando el estimador de radiancia a partir del Photon Map, o de manera mas precisa usando uno especial denominado Caustics Photon Map, que almacena solo los fotones que generan el efecto de caustics (luces enfocadas por reflexin o refraccin). Este ltimo se construye trazando fotones solo hacia objetos del tipo especular. Por ltimo el trmino que representa la luz proveniente de reflexiones sobre superficies difusas I, se calcula tambin evaluando el estimador de radiancia pero a partir del Photon Map principal.
26

El cmputo del denominado estimador de radiancia, se basa en que la radiancia r reflejada Lr, de la ecuacin del rendering en el punto x y la direccin w , puede ser estimada con los k fotones ms cercanos del Photon Map:

r 1 Lr ( x, w) 2 r

f ( x, w
r p =1

r r r p , w) p ( x, wp )

(3.9)

r Donde wp es la direccin incidente, y p es la potencia del fotn p, r es la distancia mxima hasta cada fotn y r 2 es el rea del crculo conteniendo los fotones. Dado que la bsqueda de los fotones se realiza en una esfera, es probable que se introduzcan errores en la estimacin, al incluir fotones que llegan a la superficie por detrs, en una esquina o atravesando un objeto delgado y que no deberan contribuir a la iluminacin del punto x. Estos efectos pueden reducirse, comparando la direccin incidente y la normal de la superficie y descartando mediante un producto escalar a aquellos que llegan por detrs. Aunque los fotones estn contenidos en una esfera, la densidad se mide sobre el rea de la esfera proyectada sobre la superficie (ver figura 3.9) la cual que tiene forma de disco. El uso de una distancia mxima r es para evitar que la bsqueda de fotones abarque reas excesivamente grandes.

Fig. 3.9: estimador de radiancia El ruido en la imagen final se reduce a medida que se aumenta la cantidad de fotones usados en el estimador de radiancia. Est demostrado que se puede obtener un estimador arbitrariamente bueno incluyendo una cantidad suficiente de fotones.

3.6.5 Desempeo y mejoras


El algoritmo genera soluciones de iluminacin global completas, de mayor calidad y en menor tiempo que otros mtodos como Path-Tracing. Dada la popularidad de esta tcnica, su robustez y su sencilla implementacin, se presentaron muchas mejoras y extensiones. Entre ellas, se present una extensin para computar efectos de dispersin dentro de superficies traslucidas (sub-surface scattering) que simulan materiales como la piel o el mrmol. Tambin se desarrollaron extensiones para computar efectos atmosfricos tales como niebla o humos. Entre las mejoras propuestas se encuentra el algoritmo propuesto por Ward [17] denominado Irradiance Caching, que permite reducir el nmero de bsquedas de fotones cercanos para 27

computar los estimadores de radiancia interpolando los valores de otros estimadores calculados para puntos cercanos del espacio.

28

Captulo 4 - Plataformas de Rendering de alto desempeo


Estas plataformas comprenden aquellas comnmente utilizadas para implementar sistemas de visualizacin que requieren el procesamiento de grandes volmenes de datos en tiempos relativamente breves con el objetivo de sintetizar imgenes a partir de un modelo o escena. Tal es el caso de sistemas que requieren generar secuencias de imgenes para componer una animacin, en donde es deseable una tasa de generacin de cuadros cercana a los 15 cuadros por segundo para lograr una sensacin de fluidez de movimiento propia de las secuencias cinematogrficas. Tambin es el caso de los sistemas de visualizacin interactivos (por ejemplo sistemas de realidad virtual), en donde la intervencin del usuario mediante algn dispositivo de entrada modifica las variables del modelo (por ejemplo el cambio de posicin o direccin observacin de la escena), a partir de las cuales el sistema debe generar una nueva respuesta en forma de imagen. Las estrategias generalmente aplicadas en estos sistemas, apuntan a subdividir las tareas de cmputo en bloques independientes que puedan ser resueltos en forma simultnea o paralela por varias unidades de procesamiento. Los algoritmos de sntesis de imgenes suelen ser altamente paralelizables, lo cual significa que existe un alto de grado de independencia entre los datos a procesar y los resultados que estos generan, permitiendo su cmputo simultneo en unidades separadas. Esta es una caracterstica deseable ya que reduce la necesidad de comunicacin o sincronizacin entre nodos y logra un mximo aprovechamiento del tiempo de procesamiento de cada unidad. En el caso de los algoritmos de iluminacin global mencionados en el captulo 3, la gran cantidad de clculos y la complejidad de la escena a sintetizar, hacen que una CPU estndar (Intel Pentium IV 3.0 GHz) demore varios minutos y hasta incluso horas en generar una imagen. Dos caminos para encarar el problema planteado son: Implementacin sobre clusters de PCs. Implementacin sobre hardware grfico programable (GPUs).

A continuacin se analizarn ms en detalles ambas alternativas.

4.1 Clusters de PCs


Son sistemas conformados por un conjunto de hosts o PCs interconectados mediante una red local (ver figura 4.1) de alta velocidad (Fast o Giga Ethernet) entre los cuales se distribuyen las tareas de cmputo para ser procesadas en forma simultanea por todos los nodos. Respecto al modo de subdividir las tareas de cmputo, algunos sistemas definen como unidad bsica de trabajo un cuadro o imagen completa. Otros en cambio, explotan al paralelismo inter-cuadro, subdividiendo la ventana de visualizacin en porciones o fragmentos independientes. Estos son alimentados a cada nodo para luego ser integrados nuevamente en una sola imagen o ser provistos directamente a dispositivos de visualizacin conformados por mltiples pantallas en configuracin de matriz.

29

Cada nodo de la red posee una memoria propia, debiendo intercambiar informacin o sincronizar su estado con el resto de la red mediante el pasaje de mensajes. Estos sistemas explotan el paralelismo de grano grueso, lo cual significa que las tareas a realizar por cada procesador, deben insumir un tiempo relativamente largo en comparacin a los tiempos de comunicacin entre nodos (latencia de la red y overhead de los mensajes). De otro modo, la eficiencia del sistema se vera reducida, ya que se desperdiciara un alto porcentaje de tiempo en la comunicacin.

Figura 4.1. Cluster de PCs. Existen ejemplos como el caso del sistema Chromium [23], que provee un mecanismo genrico para manipular y procesar secuencias de comandos de una API grafica estndar. El sistema virtualiza los recursos disponibles en la red, permitiendo ejecutar por ejemplo una aplicacin OpenGL (Open Graphics Library) estndar incluso sin necesidad de recompilarla. Otro caso es el de WireGL [24], un sistema de rendering distribuido, escalable, que permite a una aplicacin realizar el proceso de rendering sobre una matriz de mltiples pantallas. No requiere el uso de una API especfica y puede funcionar sobre hardware estndar de bajo costo.

4.2 Hardware grfico programable


Est tipo de hardware tambin conocido como GPU (Graphics Processing Unit), comprende unidades dedicadas exclusivamente al procesamiento de grficos 3D. A diferencia de las CPU, su diseo especializado permite procesar tareas grficas en tiempos ms breves. Aunque, las GPUs ms recientes son capaces de procesar cientos de millones de vrtices y miles de millones de fragmentos (estructura de datos que actualiza el color de cada pxel) por segundo, no estn preparadas para computar algoritmos de propsito general, Es decir no es sencillo portar cdigo de una aplicacin escrito originalmente para una CPU. A pesar de ello, hoy en da, representan la mejor relacin entre poder computacional por dlar. Adems su desempeo crece a ritmos mayores que las CPU, dado que se duplica aproximadamente cada 12 meses. El crecimiento e innovacin en este campo es impulsado principalmente por la industria de los video-juegos. A continuacin se comparan las caractersticas de ambas unidades de procesamiento:

30

CPU
Utiliza la memoria principal (RAM) del sistema. Arquitectura SISD (single instruction single data). Optimizada para alto desempeo de cdigo genrico secuencial (caches y prediccin de bifurcacin). Su desempeo se duplicada cada 18 meses. Intel Pentium 4 3.0 GHz Desempeo: 6 Gigaflops (tericos) Memoria: 6 GB/seg (pico). Aptos para algoritmos de propsito general. Accesible en forma directa.

GPU
Utiliza una memoria dedicada contenida en la placa grfica de la PC (memoria de texturas). Arquitectura SIMD (single instruction multiple data). Optimizada para procesamiento paralelo de cdigo con alta proporcin de operaciones aritmticas. Su desempeo se duplica cada 12 meses Nvidia GeforceFX 5900 Desempeo: 20 Gigaflops Memoria: 20 GB/seg (pico). Diseadas para implementar algoritmos grficos especficos Accesible mediante una API (Aplication Programming Interfase). Requiere el uso de nuevos paradigmas no convencionales, como Stream Programming.

Paradigmas de programacin convencionales como: Programacin Orientada a Objetos, Procedural, etc.

31

Captulo 5 - GPU (Graphics Processing Unit)


El trmino fue acuado por NVIDIA a finales de la dcada de los 90, cuando el trmino Video Graphics Array (VGA) Controller ya no defina de forma precisa las funciones del hardware grfico en una PC. Se trata de un dispositivo capaz de manipular, procesar y mostrar grficos de manera eficiente. Su arquitectura altamente paralela, conformada por mltiples unidades de ejecucin, es capaz de realizar operaciones de punto flotante con 32 bits de precisin y trabajar simultneamente sobre mltiples conjuntos de datos. Hoy en da, es un componente estndar del subsistema de video en la mayora de las PC. En el siguiente cuadro se detalla su evolucin:

1998 3DFX Voodoo, NVIDIA TNT y ATI Rage. Realizan proceso de rasterizacin (conversin de forma vectorial a pxeles) de tringulos y mapeo de hasta 2 texturas. Menos de 10 millones de transistores por GPU. No son capaces de aplicar transformaciones a los vrtices. Operaciones aritmticas muy limitadas. Implementan funciones de DirectX 6.0. 2000 NVIDIA GeForce serie 2 y ATI Radeon. 25 millones de transistores por GPU. Incorporan capacidad de transformar vrtices. Son configurables, pero an no programables. Implementan funciones de DirectX 7.0. 2001 NVIDIA GeForce series 3 / 4 y ATI Radeon serie R200. Incorporan programabilidad en el procesador de vrtices. 60 millones de transistores por GPU. Poseen ms opciones de configuracin que las series anteriores, para procesar vrtices, pero an no son programables. Implementan funciones de DirectX 8.0. 2003 NVIDIA GeForce serie FX y ATI Radeon serie R300. 120 millones de transistores por GPU. Programabilidad a nivel vrtices y fragmentos. Soporte completo de DirectX 9.0. 2004 NVIDIA GeForce serie 6 y ATI Radeon serie R420. 220 millones de transistores por GPU. Introduccin de sistema SLI (Scalable Link Interface). Introduccin de modo MRT (Mltiple Render Targets). 2005 NVIDIA GeForce serie 7 y ATI Radeon serie R520. 300 millones de transistores por GPU. Mayor velocidad de reloj y ensanchamiento del pipeline (ms unidades de procesamiento en paralelo).
32

2006 NVIDIA GeForce serie 8 y ATI Radeon serie R600. Arquitectura de unidades de procesamiento unificada (procesan vrtices y fragmentos). 700 millones de transistores por GPU. Soporte completo para DirectX 10.0.
En futuras generaciones se espera que los recursos de la GPU se generalicen cada vez ms permitiendo an mayor grado de programabilidad.

5.1

El pipeline grfico

Un pipeline consta de una secuencia de etapas que operan en un orden determinado (similar a una lnea de montaje industrial). Cada etapa recibe en su entrada el resultado del proceso de la etapa anterior y todas las etapas en conjunto pueden operar simultneamente sobre distintos elementos. El pipeline grfico puede ser pensado como una caja negra por donde fluyen conjuntos de datos que sufren transformaciones para generar como resultado final una imagen 2D o un mapa de bits. Aunque en realidad no se trata de una caja negra ya que uno puede controlar la forma en que los datos son transformados. Este pipeline recibe en su entrada los vrtices correspondientes a la geometra de la escena 3D. Cada vrtice es una estructura de datos que contiene las coordenadas homogneas de un punto en el espacio 3D y otros atributos opcionales que pueden ser escalares o vectoriales (de 2, 3 o 4 componentes) que se definen en funcin de la aplicacin que se quiera implementar. Los principales son:

Posicin: coordenadas homogneas del vrtice. Normal: vector que indica la direccin en que apunta la superficie, en el punto definido por la posicin. Este dato es til para clculos de iluminacin. Color: este dato luego ser utilizado para sombrear el rea de pantalla que cubra la primitiva geomtrica segn el tipo de algoritmo de sombreado que se use. Puede haber ms de un color definido por cada vrtice. Coordenadas de textura: un par de coordenadas reales mapean un punto sobre una textura 2D, que se utilizar luego para el sombreado de la primitiva geomtrica. Pueden utilizarse varios pares de coordenadas de vrtice para indexar diferentes texturas.

Adems, el usuario puede definir otros atributos de utilidad para modelar caractersticas de los materiales de las superficies representadas. Sobre los vrtices se aplican una serie de operaciones matemticas denominadas transformaciones de vrtices que incluyen traslaciones, rotaciones, cambios de escala y proyecciones. Al utilizar un sistema de coordenadas homogneas, todas las transformaciones pueden representarse por matrices (de 4 x 4) que al multiplicarlas por los vectores de coordenadas de los vrtices dan como resultado el vector transformado. Otra ventaja de las coordenadas homogneas, es la posibilidad de encadenar varias transformaciones multiplicando sus matrices asociadas. El objetivo de las transformaciones es traducir las coordenadas de la escena 3D del espacio de coordenadas abstracto de cada objeto (modelo o patrn de un objeto 3D) a las coordenadas 2D en el denominado plano de vista o plano de visualizacin.

33

Esta conversin de coordenadas se subdivide en varias fases:

Transformacin de modelado: implica posicionar, rotar y escalar el objeto respecto del resto de la escena (traducir coordenadas del modelo a coordenadas del mundo). Transformacin de vista: implica convertir las coordenadas de toda la escena a un sistema con origen en el punto de vista y la direccin de la cmara o el ojo que observa la escena. Transformacin de proyeccin: implica convertir coordenadas del espacio tridimensional de las coordenadas de vista a coordenadas en un plano de proyeccin bidimensional. Existen varios tipos de proyeccin como ser la perspectiva o la ortogrfica. La matriz de proyeccin se define a partir de un denominado volumen de vista (view frustum) que establece como mapear una porcin de espacio sobre el plano de proyeccin.

Las 3 transformaciones se aplican en orden a cada vrtice de la escena. Luego, los vrtices transformados son combinados en la etapa de ensamblado, para formar las que se conocen como primitivas geomtricas (ver figura 5.1) que comprenden: puntos, lneas, tringulos, etc.

Figura 5.1: Primitivas geomtricas. Para continuar, el proceso de rasterizacin descompone las primitivas en elementos del tamao de pxeles, llamados fragmentos que intervienen en la definicin del color de los pxeles de la imagen 2D generada a la salida del pipeline.

Figura 5.2: Representacin del pipeline grfico.

34

Un fragmento es una estructura de datos asociada a la ubicacin de un pxel de la imagen de salida. Tambin se puede pensar al fragmento como un pxel potencial ya que algunos son descartados. En la figura 5.2, se detalla la evolucin de los datos a lo largo de las etapas. En la industria, OpenGL y Direct3D son los dos modelos de pipelines grficos ampliamente aceptados como estndares.

5.2

El pipeline grfico programable

En la actualidad la mayora de las etapas del pipeline grfico son implementadas directamente en el hardware, exhibiendo un alto grado de programabilidad. Esto significa que los algoritmos que implantan son modificables y son suministrados por la aplicacin de alto nivel como parte del flujo de datos de entrada del pipeline. Incluso es posible ingresar secuencias que intercalan datos geomtricos y los programas que deban procesarlos, permitiendo el uso de diferentes algoritmos para distintos objetos de la escena. En las primeras generaciones de GPUs dichos programas estaban grabados en el hardware (no eran modificables) y eran solo configurables en forma limitada. Los programas suministrados al pipeline programable son de dos tipos: los programas de vrtices (aplican las transformaciones a los vrtices) y los programas de fragmentos (computan los datos que definirn los colores de los pxeles). Ambos tipos de programas pueden ser escritos en diversos lenguajes como:

Cg (C for Graphics): es un lenguaje [29] de sombreado (shading language) de alto nivel desarrollado por NVIDIA y Microsoft. Est basado en el lenguaje C y tiene algunos tipos de datos agregados, adecuados para programar en la GPU. Es un lenguaje especializado. Un compilador lo traduce al assembler o cdigo de mquina. HLSL (High Level Shading Language): desarrollado por Microsoft para utilizarse con Direct3D, es muy similar a Cg. GLSL (OpenGL Shading Language): fue creado por OpenGL Architecture Review Board y tiene caractersticas muy similares a los dos anteriores.

La figura 5.3 ilustra la estructura del pipeline grfico programable. El proceso comienza cuando la aplicacin de alto nivel enva a la GPU un conjunto de vrtices. En la primera etapa el procesador de vrtices los trasforma de acuerdo a un programa de vrtices y define el valor del resto de sus atributos. Las transformaciones tienen como objetivo traducir la posicin de cada vrtice, del sistema de coordenadas del objeto modelado (tridimensional) al sistema de coordenadas de la pantalla (bidimensional) aplicando un conjunto de operaciones aritmticas representadas por productos de matrices (de traslacin, escalado, rotacin y proyeccin).

35

Figura 5.3: El pipeline grfico programable. En la segunda etapa (ensamblado y rasterizacin) se ensamblan los vrtices transformados (vrtices con coordenadas en el espacio de pantalla) para formar la primitiva geomtrica. A la primitiva ensamblada se le aplican los procesos de Clipping y Culling. El proceso de Clipping, se encarga de recortar la primitiva geomtrica, para remover las porciones que quedan fuera del rea que se pretende visualizar (denominada ventana del mundo). El proceso de Culling se encarga de descartar aquellas primitivas que no deben dibujarse ya que se encuentran de espaldas al observador de la escena. Las primitivas geomtricas que no son descartadas, pasan al proceso de rasterizacin. Este consiste en determinar qu pxeles del dispositivo de salida son cubiertos por la primitiva geomtrica y generar los correspondientes fragmentos. Los fragmentos son estructuras de datos transitorias que almacenan atributos como:

Posicin: ubicacin del pxel al que est asociado. Son un par de coordenadas enteras. Profundidad: es la distancia en el eje Z (eje perpendicular al plano de vista) al origen del punto de observacin. Color: surge de la interpolacin lineal de los atributos de color de los vrtices que dieron origen al fragmento. Coordenadas de texturas: del mismo modo que el color, su valor es interpolado linealmente.

Adems un fragmento puede poseer otros atributos especialmente definidos por la aplicacin como por ejemplo varios colores y pares de coordenadas de texturas adicionales. La tercera etapa, habitualmente llamada de sombreado (porque tradicionalmente define el color de los pxeles segn algn modelo de iluminacin) es implementada por el procesador de fragmentos segn un programa, que da como resultado el color del pxel asociado. El programa resuelve el color a partir de los atributos del fragmento y otros datos disponibles en la memoria de la GPU, como texturas y parmetros globales definidos por la aplicacin. La informacin almacenada en texturas se accede mediante

36

ndices computados por el programa a partir, por ejemplo, de las coordenadas de texturas. Para finalizar, los fragmentos pasan por una serie de pruebas (Scissor Test, Alpha Test, Stencil Test y Depth Test) y procesos (Blending y Dithering) que son parte estndar de OpenGL y Direct3D para evaluar cuales producirn una actualizacin del pxel correspondiente en el buffer de salida y cuales deben ser descartados.

5.3 Modelo de memoria de la GPU


Existen tres reas de almacenamiento de datos en una GPU:

Memoria para datos de vrtices: este espacio es esencialmente utilizado para leer los atributos de los vrtices desde el procesador de vrtices. Estos son cargados desde la aplicacin ejecutada en la CPU. En las GPUs ms recientes es posible escribir o copiar datos en esta memoria, a partir de un programa de fragmentos (modo copy-to-vertex-array). Framebuffers: se utilizan principalmente para escribir los resultados generados por el procesador de fragmentos (hasta 16 valores de punto flotante de 32 bits, utilizando el modo MRT) y luego ser visualizados en el dispositivo de salida. Memoria de texturas: su nombre se debe a que surgi como un espacio para almacenar informacin de imgenes 2D que representan muestras de colores y atributos de superficies. Est optimizada para acceso mediante coordenadas 2D. Es la que se utiliza como memoria de trabajo en programas de fragmentos que implican mltiples pasadas permitiendo hacer ciclos de lectura y escritura de datos. Hoy en da es posible utilizarla para otros datos, que no necesariamente estn relacionados con imgenes o colores. Por ejemplo, es posible almacenar estructuras de datos ms complejas, como listas, arreglos 1D y 3D, etc. Estas estructuras requieren implementar mecanismos de traduccin de direcciones y conversin de tipos de datos, ya que la forma primitiva de organizar los datos es en arreglos bidimensionales de valores de punto flotante con tamao fijo.

La siguiente figura 5.4 ilustra la relacin entre las 3 reas de memoria, los procesadores de vrtices, fragmentos y la CPU.

Figura 5.4: reas de memoria en la GPU.

37

Se espera que este modelo de memoria siga evolucionando hacia un modelo ms general que permita una mayor flexibilidad en las operaciones de lectura y escritura.

5.4 El procesador de vrtices


Es el encargado de ejecutar los programas de vrtices (vertex programs). El proceso comienza con la carga de los atributos de los vrtices en registros de entrada. A medida que se ejecutan las instrucciones del programa de vrtices, los resultados intermedios son almacenados en registros temporales. Adems el programa tiene acceso a registros de solo lectura en donde se almacenan constantes globales de la aplicacin (existe una sola instancia para todos los programas de vrtices). Las instrucciones disponibles incluyen operaciones matemticas sobre vectores de punto flotante de hasta 4 componentes (X, Y, Z, W), instrucciones de control de flujo, de salto y lazos. Las ltimas generaciones de GPUs permiten el acceso aleatorio a memoria de texturas desde el programa de vrtices. La salida del programa son las coordenadas transformadas del vrtice y el resto de sus atributos que son almacenados en registros de slo-escritura para luego ser provistos al rasterizador. Existe un lmite en la cantidad total de instrucciones, por ejemplo, para las GPUs NVIDIA de la serie GeForce 6 es de 512 instrucciones estticas (las del programa compilado) y 65535 dinmicas (son las que realmente se ejecutan al multiplicar los bloques que incluyen ciclos por la cantidad total de ciclos especificados). Es importante destacar que por cada vrtice de la escena se ejecuta una instancia independiente del programa de vrtices, pudindose as procesar varios vrtices en paralelo dependiendo de la cantidad de unidades de procesamiento de vrtices que posea la GPU.

5.5 El rasterizador
Primero el rasterizador ensambla los vrtices transformados por la etapa anterior para conformar la primitiva geomtrica de acuerdo a un comando suministrado por la aplicacin que indica como deben vincularse los vrtices, para formar un polgono determinado.

Figura 5.5: Proceso Clipping, Culling y Rasterizacin. Sobre el plano de vista, se define un rea rectangular denominada ventana del mundo, que representa la zona de inters que se pretende visualizar. 38

Luego el proceso de Clipping se encarga de determinar que partes de la primitiva estn dentro de la ventana de visualizacin o ventana del mundo y generar, de ser necesario, una versin recortada de las mismas. En la figura 5.5, el tringulo nro. 1 es recortado para remover las porciones que estn fuera del rea de inters. El proceso de Culling determina si las primitivas estn de frente o de espaldas al observador de la escena, evitando as dibujar elementos no visibles (por ejemplo en la figura 5.5, el tringulo nro. 4 es descartado por este proceso). Por ltimo, el proceso de rasterizacin proyecta la primitiva recortada sobre el plano de visualizacin, convirtiendo el elemento geomtrico vectorial 2D en su representacin en forma de fragmentos (ver figura 5.5). Los fragmentos generados son suministrados a la etapa siguiente junto con las coordenadas del pxel al que estn asociados. Es importante sealar que la cantidad de fragmentos no tiene relacin con la cantidad de vrtices de una primitiva (un polgono de 3 vrtices puede generar millones de fragmentos, si la primitiva cubre toda ventana del mundo).

5.6 El procesador de fragmentos programable


Este procesador ejecuta programas de fragmentos. En una GPU existen ms de una unidad de procesamiento de fragmentos, cada una capaz de procesar un fragmento a la vez. Las entradas del programa de fragmentos son los atributos que surgen de hacer una interpolacin lineal de los atributos de los vrtices que le dieron origen al fragmento. Adems de las instrucciones tpicas disponibles en los programas de vrtices, los de fragmentos agregan instrucciones para acceder a una textura mediante un par de coordenadas reales. Este mecanismo utiliza lo que se denominan sampler objects, que toman una muestra de la textura en base a la interpolacin de los valores de los pxeles cercanos. El procesador de fragmentos cuenta tambin con un conjunto de registros de lectura/escritura para almacenar valores intermedios. Como salida, el procesador de fragmentos genera una serie de valores que representan atributos de un pxel de la imagen final como ser color, transparencia, etc. En el caso de los programas de fragmentos el lmite en la cantidad de instrucciones es de 65535, tanto dinmicas como estticas. Aunque los programas de fragmentos y vrtices permiten el uso de instrucciones de bifurcacin (If / Else), es importante saber que a diferencia de un programa ejecutado en una CPU, ambas ramas de la condicin son evaluadas. Y el costo en tiempo computacional es el de la suma de ambas.

5.7 Stream Programming Model


Este paradigma o modelo de programacin naci con el surgimiento de los procesadores de streams y un cambio de tendencia en el desarrollo de la tecnologa de semiconductores, en donde el costo de cmputo es proporcionalmente cada vez ms barato que el costo del acceso a la memoria. En este tipo de procesadores se trata de reutilizar al mximo los registros internos del chip para entrada/salida de datos y as minimizar el acceso al sistema de memoria externa para poder mejorar el desempeo de los programas. Se pretende explotar la localidad y el paralelismo existente en los programas empleando centenares de unidades trabajando simultneamente sobre distintas partes o tareas independientes que componen un mismo programa. 39

El modelo impone restricciones sobre la forma en que deben ser escritos los programas a fin de que el compilador logre optimizar el cdigo y mapearlo de modo directo al hardware. El paralelismo y la localidad del cdigo estn explcitamente definidos en el modelo. Uno de los componentes de este modelo son los kernels, que bsicamente son llamadas a funciones que realizan un nmero considerable de cmputos sobre un conjunto de datos de entrada y escribe los resultados sobre otro conjunto de datos de salida. Estos conjuntos de datos sobre los que opera se denominan streams. Los kernels no pueden poseer un estado, esto significa que sus resultados no deben depender de los resultados de una invocacin anterior.

Figura 5.6: Stream Programming Model En resumen, la figura 5.6 ilustra los conceptos esenciales del modelo, donde un kernel (programa) procesa streams (datos de entrada) y genera streams (datos de salida). Adems un kernel puede tener acceso a parmetros globales almacenados en un rea de memoria de slo-lectura. Los streams son los elementos que conectan los kernels entre s. Relacionando los conceptos del modelo con el modelo de programacin en una GPU, se pueden observar analogas en la forma en que los kernels operan sobre los streams y el modo en el que los programas de fragmentos operan sobre los datos almacenados en la memoria de texturas. Por lo tanto, el procesador de fragmentos puede ser interpretado como un procesador de streams que implementa un subconjunto de funciones de las que tendra un procesador de streams ideal. Esto se debe a ciertas limitaciones de las GPUs actuales, entre las que se encuentran la imposibilidad de escribir un dato en una direccin computada dinmicamente desde un programa de fragmentos, o el lmite en la cantidad de streams de salida por programa (4 streams). Existen varios trabajos recientes, orientados en este sentido, como los Purcell [6,8] en donde propone la implementacin de un motor de Ray Tracing o un motor de Photon Mapping sobre hardware grfico programable, utilizando el paradigma de Stream Programming.

5.8 GPGPU
La posibilidad de utilizar la GPU como un procesador de streams ha generado todo una tendencia que se conoce como GPGPU (General Purpose Computation on a GPU) que implica la utilizacin de la unidad de procesamiento grfico para computar

40

algoritmos de propsito general que incluso no relacionados a la computacin grfica como por ejemplo: Procesamiento de seales de audio y video. Simulaciones fsicas. Procesamiento de bases de datos. Simulaciones cientficas.

En la prctica slo se hace uso del procesador de fragmentos, ya que las GPUs actuales poseen mayor cantidad de unidades de procesamiento de fragmentos que de vrtices. Entre las dificultades se encuentran las limitaciones inherentes al hardware grfico sobre el que se trabaja, la casi nula existencia de herramientas de depuracin.

5.9 Computando con un programa de fragmentos


Bajo el esquema GPGPU, los programas de fragmentos escriben sus datos de salida en la memoria de texturas, en lugar del framebuffer (buffer utilizado para mostrar la salida por el dispositivo de pantalla), para que luego puedan ser utilizados como entrada en fases de cmputo subsiguientes. Este modo de trabajo se conoce como rendering a texturas (Render-to-Texture). La extensin de OpenGL llamada Framebuffer Object [19] permite gestionar y vincular las texturas OpenGL con buffers lgicos especiales asociados a las salidas del procesador de fragmentos. Un programa de fragmentos puede escribir hasta en 4 texturas simultneamente utilizando el mecanismo MRT (Multiple Render Targets). Respecto de las entradas de un programa de fragmentos, existen 2 tipos:

Parmetros uniformes: son suministrados directamente por la aplicacin ejecutada en la CPU. Pueden ser valores escalares, vectores o manejadores de texturas (un puntero a un arreglo de valores de punto flotante). Su valor es constante e idntico para todos los fragmentos asociados al programa. Parmetros variables: llegan al programa de fragmentos luego de la etapa de rasterizacin (color, coordenadas de texturas, normales, etc.) y cada fragmento recibe un valor diferente que surge de la interpolacin lineal de los correspondientes atributos de los vrtices.

Hay casos en que se desea definir valores de entrada especficos para cada fragmento, que no sean el resultado de la interpolacin lineal de atributos de los vrtices de la primitiva geomtrica. En estos casos se utiliza un mecanismo de direccionamiento de memoria en base a coordenadas de textura. Dichas coordenadas se definen para los vrtices de una primitiva geomtrica que al ser rasterizada genera los pares de coordenadas intermedias mediante interpolacin lineal. En el programa de fragmentos, se hace una lectura de la textura 2D que contiene los valores de entrada, utilizando como ndice el par de coordenadas de textura. Este mecanismo es aplicable a mltiples streams de entrada. La figura 5.7 ilustra un caso donde el programa de fragmentos utiliza tres parmetros de entrada in1, in2 e in3. El par de coordenadas coord lo genera el rasterizador, interpolando el atributo del mismo nombre, definido en los 4 vrtices del rectngulo. 41

Figura. 5.7: Acceso indirecto a la memoria de texturas. El cmputo de propsito general en la GPU tiene algunas limitaciones que impiden implementar cierto tipo de algoritmos que requieren operaciones de escritura a memoria de acceso aleatorio, tambin conocidas como operaciones de dispersin (scattering operations). En este esquema, cada programa de fragmentos puede guardar informacin persistente solo en el pxel del buffer de salida (utilizando MRT se puede extender esta cantidad a 4 pxeles, cada uno con 4 componentes de 32 bits, correspondientes al formato de color RGBA), pero no puede escribir en una direccin de memoria aleatoria. Por el contrario, las operaciones de reunido (gathering operations) son sencillas de implementar, como se observ en el ejemplo de la figura 5.7. Para ejecutar los cmputos especificados en el kernel, bajo la plataforma OpenGL, se deben efectuar los siguientes pasos (ver figura 5.8):

Configurar la matriz de proyeccin: definir la matriz de proyeccin (GL_PROJECTION) para obtener proyeccin ortogrfica de la escena. Configurar la matriz de transformacin: cargar la matriz identidad como matriz de transformacin (GL_MODELVIEW) . Configurar la ventana en el dispositivo de salida: establecer el rea de pantalla (en pxeles) sobre la cual se computar la salida del pipeline. Est rea debe coincidir con las dimensiones exactas del o los streams de salida (en definitiva una textura 2D). Cargar el programa de fragmentos: se carga y compila el programa a partir del archivo de texto con extensin .cg. Establecer parmetros: Se establecen los valores parmetros uniformes y variables requeridos por el programa Cg, desde la aplicacin de alto nivel. Configurar de buffers de salida: Se vinculan las texturas de los streams de salida con los 4 buffers lgicos disponibles mediante la extensin FBO. Dibujo de la primitiva: se dibuja una primitiva geomtrica del tipo rectngulo (GL_QUADS) que cubra todo el plano de vista y se definen las coordenadas de textura de sus vrtices, de modo que coincidan con las coordenadas de sus pxeles asociados (ver ejemplo en figura 575).
42

Actualizar buffers de salida: mediante el comando glFlush() se inicia el proceso de rasterizacin del rectngulo y se inicia el cmputo del programa de fragmentos.

Figura 5.8: Cmputo de un kernel usando el procesador de fragmentos en el modo render-to-texture. Es importante notar que para cada fragmento se ejecuta una instancia independiente del programa Cg. Estas instancias se ejecutan en paralelo por mltiples unidades (en GPUs como las NVIDIA GeForce de la serie 6 oscilan entre 16 y 32 unidades). Por lo tanto no es posible referirse, en una instancia, a los valores de salida generados por otra. En esta limitacin yace la eficiencia del procesamiento paralelo del sistema. Muchos algoritmos requieren mltiples ejecuciones de un mismo kernel en ciclos que implican leer y escribir sobre un mismo conjunto de datos (streams de entrada y salida). En estos casos se maneja la estrategia de ping-pong, que consiste en alternar

43

en sucesivas iteraciones el rol de 2 streams, uno de entrada y otro de salida (ver figura 5.9).

Figura 5.9: Estrategia de Ping Pong. Esta estrategia se utiliza debido a que la especificacin de la extensin Framebuffer Object no garantiza un correcto funcionamiento al leer y escribir una misma textura dentro de un mismo programa. Sin embargo, en este trabajo, no se observaron inconvenientes con este modo de utilizacin, por lo tanto se descart el uso de pingpong a pesar de la falta de garantas. Cuando se implementan kernels de mltiples pasadas (mltiples iteraciones de un mismo kernel sobre un conjunto de streams) es necesario poder detectar cuales elementos del stream no requieren ms procesamiento (porque alcanzaron cierto estado final definido segn el algoritmo implementado). Esto puede ocurrir en diferentes momentos para diferentes elementos del stream, dependiendo de las condiciones particulares y los valores de las variables involucradas. En un programa de fragmentos, es posible indicar esta condicin o estado de finalizacin mediante una instruccin Cg, denominada discard. Esta instruccin evita que el resultado del programa de fragmentos sea escrito en el buffer de salida, aunque no ahorra en ciclos de cmputo, activa un bit especial asociado al pxel. La extensin de OpenGL, OCCLUSION_QUERY, permite saber cuantos fragmentos alcanzaron dicha condicin contabilizando la cantidad de esos bits que estn activos. La forma de utilizar este mecanismo sera la siguiente:
mientras (fragmentos_activos>0){ kernel.ejecutar(); fragmentos_activos=obtenerOcclusionQuery() }

44

Captulo 6 - Implementacin de un caso de estudio


En este captulo, se propone el desarrollo de una aplicacin que implemente el algoritmo de Photon Mapping sobre una plataforma basada en hardware grfico programable, con el fin de analizar cuales fases de esta tcnica son factibles de computar en la GPU, evaluar el desempeo y las limitaciones existentes. Se diseo una capa de software de base o un marco de trabajo que provee los mecanismos bsicos del Stream Programming Model, esto es, un conjunto de clases que encapsulan los conceptos de los kernels y los streams. Luego a partir de esas clases se construy un motor de rendering, que combina una estructura de aceleracin de trazado denominada BVH (Bounding Volumes Hierachy) y la tcnica de Photon Splatting para reconstruir la iluminacin indirecta. Ambas tcnicas ya fueron implementadas individualmente en una GPU, en el caso de BVH, se generaliz la implementacin original, para trazar tanto rayos como fotones. A continuacin se establecen los parmetros que describirn el observador de la escena (ubicacin, direccin y campo de visin, resolucin de imagen de salida, etc.), la fuente de luz, la geometra 3D y las propiedades de sus materiales en la aplicacin. Adems se definen las caractersticas del modelo de iluminacin implementado.

6.1 Proyeccin perspectiva de la escena


A continuacin se definen los parmetros de la aplicacin, que definen las dimensiones del volumen de visualizacin (o view frustum, ver figura 6.1), que es la porcin de espacio 3D a ser proyectada sobre el plano de proyeccin para representar la vista de la escena.

Figura 6.1: Volumen de visualizacin.

wsize y hsize: resolucin horizontal y vertical (pxeles) de la imagen de salida (tambin denominada resolucin del viewport). width y height: ancho y alto del rea de proyeccin de la escena en el plano cercano. pos: vector posicin de ojo del observador o punto de vista. normal: vector perpendicular al plano de proyeccin. up: vector que seala el lado superior del plano de proyeccin.
45

near: distancia al plano de proyeccin cercano desde el ojo del observador. far: distancia a plano lejano.

6.2 La fuente de luz


La fuente de luz fue modelada como una fuente tipo spotlight, donde los rayos son emitidos dentro de la zona delimitada por un cono orientado (ver figura 6.2). Los parmetros que la definen son los siguientes:

pos: vector origen de la fuente lumnica. normal: vector que indica direccin de emisin. up: vector que indica lado superior del plano de emisin. maxAngle: es el ngulo respecto de la normal que indica el punto en el que la potencia lumnica decae a cero. minAngleRatio: indica el ngulo mnimo como una fraccin del ngulo mximo, a partir del cual la potencia comienza a decaer linealmente hasta cero. splatRadius: es el radio del splat, utilizado en la etapa de Photon Splatting. power: indica la potencia lumnica total de la fuente.

Figura 6.2: Fuente de luz tipo spotlight. Como se observa en la figura 6.2, la intensidad lumnica de la fuente se mantiene en su valor mximo entre la direccin normal y el ngulo mnimo. Luego decae linealmente hasta cero en el ngulo mximo (maxAngle). En la aplicacin implementada slo est prevista la definicin de una nica fuente.

6.3 La geometra de la escena


Los modelos geomtricos utilizados en este caso de estudio, fueron generados con 3D Studio Max y exportados en el formato 3DS. Luego, en la aplicacin, este archivo es interpretado por una librera que devuelve las coordenadas de los vrtices y las normales de los tringulos junto con el nombre del material y su color. Utilizando el nombre del material como clave de bsqueda, se accede a una librera de atributos de materiales definida en el archivo de parmetros general (.INI). Para cada material se definen:

color: en formato RGB. diffuseK: ndice de reflexin difusa, es un nmero real entre 0 y 1.
46

specularK: ndice de reflexin especular, es un nmero real entre 0 y 1. reflectK: ndice de reflectividad del material, define la intensidad con que se refleja el entorno. Es un nmero real entre 0 y 1. Un valor mayor a 0 implica trazar un rayo secundario para calcular el color la inter-reflexin especular o reflexin tipo espejo. smoothing: indica si las normales deben ser o no interpoladas sobre la superficie de cada tringulo para lograr un efecto de superficie suave. Admite dos valores posibles: 0 o 1. selfIlum: indica si el material emite luz propia. Admite dos valores: 0 1. se utiliza slo para destacar claramente un objeto rectangular que representa la fuente de luz, pero no altera ni genera iluminacin sobre su entorno.

Para evaluar el desempeo de la implementacin, se generaron variantes del modelo conocido como Cornell Box (ver figura 6.3), utilizando diferentes tipos de materiales y objetos ubicados en el interior de la caja.

Figura 6.3: Modelo Cornell Box.

6.4 El modelo de iluminacin


Mediante Ray Tracing, luego de trazar los rayos primarios desde el ojo del observador (ver figura 6.4), se calcula la iluminacin en las superficies intersecadas combinando las siguientes componentes:

Ambiente: se define como el producto del color del material y el coeficiente de luz ambiental (ambientK), que es un parmetro global de la aplicacin. Directa: utilizando modelo de Phong [30], se computa en base a los coeficientes de reflexin difusa y especular asociados al material de la superficie (diffuseK y specularK respectivamente) y se multiplica por un factor de visibilidad que puede valer 0 1. Dicho factor, se obtiene trazando un rayo de sombra para determinar la visibilidad de la fuente de luz. Es la iluminacin que proviene directamente de la fuente.

47

Indirecta: se computa utilizando la tcnica de Photon Splatting (ver punto 6.7 para ms detalles). Es la iluminacin que llega al punto tras, al menos, una reflexin difusa. Inter-reflexin especular perfecta: se obtiene trazando un rayo secundario en la direccin de reflexin del espejo. Slo en los casos en que el material de la superficie en cuestin posea un ndice de reflectividad (reflectK) mayor a cero.

Figura 6.4: Componentes de iluminacin. A, B y C son tres fotones que aportan iluminacin indirecta al punto P.

6.5 Marco de trabajo basado en Kernels y Streams


En base a los conceptos presentados en el capitulo 5, se construy una capa de software de base que provee los elementos bsicos del Stream Programming Model implementado sobre el hardware grfico, utilizando el mecanismo de rendering a texturas y el procesador de fragmentos de la GPU. Para ello, se definieron dos clases C++ denominadas FpKernel y FpStream.

6.5.1 La clase FpKernel


Est asociada a un programa de fragmentos Cg y sirve para implementar kernels de una o de mltiples pasadas. Utiliza los servicios de clase FBO [22], que presenta una mnima abstraccin de la extensin OpenGL Framebuffer Object, para la gestin y vinculacin de texturas y buffers de salida. La figura 6.5 muestra mediante un diagrama UML los mtodos y atributos principales de la clase. El mtodo constructor recibe como parmetros las dimensiones del o los streams de salida, el nombre archivo Cg y el nombre de la funcin Cg a invocar dentro de ese archivo (entryPoint). El procedimiento de uso de la clase es el siguiente en:

Inicializar la clase: mediante el mtodo init. Establecer parmetros uniformes: mediante los mtodos setParamater. Vincular streams: mediante el mtodo setStream.
48

Ejecutar el kernel: mediante el mtodo run.

Figura 6.5: Clase FpKernel. El mtodo setParameter1f admite un parmetro real escalar y el mtodo setParameter3fv admite un vector de 3 componentes reales, adems en ambos casos en necesario suministrar el nombre del parmetro asociado al valor, en el programa Cg. El mtodo setStream, vincula los streams al kernel, esto es, conecta el identificador de la textura 2D OpenGL con el parmetro asociado en el programa Cg Finalmente el mtodo run, inicializa, vincula la instancia del Framebuffer Object y realiza el cmputo utilizando el modo de render a texturas. El mtodo devuelve la cantidad de fragmentos activos en la corrida del programa (OCCLUSION_QUERY).

6.5.2 La clase FpStream


Su atributo principal es una textura rectangular OpenGL con un formato de 1,3 o 4 canales float de 32 bits de precisin que representa el stream (de tipo GL_TEXTURE_RECTANGLE_ARB). Existen tres clases descendientes asociadas a los modos de uso de los streams (entrada, salida o entrada/salida). A continuacin, la figura 6.6 detalla los mtodos y atributos principales de la clase y sus tres clases descendientes:

49

Figura 6.6: Clase FpStream y sus clases descendientes. El mtodo constructor de un stream de entrada (FpStreamInputOnly) admite como parmetro un stream de salida (FpStreamOutputOnly), permitiendo vincular la salida de un kernel con la entrada de otro. Este vnculo se establece a nivel lgico (ver figura 6.7), ya que en realidad existe una sola instancia de los datos, representada por un mismo identificador de textura OpenGL (texture id).
Nivel lgico (Instancias de FpKernel y FpStream) Vnculo lgico FpKernel 1 Output FpStream 1 Input FpStream 2 FpKernel 2

Nivel fsico (Programas Cg y texturas 2D) Salida Programa de fragmentos Cg 1 Textura OpenGL 2D Entrada Programa de fragmentos Cg 2

Figura 6.7. Esquema lgico y fsico de Kernels y Streams

50

Es posible tambin crear mltiples streams de entrada por referencia, esto es, varios streams que comparten el mismo espacio de almacenamiento bajo diferentes denominaciones.

6.5.3

Un ejemplo de uso

El siguiente ejemplo ilustra la forma en que se combinan ambas clases para crear un programa sencillo que implementa un kernel de mltiples pasadas.
int w = 64; h = 64; // Resolucin horizontal y vertical // Declaracin de kernels FpKernel k; FpStreamInput sIn1,sIn2; FpStreamInputOutput sInOut; // instanciacin de los kernels // inN son los identificadores en el programa CG // *dataN poseen datos para inicializar los streams k = new FpKernel (w,h,krn1.cg); sIn1=new FpStreamInput(w,h,in1,*data1); sIn2=new FpStreamInput(w,h,in2,*data2); sInOut = new FpStreamInputOutput (w,h,0,in3,*data3); // fija el valor de un parmetro uniforme k->setParameter1f(sampleparam,1.75); k->setStream(sIn1); //vincula stream de entrada 1 k->setStream(sIn2); //vincula stream de entrada 2 k->setStream(sInOut);//vincula stream de entrada/salida int occlusion_query=0; do { occlusion_query=k->run(); // ejecuta el kernel } while (occlusion_query>0); // iterar

La figura 6.8 muestra la relacin entre los distintos objetos del ejemplo anterior.

Figura 6.8: Diagrama de Kernels y Streams para el ejemplo de uso.

6.6 Trazador de fotones y rayos en la GPU


Dadas las similitudes entre el proceso de trazado de rayos y fotones, se decidi disear una clase C++ capaz de resolver el trazado de ambos casos mediante un 51

mecanismo unificado. Se utiliz la estructura de aceleracin BVH (Bounding Volumes Hierachy) y los ejemplos provistos en el trabajo de Thrane et al. [18] como base para la implementacin del caso de estudio. En dicho trabajo se presenta a esta estructura como la ms eficiente y sencilla desde el punto de vista de la programacin, para implementar en la GPU.

6.6.1 La estructura de aceleracin BVH


Es una estructura que subdivide la escena en una jerarqua conformada por dos tipos de nodos: tringulos y volmenes envolventes (ver figura 6.9). La estructura tiene la forma de un rbol binario. Los nodos internos corresponden a los volmenes envolventes que contienen a todos los elementos de su rama. Los volmenes, en este caso, son cajas alineadas con los ejes coordenados. Las hojas del rbol corresponden a los elementos geomtricos de la escena (en este caso los tringulos). La idea detrs de esta estructura es ahorrar un gran nmero de verificaciones de interseccin entre tringulos y rayos. Para ello se envuelve un conjunto de elementos geomtricos cercanos con una caja (alineada a los ejes coordenados) y se evala la interseccin del rayo con la caja (lo cual, tiene de hecho, un costo menor que evaluar la interseccin de un rayo y un tringulo). En caso de no existir interseccin con la caja, tampoco existir con los elementos geomtricos contenidos en ella. El proceso para verificar la interseccin de un rayo con toda la escena implica recorrer el rbol haciendo un descenso recursivo comenzando por la raz.

Figura 6.9: Ejemplo de la estructura BVH aplicada a un conjunto de 5 tringulos. No existe hasta el momento un algoritmo ptimo de construccin del rbol, pero existen diferentes heursticas. El algoritmo que se utiliz en esta implementacin esta basado en el presentado por Thrane et al. [18]. La idea general es tomar el conjunto de tringulos que conforman la escena, calcular las dimensiones de una caja alineada a los ejes coordenados que envuelva a todo el conjunto (Bounding Box) y luego calcular la media aritmtica de las coordenadas de los vrtices de todos los tringulos. A continuacin se debe dividir el conjunto de tringulos en 2 mitades, segn un plano cuya normal coincida con el lado ms largo de la caja, que pase por la media aritmtica del conjunto de vrtices (ver figura 6.9). Cada subconjunto de tringulos pasa a formar parte de los dos nodos hijos segn el centro de cada tringulo se encuentre de uno u otro lado del plano de corte. Luego el proceso se repite para cada nodo hasta que quede un solo tringulo por nodo. 52

A continuacin se delinea el algoritmo de construccin:


BVHNode construirArbol (tringulos) if (tringulos es solo 1 tringulo){ return hoja del rbol con un tringulo }else { Calcular punto de corte (media arit. de coord. de los vrtices) Calcular mejor plano de corte (cuya normal = al lado mas largo) BVHNode res res.leftChild = construirArbol (tringulos a la izq. del corte) res.rightChild = construirArbol (tringulos a la der. del corte) res.boundingBox = caja que envuelva a todos los tringulos return res }

El proceso de construccin lo realiza la CPU como un preproceso junto con la carga del modelo 3D. El resultado es un conjunto de arreglos (ver fig. 6.10) que indican como recorrer el rbol para hacer la verificacin de intersecciones (no se almacena la estructura completa, sino slo los datos necesarios para recorrerlo en forma descendente).

0 1 2 3 4 5 6 7 8

Traversal Array type index escape code 0 0 INF 0 1 6 0 2 5 1 0 -1 1 1 -1 1 2 -1 0 3 INF 1 3 -1 1 4 -1 type: 0 = bounding box 1 = triangle

0 1 2 3

bbox_min (x,y,z) V0 (x,y,z) V1 V2

bbox_max N0 N1 N2

0 1 2 3 4

Figura 6.10: Estructuras de datos del algoritmo BVH.

53

El algoritmo de deteccin de intersecciones rayo-tringulo usando la estructura BVH, comienza recorriendo el arreglo Traversal Array en orden secuencial, evaluando en cada posicin si hay interseccin entre el rayo y el nodo. Si el valor del campo type es 0, se debe acceder a los parmetros de la caja envolvente en los arreglos bbox_min y bbox_max, que definen las coordenadas de sus extremos usando el valor del campo index. Si el valor del campo type es 1, se debe acceder a los arreglos V0, V1, V2, que definen los vrtices del tringulo. En caso de no verificarse interseccin,con un nodo, esto significa que tampoco ocurrir con ningn elemento de la rama. El cdigo de escape (escape code) indica a qu registro del arreglo hay que saltar para evitar toda la rama. Los arreglos N0, N1 y N2 son las normales en cada uno de los vrtices de los tringulos.

6.6.2 Clase Tracer


Esta clase se ocupa de trazar rayos o fotones, a partir de dos streams que indican los orgenes y las direcciones. La clase utiliza los servicios de la clase SceneLoader (ver punto 6.8.1), encargada de cargar la geometra de la escena desde un archivo y generar las estructuras de datos para el algoritmo BVH. La figura 6.11 detalla los mtodos y atributos principales de la clase.

Figura 6.11: Clase Tracer. El mtodo init, que inicializa los atributos internos, acepta como parmetros: los streams de orgenes, direcciones y de estado inicial (indica si algn rayo o fotn no debe ser trazado). El mtodo trace realiza el trazado utilizando la estructura de aceleracin detallada en el punto 6.6.1. Por ltimo, los mtodos getTraverserStates y getIntersectorNormals devuelven en forma de streams el resultado del trazado que incluye por cada rayo o fotn:

Estado: indica si el rayo o fotn impact alguna superficie o sali fuera de los lmites de la escena.

54

Coordenadas de impacto: define el punto exacto de impacto sobre el tringulo, en coordenadas locales del plano del tringulo. Identificador del tringulo impactado: el ndice del tringulo dentro de la escena. Distancia Z: la distancia al punto de impacto desde el origen del rayo o fotn hasta alcanzar el punto de impacto en la superficie.

6.6.3 El trazado de fotones


Para el caso de estudio se estableci un mximo de 4 etapas de trazado de fotones. En la figura 6.12 se observa un ejemplo en donde se emiten 1000 fotones desde la fuente de luz. En la primera etapa los fotones son trazados hasta interactuar la primera superficie S1. Dichos fotones representan iluminacin directa, por lo tanto, no es til almacenarlos, ya que la iluminacin directa se resuelve mediante Ray Tracing. Por lo tanto Ab1 es 0 y todos los fotones incidentes en S1 son reflejados.
diffuseK = 0,3 specularK = 0,1 absorbK = 0,6 S2 Ab2=600 Pm2=600 S4 Ab4=96 Pm4=96

Fuente de Luz Nf=1000 Re1=1000 Rd1=750 Rs1=250

Re3=160 Rd3=120 Rs3=40 Re2=400 Rd2=300 Rs2=100

Re4=64

S1

Ab1=0 Pm1=0

S3

Ab3=240 Pm3=240

Nf = nmero de fotones emitidos Rei = fotones reflejados por la superficie i Rsi = fotones reflejados en forma difusa por la superficie i Rdi = fotones reflejados en forma especular por la superficie i Abi = fotones absorbidos por la superficie i Pmi= fotones almacenados en la superficie i

Figura 6.12: Fases de trazado de fotones. Luego, en las superficies S2, S3 y S4 una fraccin de los fotones incidentes son absorbidos. Aquellos fotones que son reflejados desde la ltima superficie S4, son descartados. Rdi y Rsi corresponden a la cantidad de fotones reflejados en forma difusa o especular de acuerdo a los coeficientes diffuseK y specularK en la superficie i. 55

En el mtodo aplicado, en el caso de estudio, los fotones absorbidos por cada superficie Si, son los almacenados para luego ser utilizados en la fase de Photon Splatting (ver detalles en el punto 6.7).

6.7 Photon Splatting


Esta tcnica fue presentada por primera vez por Strzlinger y Bastos [19] en 1997. Permite hacer una reconstruccin de la iluminacin indirecta a partir de la informacin generada por el trazado de fotones, usando un mtodo basado en imgenes. Luego Paulin et al. [21] presento algunas mejoras al mtodo original utilizando hardware grfico. El objetivo es reconstruir la irradiancia en cada pxel del plano de vista estimando el aporte de cada fotn. Esto se puede lograr de 2 maneras: Para cada pxel, buscar los fotones que impactan dentro de cierto radio del punto visible a travs del pxel y sumar su contribucin al estimador. Para cada fotn, agregar su aporte al estimador de cada pxel cercano (a una distancia menor a cierto radio del punto visible este a travs del pxel).

Esta segunda forma es la que aplica la tcnica de Photon Splatting. Un splat tiene la forma de un disco, que representa la contribucin del fotn a la iluminacin indirecta en las cercanas del punto de impacto. Dicha contribucin se computa y acumula sobre cada pxel del plano de vista, cubierto por la proyeccin del splat, slo si dicho pxel pertenece a la misma superficie en la que impact el fotn. Esto es importante, ya que la cercana en el plano de proyeccin no implica una cercana en el espacio tridimensional. De hecho, para 2 pxeles contiguos, su distancia en la coordenada Z (normal al plano de proyeccin) puede ser considerable (mayor al radio del splat). El algoritmo consiste en iterar sobre la lista de fotones de la escena y generar por cada uno, un disco centrado en el punto donde impact el fotn y orientado segn la normal de la superficie, que luego es proyectado sobre el plano de vista. La suma de todas las proyecciones se acumular en el buffer de salida, utilizando el modo de OpenGL de fundido aditivo (additive blending). Antes de comenzar el proceso, se establece la matriz de vista y proyeccin segn los parmetros de la escena. Luego se procede a dibujar cada disco o splat ejecutando un comando OpenGL que dibuja un tringulo (GL_TRIANGLE). Un programa de fragmentos que resuelve el sombreado del tringulo muestrea la funcin de distribucin de energa del fotn a partir de una textura 2D. La forma de esta distribucin responde a una funcin patrn (o kernel function) tambin conocida como filtro, que depende de la distancia al centro del splat. Existen tres tipos de funciones patrn usadas habitualmente (ver figura 6.13):

Constante: La intensidad es constante dentro del disco, y nula fuera de este. Cnica: La intensidad decae linealmente desde el centro hasta el radio del disco. Gaussiana: La intensidad decae desde el centro hacia afuera segn la forma de una campana gaussiana.

Luego del proceso de rasterizacin del splat, se debe analizar para cada fragmento (o pxel potencial) si el aporte definido por el muestreo de la funcin patrn debe ser agregado o no al buffer de salida. Para sumarlo deben cumplirse dos condiciones:

56

r r Las normales n x y n f en los puntos X y F respectivamente, deben ser similares Esta similitud se define en trminos un producto escalar entre ambos vectores (ver figura 6.14). r r n x n f > umbral Donde 0 < umbral < 1. Esto evita que en zonas como esquinas, el fotn aporte iluminacin a una superficie cercana, pero que est orientada en una direccin muy diferente.

Los identificadores de superficie en los pxeles X y F deben ser coincidentes. Estos identificadores son valores enteros asignados a todos los tringulos de cada objeto de la escena (un objeto puede estar compuesto por varios tringulos).

Figura 6.13: Funciones patrn.

Figura 6.14: Condiciones de aceptacin/rechazo de fragmentos del splat.

57

En el ejemplo de la figura 6.15 se ilustran diferentes casos. Dado el punto F correspondiente al punto de impacto del fotn, analizando el punto X1 (asociado al pxel r r X1) se ve que las normales n x1 y n f son similares y sus identificadores de superficie tambin ya que ambos puntos pertenecen al mismo objeto, por lo tanto el aporte del r pxel X1 es agregado al buffer de salida. Para el punto X2, las normales n x 2 y r n f difieren considerablemente, por lo tanto, se descarta el aporte del pxel X2del splat. Por ltimo para el punto X2, las normales son similares pero difieren en los identificadores de superficies por ende su aporte tampoco es tenido en cuenta.

Figura 6.15: Distribucin de aporte de un fotn sobre los pxeles del plano de vista. La calidad de la solucin obtenida mediante el mtodo de Photon Splatting, es proporcional al nmero de fotones utilizados en el proceso. A mayor cantidad de splats sumados, ms suave (con menor ruido) es la iluminacin de la imagen obtenida. A su vez, un radio de splat ms grande tambin contribuye a reducir el ruido, pero elimina detalles locales de la iluminacin, ya que cada splat afecta un rea demasiado grande. En la figura 6.16, se ilustran 4 casos en donde se aplica el mtodo sobre una escena conformada por una caja y una fuente de luz direccional ubicada en el plano superior apuntando hacia abajo. En cada caso se utiliz una cantidad diferente de fotones. La figura 6.16a exhibe una calidad insuficiente, mientras que la figura 6.16d logra una calidad aceptable con un nivel de ruido casi imperceptible. Adems, la calidad depende del tipo de funcin patrn que se utiliza. El filtro gaussiano generalmente genera mejores resultados. La imagen resultante del proceso de splatting se denomina textura de irradiancia y sirve de entrada a la fase de rendering. Provee el valor de la irradiancia sobre los puntos de las superficies vistos desde el ojo del observador (por lo tanto es dependiente del punto de vista de la escena).

58

Figura 6.16: Photon Splatting con una funcin patrn constante (radio del splat=1,5 unidades, las paredes de la escena miden 10x10 unidades).

6.8 Motor de Rendering basado en Photon Mapping


Sobre la base del marco de trabajo presentado en 6.5 se dise un motor de rendering capaz de sintetizar una vista de una escena 3D a partir de dos archivos de entrada que contienen la descripcin de la escena. El motor se compone de 3 clases principales:

SceneLoader: carga y conversin a streams de los datos de entrada y generacin de estructura de aceleracin de trazado. PhotonMapper: Resuelve el trazado de fotones.

59

RayTracer: integra los resultados generados por la clase PhotonMapper con el trazado de rayos desde el ojo del observador para sintetizar la imagen de salida.

En la figura 6.17 se detalla la relacin entre estas clases y el flujo de datos entre ellas.

Figura 6.17: Arquitectura del motor de Rendering.

6.8.1 La clase SceneLoader


Se ocupa de cargar en memoria la informacin de la escena desde archivos, construir la estructura de aceleracin para el trazado de rayos o fotones (detallada en 6.6.1) y convertir esos datos a streams. La informacin de la geometra de la escena, es leda desde un archivo en formato 3DS. Este formato es un estndar para el intercambio de modelos 3D que naci como parte del software de edicin 3D Studio. Adems carga los parmetros que describen la fuente de luz, el punto de vista, las propiedades de los materiales y las caractersticas de la imagen a sintetizar, desde un archivo de texto plano denominado param.ini. La clase implementa un singleton que provee los streams de entrada requeridos por las clases RayTracer y PhotonMapper.

6.8.2 La clase PhotonMapper


Esta clase se encarga de trazar los fotones emitidos por la fuente de luz a travs de la escena. El proceso se realiza por medio de cuatro kernels (ver figura 6.18). Primero, el kernel Photons Generator, muestrea el espacio de emisin de fotones de la fuente de luz mediante la generacin de pares de coordenadas polares aleatorias dentro de los lmites del cono de luz (ver figura 6.2) definido para la escena. Este kernel 60

genera como salida los streams que representan origen, direccin, estado y color de los fotones. El proceso de muestreo requiere la generacin de nmeros al azar desde el programa Cg con el que se implementa el kernel. Debido a que en la plataforma de software utilizada, la instruccin Cg para generar nmeros aleatorios no est implementada, fue necesario generar dichas secuencias de nmeros en la CPU y cargarlas en texturas para ser utilizadas por el kernel.
Parmetros de la fuente de luz Streams de geometra 3D + estructura. BVH

Parmetros de la vista

Streams 1. Fotones (origen, direccin y estado) 2. Fotones (datos de interseccin) 3. Fotones reflejados (origen y direccin), son la entrada de una nueva fase de trazado. 4. Fotones absorbidos(origen, direccin y datos de interseccin) 5. Splats (posicin, id de objeto, color y normal)

Photons Generator

Tracer 4 2 Photons Reflector 3 Photons Projector

PhotonMapper

5 Datos de los Splats

Figura 6.18: Diseo interno de la clases PhotonMapper (flujo de datos entre los kernels) El proceso contina con una fase de trazado derivada a una instancia de la clase Tracer (detallada en el punto 6.6.2). Los fotones trazados pasan luego al kernel Photons Reflector, que se encarga de simular la interaccin con las superficies, determinando cuales deben ser absorbidos, reflejados de forma difusa o especular. Los fotones reflejados sirven de entrada para una nueva etapa de trazado. Este proceso se repite hasta completar un nmero mximo de fases de trazado definido en el archivo param.ini. Aquellos fotones que son reflejados luego de la ltima fase trazado junto con aquellos que escapan fuera de los lmites de la escena, son descartados. Al concluir las N fases de trazado, se tiene un conjunto de datos que especifica los fotones absorbidos por las superficies (incluyendo el color que es modificado de acuerdo al color de las superficies en las que impacto el fotn). Para finalizar, el kernel Photons Projector traduce los fotones absorbidos en una lista de atributos que especifican la forma y ubicacin de los splats en el sistema de coordenadas de la escena, que servirn de entrada a la fase de Photon Splatting. Concretamente: Las coordenadas X, Y, Z de vrtices del triangulo que representa al splat. Las coordenadas X, Y, Z de la normal del splat. 61

El identificador de la superficie impactada.

6.8.3 La clase Raytracer


Se encarga de trazar los rayos desde el ojo del observador, realizar el proceso de Photon Splatting usando los datos generados por la clase PhotonMapper, para luego sintetizar la imagen final. En la figura 6.19 se observan los kernels involucrados en el proceso.
Parmetros del punto de vista Datos de los Splats

Raytracer

Eye Rays Generator 2 1 Tracer 2

Surface-Data Generator

9 9 Shader (primarios) 4 10

Proceso de Photon Splatting

8 2 Shadows Generator 5 3

Specular Reflections Generator

Clase Tracer 7

Integrator

Clase Tracer Streams

Shader (secund.)

11

Imagen Rayos primarios (origen y direccin). sintetizada Rayos primarios (datos de intersecciones). Rayos de sombra (origen y direccin). Rayos de sombra (datos de intersecciones). Rayos secundarios por inter-reflexiones especulares (origen y direccin). Rayos secundarios por inter-reflexiones especulares (datos de interseccin). Colores en puntos de impacto de rayos secundarios. Colores en puntos de impacto de rayos primarios. Normales e identificadores de superficies en los puntos de impacto de los rayos primarios. 10. Irradiancia en puntos de impacto de los rayos primarios. 11. Pxeles de la imagen sintetizada. 1. 2. 3. 4. 5. 6. 7. 8. 9.

Figura 6.19: Diseo interno de la clase RayTracer (flujo de datos entre sus kernels).

62

Primero, el kernel Eye Ray Generator muestrea los pxeles sobre el plano de proyeccin y genera los rayos primarios, con su origen en el ojo del observador. Una instancia de la clase Tracer traza los rayos primarios y determina los puntos de interseccin con las superficies. A partir de los resultados del trazado, el kernel Surface-Data Generator determina los atributos de las superficies impactadas por cada rayo (normal e identificador de superficie). El kernel Specular Reflections Generador, genera los rayos secundarios que corresponden a las inter-reflexiones especulares en los puntos impactados por los rayos primarios. El kernel Shadows Generator genera los rayos de sombra que determinarn la visibilidad de la fuente de luz desde los puntos de impacto de los rayos primarios. Tanto los rayos de sombra como los rayos secundarios, son trazados utilizando los servicios de una instancia de la clase Tracer. El kernel Shader calcula el sombreado local usando el modelo de Phong incorporando la irradiancia computada en la fase de Photon Splatting y la informacin capturada por los rayos de sombra para determinar la intensidad de iluminacin directa que llega al punto. Para finalizar, el kernel Integrator, agrega el aporte de iluminacin por interreflexin especular (color capturado por los rayos secundarios) a la imagen generada por el kernel Shader.

63

Captulo 7 - Evaluacin de la implementacin


En este captulo se presentan una serie de mediciones realizadas sobre la aplicacin implementada en el caso de estudio definido en el captulo anterior, con el fin de evaluar el tiempo requerido para sintetizar una imagen de una escena de prueba, bajo diferentes parmetros. Adems se describe la plataforma de hardware y software utilizada. Por ltimo se hace un anlisis cualitativo de las imgenes generadas.

7.1 Entorno de hardware y software


La plataforma utilizada para la implementacin posee las siguientes caractersticas: Software: Sistema operativo: Microsoft Windows XP SP2. Lenguaje de programacin: Microsoft Visual C++ 7.0. OpenGL 2.0. y NVIDIA Cg Toolkit 1.5. Controlador de video NVIDIA versin 91.45. Hardware: CPU: AMD Athlon 64 3000+ (1.8 GHz). GPU: MSI NVIDIA GeForce 6600 GTS 128 MB DDR. RAM: 1024 MBytes DDR400 MHz.

7.2 Mediciones del desempeo


Se dise un modelo de una caja de Cornell (Cornell Box) para evaluar el funcionamiento de la implementacin. En la figura 7.1 se observan los ngulos que definen al cono de emisin de la fuente de luz. El modelo est delimitado por las paredes que forman un cubo de 10x10x10 unidades, excepto la pared cercana al ojo del observador que fue removida, por lo tanto, los fotones emitidos hacia dicha superficie saldrn fuera de los lmites de la escena y por lo tanto sers descartados. Todas las superficies del modelo poseen un coeficiente de reflexin difusa de 0,2 y un coeficiente de reflexin especular de 0,1. Por lo tanto, si 100 fotones intersecan una de estas superficies, el 70% ser absorbido y el 30% restante es reflejado, parte en forma especular (10%) y el resto en forma difusa (20%). Se estableci un mximo de 4 fases, para el proceso de trazado de fotones (por lo tanto un fotn puede ser reflejado como mximo en 3 veces). Adems, para todas las superficies se defini, un coeficiente de inter-reflexin especular perfecta con valor nulo, por lo tanto no se computaron rayos secundarios en la etapa de Ray Tracing. Bajo estas restricciones se evaluaron las 27 combinaciones de los siguientes parmetros:

Resolucin de imagen de salida: 128x128, 256x256 y 512x512 pxeles. Radio del splat: 0,5; 1,0 y 1,5 unidades. Nmero de fotones generados: 16384, 65535 y 262144.
64

Figura 7.1: Modelo Cornell Box utilizado en las mediciones. Estos 3 parmetros fueron seleccionados ya que afectan en forma ms directa la calidad de la solucin obtenida. En el caso de los parmetros de resolucin de imagen y la cantidad de fotones un incremento suele producir una mejor solucin o estimacin de la iluminacin de la escena.

Tabla 1. Medicin de tiempos de generacin de un cuadro.


Tiempo de generacin (seg.) segn la resolucin de imagen (pxeles) Radio del splat Fotones generados 16384 0,5 65535 262144 16384 1,0 65535 262144 16384 1,5 65535 262144 128 x 128 4,87 5,87 10,67 5,47 5,89 10,69 4,86 6,00 10,7 256 x 256 5,09 6,56 11,43 5,11 6,25 11,22 5,19 6,53 12,34 512 x 512 6,17 7,37 12,33 6,78 8,22 15,89 6,65 9,48 20,43 Tiempo de fase de splatting (seg.) segn resolucin de imagen (pxeles) 128 x 128 0,20 0,50 1,48 0,22 0,51 1,51 0,23 0,61 1,48 256 x 256 0,22 0,52 1,51 0,25 0,64 1,72 0,33 0,95 2,84 512 x 512 0,33 0,73 1,92 0,53 1,59 5,23 0,84 2,84 10,01

65

Sin embargo, en el caso del radio de splat, un valor muy grande genera una solucin incorrecta por afectar la iluminacin de puntos demasiado distantes al punto de impacto del fotn. Es importante mencionar que debido a limitaciones del controlador de video y el kit de desarrollo de software Cg utilizado, no fue posible utilizar en las mediciones, streams de salida con resoluciones de textura mayores a 512x512 pxeles. De ah surge el valor mximo de resolucin de la imagen de salida y el nmero de fotones utilizados en las mediciones. Cabe aclarar que no todos los fotones generados se traducen en un splat, dado que algunos se reflejan fuera de la escena y otros se descartan luego de ser reflejados pasado el nmero mximo de reflexiones de los fotones. Empricamente, en esta escena, la cantidad de splats result ser equivalente a 75 3% de los fotones generados. Por lo tanto si se generan 262144 fotones, se producen aproximadamente 196000 splats. Este valor es aproximado, ya que incluso en corridas sucesivas bajo parmetros idnticos, el nmero de splats es variable debido a que los eventos que determinan el camino recorrido por un fotn dependen de variables aleatorias. En la tabla 1 se presentan los tiempos totales de generacin de un cuadro (sin incluir los tiempos de preprocesamiento iniciales requeridos para leer los archivos de la escena y generar la estructura BVH).

Tabla 2. Incremento de tiempo de generacin vs. Incremento en la cantidad de fotones generados.


Factor de incremento del tiempo de generacin (seg.) segn la resol. de imagen (pxeles) Radio del splat Factor de incremento en la cantidad de fotones generados 1 (16384 fotones) 0,5 4 veces 16 veces 1 (16384 fotones) 1,0 4 veces 16 veces 1 (16384 fotones) 1,5 4 veces 16 veces 128 x 128 1,00 1,21 2,19 1,00 1,10 1,95 1,00 1,23 2,20 256 x 256 1,00 1,29 2,25 1,00 1,28 2,20 1,00 1,26 2,38 512 x 512 1,00 1,19 2,00 1,00 1,40 2,34 1,00 1,43 3,07

Definicin del factor

t1/t1 t2/t1 t3/t1 t1/t1 t2/t1 t3/t1 t1/t1 t2/t1 t3/t1

* t1 = tiempo de generacin para 16384 fotones * t2 = tiempo de generacin para 65535 fotones * t3 = tiempo de generacin para 262144 fotones

66

En la tabla 2, se analiza el incremento en el tiempo de generacin de un cuadro al aumentar la cantidad de fotones. Se puede observar en todos los casos que el tiempo crece sublinealmente respecto de la cantidad de fotones. En la tabla 3, se comparan los tiempos de generacin en relacin al incremento en la resolucin de la imagen de salida. Nuevamente se observa que el tiempo crece sublinealmente respecto de la resolucin. En el peor caso (correspondiente a un radio de splat = 1,5; fotones generados = 262144 y una resolucin de 512x512 pxeles) el tiempo de generacin prcticamente se duplic, para una imagen sintetizada con cuatros veces ms de pixeles.

Tabla 3. Incremento de tiempo de generacin vs. Incremento en la resolucin de imagen.


Factor de incremento del tiempo de generacin (seg.) segn incremento en la resol. de imagen (pxeles) Fotones generados 16384 0,5 65535 262144 16384 1,0 65535 262144 16384 1,5 65535 262144 Definicin del factor

Radio del splat

1 (128 x 128) 1,00 1,00 1,00 1,00 1,00 1,00 1,00 1,00 1,00

2 veces 1,05 1,12 1,07 0,93 1,09 1,05 1,07 1,09 1,15

4 veces 1,27 1,26 1,16 1,12 1,58 1,49 1,37 1,58 1,91

t1/t1

t1/t2

t1/t3

* t1 = tiempo de generacin para una imagen de 128x128 pxeles * t2 = tiempo de generacin para una imagen de 256x256 pxeles * t3 = tiempo de generacin para una imagen de 512x512 pxeles

En la tabla 4, se analiza el incremento en el tiempo de rendering respecto del incremento en el radio del splat. Aqu se observa una variacin mnima de tiempo (menor a un 15%) para la resolucin de 256x256 respecto del caso patrn (128x128 pxeles), esto se debe a que los splats en estos casos cubren muy pocos pxeles, entonces el incremento en el radio no hace variar sustancialmente la cantidad de fragmentos que deben ser computados en la fase de Photon Splatting. Luego, igual que en las tablas 2 y

67

3, se observa que el tiempo de generacin de un cuadro crece sublinealmente respecto del radio del splat.

Tabla 4. Incremento de tiempo de generacin vs. Incremento en la resolucin de imagen.


Factor de incremento del tiempo de generacin (seg.) segn la resol. de imagen (pxeles) Fotones generados Radio del splat 1 (0.5 unidades) 16384 2 veces 3 veces 1 (0.5 unidades) 65535 2 veces 3 veces 1 (0.5 unidades) 262144 2 veces 3 veces 128 x 128 1,00 1,12 1,00 1,00 1,02 1,02 1,00 1,00 1,00 256 x 256 1,00 1,00 1,02 1,00 1,00 1,00 1,00 0,98 1,08 512 x 512 1,00 1,10 1,08 1,00 1,29 1,29 1,00 1,29 1,66

Definicin del factor

t1/t1 t2/t1 t3/t1 t1/t1 t2/t1 t3/t1 t1/t1 t2/t1 t3/t1

* t1 = tiempo de generacin para un radio de splat de 0,5 unidades * t2 = tiempo de generacin para un radio de splat de 1,0 unidades * t3 = tiempo de generacin para un radio de splat de 1,5 unidades

Tabla 5. Incidencia del trazado de fotones y fase de Photon Splatting (radio del splat = 1,25).
Fotones generados 1024 4096 16384 65535 262144 Tiempo total de generacin de un cuadro (seg.) 6.81 6.89 7.42 9.42 16.92 % de tiempo consumido por la fase de trazado de fotones 40,82 40,07 40,16 39,28 42,90 % del tiempo consumido por la fase de Photon Splatting 2,90 3,92 8,33 17,72 32,56

68

En la tabla 5 se puede observar que las de fases de trazado de fotones y de Photon Splatting tienen una incidencia importante en el proceso de generacin. Especialmente para el caso correspondiente a 262144 fotones generados (ver figura 7.2) donde la calidad de la imagen obtenida comienza a ser aceptable y ambas fases consumen casi del 75% del tiempo.

Figura 7.2: Imagen generada con 512x512 pxeles, radio del splat =1,25 y 262144 fotones generados.

Tabla 6. Porcentaje del tiempo utilizado por la GPU.


Fotones generados 1024 4096 16384 65535 262144 Tiempo total de generacin de un cuadro (seg.) 5,56 5,62 6,48 9,59 20,32 % de tiempo de utilizacin de la GPU 29,94 30,70 36,72 48,42 62,89

69

En la tabla 6 se puede observar cul es el porcentaje del tiempo utilizado por la GPU durante el proceso de generacin de la imagen en funcin de la cantidad de fotones generados. Estas mediciones fueron realizadas sobre la misma escena de las pruebas anteriores, utilizando una resolucin de imagen de salida de 512x512 pxeles y un radio de splat de 1,5. Se podra decir que el tiempo de uso de la GPU crece en proporcin al tamao del problema a resolver ya que es dependiente de las dimensiones de los streams a procesar. En cambio, el rol de la CPU est mas relacionado a tareas de gestin de los recursos como: la transferencia de datos entre la memoria principal y la GPU, la compilacin de los programas Cg, la gestin de los buffers, la ejecucin de la API OpenGL y la administracin de los recursos del hardware grfico. Al incrementar la cantidad de fotones el tiempo de uso de la GPU adquiere mayor protagonismo. Es por esto que casos de mayor complejidad (ms resolucin de la imagen de salida, ms cantidad de fotones, o mayor radio de splat) se resuelven de modo mas eficiente al consumir proporcionalmente menos tiempo en preparacin y mas tiempo en la ejecucin de los kernels en el procesador de fragmentos.

7.3 Imgenes
A continuacin se presentan diversas imgenes generadas con la aplicacin implementada para evaluar el aspecto cualitativo de los resultados obtenidos. En la figura 7.3 se presenta dos ejemplos que incorporan materiales reflectivos. En 7.3a se puede notar el efecto de enfoque de fotones producido por la superficie espejada sobre el piso de la escena. En 7.3b se puede observar el efecto de sombra producido sobre el rincn trasero derecho, que es la suma las sombras duras generadas en la fase de Ray Tracing (por rayos de sombras) y las sombras suaves producto de la iluminacin indirecta.

(a)

(b)

Figura 7.3: Modelo Cornell Box con objetos reflectivos.

70

En la figura 7.4 se presentan imgenes de la misma escena utiliza en el punto 7.2 con sus componentes de iluminacin separadas (7.4a y 7.4b). En la figura 7.4c se observan los puntos sobre las superficies en donde los fotones fueron absorbidos.

Figura 7.4: (a) Componentes de iluminacin ambiente + directa + sombras. (b) Componente de iluminacin indirecta. (c) Distribucin de los fotones. (d) Solucin completa. En la figura 7.5a se puede apreciar el modo en que es afectada la iluminacin en el piso de caja debido a los 2 tabiques verticales. Dichos tabiques tienen asociados materiales puramente difusos que desvan gran parte de los fotones de la fuente hacia el piso, excepto en la separacin central en donde los fotones pasan al otro lado. En la figura 7.5b se observa un defecto en la iluminacin indirecta propio de la tcnica de Photon Mapping. En el borde inferior de la superficie rectangular ubicada en

71

el centro, algunos splats atraviesan la superficie filtrando luz por debajo e iluminando una zona del piso que debera estar oscura.

(a)

(b)

Figura 7.5: Efectos de la iluminacin indirecta. La figura 7.6 corresponde a una escena que incluye una esfera espejada con un ndice de reflectividad (reflectK) de 0,3. Las tres imgenes corresponden a tres orientaciones diferentes de la fuente de luz (sealada con el vector en color verde). En esta figura se observa claramente el efecto conocido como color bleeding en donde los fotones capturan el color de las superficies sobre las que se reflejan. En la figura 7.6a es notorio el cambio de coloracin de la escena hacia los rojos debido a que la mayora de los fotones impactan en la pared izquierda. Por el contrario en la figura 7.6c la escena se tie de tonos azules.

(a)

(b)

(c)

Figura 7.6: Escena generada con 262144 fotones y un radio de splat = 1,0. (a) Fuente de luz orientada 45 a izquierda de la normal. (b) Fuente de luz orientada hacia abajo (c) Fuente de luz o orientada 45 a derecha de la normal

72

En la figura 7.7 se pueden comparar los resultados obtenidos al utilizar una funcin patrn gaussiana o una funcin constante, utilizando 65536 fotones.

(a)

(b)

Figura 7.7: Comparacin de tipos de funciones patrn. (a) Imagen generada con un filtro gaussiano. (b) Imagen generada con un filtro constante. En la figura 7.8, se observan dos imgenes sintetizadas a partir de la misma escena. En 7.8a se desactiv el cmputo de rayos secundarios, por lo tanto el material reflectivo se observa opaco. En 7.8b se ve el cmputo de la solucin incluyendo rayos secundarios.

(a)

(b)

Figura 7.8: Componente de inter-reflexin especular. (a) Imagen sin computar rayos secundarios. (b) Imagen con rayos secundarios.

73

Captulo 8 - Conclusiones
En este trabajo de tesis se presentaron diferentes tcnicas de iluminacin global para la sntesis de imgenes a partir de una escena 3D. Se defini un caso de estudio en base al mtodo de Photon Mapping y el uso de los recursos de cmputo de una GPU. Con la aplicacin desarrollada, se han logrado tiempos de rendering aptos para implementar aplicaciones interactivas. Es esperable que al ejecutar la misma aplicacin, sobre hardware grfico ms moderno, sea capaz de sintetizar imgenes en tiempos aptos para aplicaciones de tiempo real, o que tambin sea capaz de obtener soluciones ms precisas (mayor resolucin de imagen o mayor cantidad de fotones) en igual tiempo de cmputo que en la plataforma utilizada en este proyecto. A partir de las mediciones realizadas en el punto 7.2 se puede concluir que la aplicacin implementada resulta escalable respecto de los tres parmetros evaluados. La rpida evolucin tecnolgica de las GPUs, impone cambios en la forma de programar aplicaciones grficas, que muchas veces obligan a redisearlas en forma completa para aprovechar al mximo el potencial de las nuevas generaciones. Al momento de concluir este proyecto (segundo semestre de 2007), NVIDIA present una nueva arquitectura de cmputo denominada CUDA (Compute Unified Device Architecture) que permitira reescribir la implementacin aqu presentada de manera mucho mas sencilla. Est nueva arquitectura permite aprovechar el poder de cmputo de la GPU para aplicaciones de propsito general mediante mecanismos mas simples. Es posible escribir los programas (los kernels del modelo de Stream Programming) directamente en lenguaje C estndar sin necesidad de utilizar la API grfica como OpenGL o DirectX, evitando as definir explcitamente mecanismos de traduccin de las estructuras de datos en texturas y las dificultades que se presentan a la hora de depurar el cdigo.

8.1 Trabajos Futuros


Respecto de las lneas de trabajo a seguir, sera recomendable comenzar por optimizar la fase de Photon Splatting. Ya que de las mediciones presentadas en la tabla 5, surge que dicha etapa tiene una incidencia importante en el costo total de cmputo. A tal fin, un camino sera evaluar el uso de otras primitivas geomtricas para proyectar los splats sobre la textura de irradiancia. Concretamente, se plantea analizar si el uso de primitivas como puntos (GL_POINT) o rectngulos (GL_RECTANGLE) producen un ahorro en la cantidad de fragmentos evaluados en el proceso. Esto se sustenta en el hecho de que la forma circular de las funciones patrn se adapta de manera mas ajustada al contorno de la primitiva, generando una menor rea donde la funcin filtro es nula (los puntos ubicados a una distancia mayor al radio del filtro). Otro punto a explorar sera la posibilidad de implementar los preprocesos que generan la estructura de aceleracin BVH en la GPU. Dado que en este proyecto se trabaj sobre escenas estticas, el costo computacional de esta etapa en la CPU no fue relevante. Pero ante la necesidad de disear un motor mas general, en donde las escenas se modifican a lo largo del tiempo, sera necesario reconstruir la estructura mltiples veces y all es donde la incidencia de esta etapa cobrara mayor relevancia. Respecto de la API 3D en la que se basa la aplicacin desarrollada (en este caso fue OpenGL), resultara importante analizar las ventajas de utilizar la API de DirectX, para mejorar el desempeo. Especficamente, existe una funcionalidad de la GPU que podra resultar til para optimizar el proceso de Photon Splatting, denominada instanciacin 74

de geometra (geometry instancing). Esta funcionalidad, que no est disponible actualmente en la API de OpenGL, permite clonar elementos geomtricos ya cargados a la memoria de la GPU. Para este proyecto podra ser utilizado para generar las mltiples instancias de los splats, en lugar de hacerlo desde la aplicacin corriendo en la CPU. Otro aspecto a mejorar, est relacionado al aprovechamiento de los tiempos de cmputo ociosos de la CPU y la GPU respectivamente. Sera conveniente estudiar si es posible aprovechar el tiempo de cmputo de la CPU mientras la GPU est computando kernels. Quizs esto se pueda lograr mediante el uso de mltiples hilos (multi-threads) de ejecucin en la aplicacin C++ que se corran en forma asincrnica respecto de los procesos de la GPU. Un prximo paso a desarrollar a partir de este proyecto sera el diseo de un motor de Photon Mapping de tiempo real capaz de generar de secuencias de imgenes que conformen una animacin. En ese caso habra que incorporar las ideas presentadas por Jozwowski [27], que plantea formas de reutilizar cmputos entre cuadros sucesivos aprovechando similitudes en las condiciones de iluminacin. Concretamente platea que los fotones trazados pueden ser almacenados y reutilizados en cuadros sucesivos y asignndoles un atributo que mide su edad, conservarlos hasta que el cambio en las condiciones de iluminacin justifique reemitirlos. De esta manera se reduce la cantidad total de fotones a trazar en cada cuadro, haciendo factible la generacin de cuadros en fracciones de segundos. Otro tema central a indagar, es la posibilidad de realizar el proceso completo de Photon Splatting en la GPU. Como se mencion en el captulo 6 debido a la imposibilidad de direccionar aleatoriamente la memoria de la GPU para escritura desde un programa de fragmentos, es necesario transferir los datos de los splats a la CPU para luego proyectarlos sobre el plano de vista. Es esperable que futuras generaciones de GPUs provean mecanismos mas generales de direccionamiento y as evitar el costo innecesario de transferencia de datos entre la CPU y la GPU, el cual resulto ser particularmente alto debido al bajo ancho de banda de bus de datos AGP utilizado en este proyecto. Desde el punto de vista de la plataforma, existen actualmente tecnologas que permiten instalar multiples GPUs en una misma PC , mediante la tecnologa de NVIDIA denominada SLI (Scalable Link Interface), sera interesante analizar que modificaciones seran necesarias realizar sobre la implementacin para aprovechar la capacidad de este tipo de arquitecturas. Respecto del mtodo de Photon Mapping aqu implementado existen muchos aspectos a ser mejorados a fin de implementar tipos de efectos de iluminacin ms complejos como los de refraccin, caustics o el cmputo de la iluminacin indirecta producto de inter-reflexiones en superficies del tipo glossy donde la direccin en la que impacta el fotn debe ser tenida en cuenta, a diferencia de las superficies difusas donde la radiancia reflejada se distribuye en forma uniforme en todas las direcciones.

75

Publicaciones
Federico Marino y Horacio Abbate, Implementacin de Photon Mapping en hardware grfico programable. En AST (Simposio Argentino de Informtica), como parte de las 36 Jornadas Argentinas de Informtica. Agosto de 2007. Federico Marino y Horacio Abbate, Stream Programming Framework for Global Illumination Techniques Using a GPU. En CACIC 2007 (Congreso Argentino de Ciencias de la Computacin). Octubre de 2007.

76

Cdigo Fuente

A continuacin se incluye el cdigo fuente de los kernels principales utilizados en la implementacin, escritos en lenguaje Cg.

Ray.cg
#ifndef RAY_CG #define RAY_CG struct ray { float3 o; float3 d; }; float3 evaluate(in ray r, in float module) { return r.o + module*r.d; } #endif

Photon.cg
#ifndef PHOTON_CG #define PHOTON_CG struct photon { float3 o; float3 d; float power; }; #endif

Common.cg
#ifndef COMMON_CG #define COMMON_CG #define #define #define #define #define STATE_ABSORBED (-3) STATE_DONT_TRACE (-2) STATE_TRAV_SETUP (-1) STATE_SHADE (3) STATE_BACKGROUND (5)

#define INF (999999999) const float infinity=9999999.9f; int index3dto1d(in float3 voxel_idx_3d) { int r=(floor(voxel_idx_3d.z)*gridCount*gridCount)+ (floor(voxel_idx_3d.y)*gridCount)+ floor(voxel_idx_3d.x); return r; } int3 index1d3d(in int voxel_idx_1d) {

77

int3 result; result.z = voxel_idx_1d/(gridCount*gridCount); voxel_idx_1d-=result.z * gridCount*gridCount; result.y = voxel_idx_1d/gridCount; voxel_idx_1d-=result.y*gridCount; result.x = voxel_idx_1d; return result; } float2 getAddress( in int idx, in int width) { return float2(0.25+fmod(float(idx),float(width)), idx/width); } void copyState(in float2 idx : TEXCOORD0, uniform samplerRECT states,out float4 state : COLOR0) { state = texRECT(states,idx); } #endif

Random.cg
uniform samplerRECT random; uniform float randomTex_width; uniform float global_rnd_seed;

float2 randomgen(float2 seed){ float2 OUT=texRECT(random, seed*randomTex_width).xy; return OUT; }

Generator.cg
#include "photon.cg" #include "common.cg" #include "random.cg" // frustum atributes uniform int frustumSize; uniform float3 frustumOrigin; uniform float frustumLeft,frustumRight,frustumTop, frustumBottom,frustumNear; uniform float maxAngle; uniform float3 frustumUpVec,frustumNormalVec; //up and normal vector void generateEyeRay(in float2 photonIndex:TEXCOORD0, out float3 origin:COLOR0, out float3 direction:COLOR1, out float4 state:COLOR2) { const float scale=10; float3 frustumRightVec = cross(frustumUpVec,frustumNormalVec); float2 uv0 = float2(scale*frustumLeft,scale*frustumBottom); float2 uv1 = float2(scale*frustumRight,scale*frustumTop); float near = scale*frustumNear; //Vectors along the U and V axis of the cone, float3 a = (uv1.x - uv0.x)*frustumRightVec;

78

float3 b = (uv1.y - uv0.y)*frustumUpVec; //Vector from the frustum to the lower left point float3 c = frustumOrigin+uv0.x*frustumRightVec + uv0.y*frustumUpVec + near*frustumNormalVec; float2 hituv = float2(photonIndex.x/frustumSize, photonIndex.y/frustumSize); float3 hit = hituv.x * a + hituv.y * b + c; origin = frustumOrigin; // Photon origin direction = normalize(hit - frustumOrigin); // Photon direction // Photon state.x = state.y = state.z = state.w = } float3 generateRandomDirection(float3 normal,float3 u, float2 random){ float3 OUT; float3 v=cross(normal,u); float alfa=acos(sqrt(random.x))*(maxAngle/90.0f); float beta=random.y*radians(360.0); OUT=(normal*cos(alfa))+(u*sin(alfa)*sin(beta))+(v*sin(alfa)*cos(beta)); return OUT; } void generatePhoton(in float2 photonIndex:TEXCOORD0, out float3 origin:COLOR0, out float3 direction:COLOR1, out float4 state:COLOR2, out float3 color:COLOR3) { origin = frustumOrigin; // Photon origin float2 seed=float2(photonIndex.x/frustumSize,photonIndex.y/frustumSize); direction = normalize(generateRandomDirection(frustumNormalVec, frustumUpVec,randomgen(seed))); // Photon state vector state.x = STATE_TRAV_SETUP; //state state.y = infinity; //last isect value state.z = 0; //current voxel state.w = 0; //current triangle color=float3(1,1,1); } state vector STATE_TRAV_SETUP; infinity; 0; 0;

//state //last isect value //current voxel //current triangle

Bvh.cg
#define #define #define #define #define #define STATE_ABSORBED (-3) STATE_DONT_TRACE (-2) STATE_TRAV_SETUP (-1) STATE_TRAV (0) STATE_SHADE (3) STATE_BACKGROUND (5)

const float infinity=9999999.9f ;

float4 ReadIndex(samplerRECT data, float index, float width) {

79

float2 index2D=float2(0.25+fmod(float(index),float(width)),index/width); return texRECT(data,index2D); } // Used for ray/triangle intersection testing. float4 Intersects(float3 a, float3 b, float3 c, float3 o, float3 d,float minT, float vertexIndex, float4 lasthit) { float3 e1 = b - a; float3 e2 = c - a; float3 p = cross(d, e2); float det = dot(p, e1); bool isHit = det > 0.00001f; //the triangle is nearly edge-on float invdet = 1.0f / det; float3 tvec = o - a; float u = dot(p, tvec) * invdet; float3 q = cross(tvec, e1); float v = dot(q, d) * invdet; float t = dot(q, e2) * invdet; isHit = (u >= 0.0f) && (v >= 0.0f) && (u + v <= 1.0f) && t >= 0.0f)&& (t < lasthit.z) && (t > minT); float4 retVal; if (isHit) retVal= float4(u, v, t, vertexIndex); else retVal=lasthit; return retVal; } // Checks for intersection between a ray and a box. bool BoxIntersects(float3 box_min, float3 box_max, float3 o,float3 d, float4 bestHit, float tMin) { float3 tmin, tmax; tmin = (box_min - o) / d; tmax = (box_max - o) / d; float3 real_min = min(tmin, tmax); float3 real_max = max(tmin, tmax); float minmax = min(min(real_max.x, real_max.y), real_max.z); float maxmin = max(max(real_min.x, real_min.y), real_min.z); bool res = minmax >= maxmin; return res && bestHit.z >= maxmin && tMin < minmax; } //this is the type for the output of the main program struct fragment_out { half4 bestHit : COLOR0; //best hit so far half4 renderState : COLOR1; //records how far we are }; // the main ray/scene intersection/traversal program (kernel). // returns the best hit so far and the index to the next element fragment_out multipass_main ( float2 streampos : TEXCOORD0,//texcoord to ray and best hit uniform samplerRECT bvhArray, uniform samplerRECT v0, uniform samplerRECT v1, uniform samplerRECT v2, uniform float vertexListTexWidth, uniform samplerRECT bboxMin, uniform samplerRECT bboxMax, uniform float bboxTexWidth, uniform samplerRECT origins, //a list of ray origins uniform samplerRECT directions, //a list of ray directions

80

uniform uniform uniform uniform uniform {

samplerRECT bestHits, //the best hits found so far samplerRECT renderStates, //records how far in the traversal float bvhArrayTexWidth, //the width of the geometry texture float maxIndex, //maximum legal index in geometry texture float looplimit //maximum number of allowed loops)

float4 renderState = texRECT(renderStates, streampos); float datapos = renderState.x; if (datapos > maxIndex) discard; //find the ray and the previously best hit float3 origin = texRECT(origins, streampos).xyz; float3 direction = texRECT(directions, streampos).xyz; float4 bestHit = texRECT(bestHits, streampos); int loopcount = looplimit; while (loopcount > 0 && renderState.x <= maxIndex) { half3 bvhData=ReadIndex(bvhArray,datapos,bvhArrayTexWidth); if (bvhData.x == 0) // current element is a bbox { half3 boxMinData=ReadIndex(bboxMin,bvhData.y,bboxTexWidth); half3 boxMaxData=ReadIndex(bboxMax,bvhData.y,bboxTexWidth); if (BoxIntersects(bboxMinData, bboxMaxData, origin, direction, bestHit, 0.0f)){ // advance to next record in BVH traversal Array renderState.x += 1; } else { // no bbox intersection use escape_code renderState.x =bvhData.z; } } else //current element is a triangle { half3 v0Data=ReadIndex(v0,bvhData.y,vertexListTexWidth); half3 v1Data=ReadIndex(v1,bvhData.y,vertexListTexWidth); half3 v2Data=ReadIndex(v2,bvhData.y,vertexListTexWidth); bestHit = Intersects(v0Data,v1Data,v2Data, origin.xyz, direction.xyz, 0.0,bvhData.y, bestHit); // advance to next record in BVH traversal Array renderState.x += 1; } datapos = renderState.x; loopcount--; } fragment_out result; result.bestHit = bestHit; result.renderState = renderState; return result; } void getStatesAndIsectData(in float2 pos : TEXCOORD0, uniform samplerRECT bestHits, uniform samplerRECT renderStates, uniform float vertexListTexWidth, out float4 outStates:COLOR0, out float4 outIsectData:COLOR1 ) { half4 renderState = texRECT(renderStates, pos); half4 bestHit = texRECT(bestHits, pos);

81

float4 states=float4(0,0,0,0); if ((renderState.x<0) || (renderState.x==(half)infinity)){ states.x=STATE_DONT_TRACE;// DON'T TRACE } else if (bestHit.w<0) { states.x=STATE_BACKGROUND; // Background states.y=infinity; } else { states.x=STATE_SHADE; // SHADE states.y=bestHit.z; } float4 isectData=float4(0,0,0,0); isectData.xy=bestHit.xy; float2 index2D=float2(0.25+fmod(float(bestHit.w), float(vertexListTexWidth)),bestHit.w/vertexListTexWidth); isectData.zw=index2D; outIsectData=isectData; outStates=states; } // is used as output by the initialization kernel. struct setup_out { half4 bestHit : COLOR0; half4 renderState : COLOR1; }; // Initialization kernel. Sets up empty intersection records and // traversal positions start at index 0. setup_out setup(in float2 tc : TEXCOORD0, uniform samplerRECT initialRenderStates) { setup_out result; half initialState = (half)texRECT(initialRenderStates, tc).x; result.bestHit = half4(0, 0, infinity, -1); //"no hit" half x=0.0; if ((initialState!=STATE_TRAV_SETUP)) x=(half)infinity; result.renderState = half4(x, 1.0f, 1.0f, 1.0f); return result; }

PhotonSplatVp.cg
struct appdata { float4 position : POSITION; float4 coord0 : TEXCOORD0; }; struct vfconn { float4 pos : POSITION; float2 coord0 : TEXCOORD0; };

82

vfconn photonSplat(appdata IN, uniform float4x4 ModelViewProjMatrix) { vfconn OUT; OUT.pos = mul(ModelViewProjMatrix, IN.position); OUT.coord0=IN.coord0; return OUT; }

PhotonSplatFp.cg
uniform uniform uniform uniform uniform uniform uniform float photonObjectId; float3 photonNormal; float3 photonIrradiance; sampler2D splat; samplerRECT irradiances; samplerRECT surfNormals; samplerRECT surfDatas;

void photonSplat(in float2 pos:TEXCOORD0, in float2 uv0:WPOS, out half4 color:COLOR0 ) { color = texRECT(irradiances, uv0.xy); float4 surfdata = texRECT(surfDatas, uv0.xy); float3 surfnormal = texRECT(surfNormals, uv0.xy).xyz; half3 splatColor; if ((surfdata.x==photonObjectId) && (dot(surfnormal,photonNormal)>0.75)){ splatColor=photonIrradiance*tex2D(splat, pos).x; } else { discard; } color=color+half4(splatColor.r,splatColor.g,splatColor.b,1); }

PhotonsReflector.cg
uniform samplerRECT uniform samplerRECT uniform samplerRECT uniform samplerRECT uniform samplerRECT // geometry data origins; directions; colors; states; isectdatas; //ray origins //ray directions

uniform samplerRECT v0; uniform samplerRECT v1; uniform samplerRECT v2; uniform samplerRECT n0; uniform samplerRECT n1; uniform samplerRECT n2; uniform samplerRECT matColors; uniform samplerRECT matAttribs;

83

uniform float bouncenum; #include "ray.cg" #include "common.cg" #include "random.cg" float3 lert(float3 a, float3 b, float3 c, float u, float v) { return a + u*(b - a) + v*(c-a); } float3 diffuseReflection(float3 normal,float3 u, float2 random){ float3 OUT; float3 v=cross(normal,u); float alfa=acos(sqrt(random.x)); float beta=random.y*radians(360.0); OUT=(normal*cos(alfa))+(u*sin(alfa)*sin(beta))+(v*sin(alfa)*cos(beta)); return } void photonsReflector(in float2 rayIndex:TEXCOORD0, out float3 outrayOrig:COLOR0, out float3 outrayDirec:COLOR1, out float4 outrayState:COLOR2, out float3 outrayColor:COLOR3) { float3 float3 float4 float3 float4 inrayOrig= texRECT(origins, rayIndex).xyz; inrayDirec= texRECT(directions, rayIndex).xyz; inrayState= texRECT(states, rayIndex).xyzw; inrayColor= texRECT(colors, rayIndex).xyz; inrayIsectData= texRECT(isectdatas, rayIndex); OUT;

outrayOrig=float3(0,0,0); outrayDirec=float3(0,0,0); outrayState=float4(0,0,0,0); outrayColor=float3(0,0,0); float2 triangleIndex = inrayIsectData.zw; float4 matattribs = texRECT(matAttribs, triangleIndex); float3 matColor = texRECT(matColors, triangleIndex).xyz; if (inrayState.x == STATE_SHADE) { float float float float float diffuseK=matattribs.x; specularK=matattribs.y; reflectK=matattribs.z; smoothing=matattribs.w; rangoRandomMax;

outrayColor=float3(inrayColor.x*(matColor.x/255.0), inrayColor.y*(matColor.y/255.0), inrayColor.z*(matColor.z/255.0)); if (bouncenum==0) rangoRandomMax=diffuseK+specularK; else rangoRandomMax=1; float event=randomgen(inrayIsectData.yx).y*rangoRandomMax; if (event<(diffuseK+specularK)){// reflexin difusa o especular

84

// Photon should float3 vertex0 = float3 vertex1 = float3 vertex2 =

be reflected texRECT(v0, triangleIndex).xyz; texRECT(v1, triangleIndex).xyz; texRECT(v2, triangleIndex).xyz;

//Fetch normal float3 normal0 = texRECT(n0, triangleIndex).xyz; float3 normal1 = texRECT(n1, triangleIndex).xyz; float3 normal2 = texRECT(n2, triangleIndex).xyz; //calculate hit point ray r; r.o = inrayOrig; r.d = inrayDirec; float3 hitpoint = evaluate(r,inrayState.y); //Calculate normal float ucoord=inrayIsectData.x; float vcoord=inrayIsectData.y; if (smoothing<1.0) { ucoord=0.5; vcoord=0.5; } float3 normal = normalize(lert(normal0, normal1, normal2,ucoord,vcoord));// surface normal float3 u=normalize(vertex0-vertex2); if (event<specularK) // Photon is speculary reflected outrayDirec=reflect(inrayDirec,normal); else // Photon is diffusely reflected outrayDirec=diffuseReflection(normal,u, randomgen(inrayIsectData.xy)); // sumo para evitar auto interseccin outrayOrig=hitpoint+normalize(outrayDirec)*0.01f; outrayState.x=STATE_TRAV_SETUP; outrayState.y=INF; } else {// Photon is absorbed outrayState=inrayState; outrayState.x=STATE_ABSORBED; } } else if (inrayState.x == STATE_BACKGROUND || inrayState.x == STATE_DONT_TRACE || inrayState.x == STATE_ABSORBED ) { outrayState=inrayState; } else { outrayState.x=-99; // error }

85

PhotonsProjector.cg
uniform uniform uniform uniform samplerRECT samplerRECT samplerRECT samplerRECT origins; directions; states; colors;

uniform samplerRECT isectdatas; uniform samplerRECT n0; uniform samplerRECT n1; uniform samplerRECT n2; uniform samplerRECT matColors; uniform samplerRECT matAttribs; uniform float3 frustumOrigin; float photonPower; uniform float hParam; uniform float iParam; uniform float splatArea; #include "ray.cg" #include "common.cg" float3 lert(float3 a, float3 b, float3 c, float u, float v) { return a + u*(b - a) + v*(c-a); } void projector(in float2 rayIndex:TEXCOORD0, out float4 data1:COLOR0, out float4 data2:COLOR1, out float4 data3:COLOR2, out float4 data4:COLOR3) { const float3 zAxis=float3(0,0,1); float4 state = texRECT(states, rayIndex).xyzw; float3 photonColor = texRECT(colors, rayIndex); data1=float4(0,0,0,-1); data2=float4(0,0,0,0); data3=float4(0,0,0,0); data4=float4(0,0,0,0); if (state.x == STATE_ABSORBED) { float4 isectdata = texRECT(isectdatas, rayIndex); float2 triangleIndex =isectdata.zw; float4 matAttrib = texRECT(matAttribs, triangleIndex); float4 matColor = texRECT(matColors, triangleIndex); // Hit Point POSITION ray r; r.o = texRECT(origins, rayIndex).xyz; r.d = texRECT(directions, rayIndex).xyz; // get a vector with "r" direction , "o" origin and state.y float3 hitPosition = evaluate(r,state.y); // Hit Point SURFACE NORMAL float3 normal0 = texRECT(n0, triangleIndex).xyz; float3 normal1 = texRECT(n1, triangleIndex).xyz; float3 normal2 = texRECT(n2, triangleIndex).xyz;

86

float3 normal = normalize(lert(normal0, normal1, normal2,isectdata.x,isectdata.y)); // Irradiance float3 irradiance=photonColor*max(dot(normal, -normalize(r.d))*(photonPower/splatArea),0); // Splat Triangle Vertex float3 u,v; if (abs(dot(normal,zAxis))<1.0) u=cross(zAxis,normal); else u=float3(1,0,0); v=normalize(cross(normal,u)); float4 vertexA; float4 vertexB; float4 vertexC; vertexA.xyz=hitPosition-hParam*(u+v); vertexB.xyz=hitPosition+iParam*u-hParam*v; vertexC.xyz=hitPosition+iParam*v-hParam*u; data1.xyz=vertexA.xyz; data2.xyz=vertexB.xyz; data3.xyz=vertexC.xyz; data4.xyz=normal; //data1.w=-1; } else { data1=float4(0,0,0,0); data2=float4(0,0,0,0); data3=float4(0,0,0,0); data4=float4(0,0,0,0); } } data1.w=matColor.w; // OBJECT ID data2.w=irradiance.r; // irradiance RED data3.w=irradiance.g; data4.w=irradiance.b;

Shader.cg
uniform int viewSize; uniform float colorscale; uniform int specularBounce; uniform uniform uniform uniform uniform uniform uniform uniform uniform uniform uniform uniform uniform float3 lightOrigin; float3 lightUpVec,lightNormalVec; float maxAngle; float minAngleRatio; samplerRECT samplerRECT samplerRECT samplerRECT samplerRECT origins; directions; states; isectdatas; photonhits;

samplerRECT v0; samplerRECT v1; samplerRECT v2; int vertexListSize;

uniform samplerRECT n0;

87

uniform uniform uniform uniform

samplerRECT samplerRECT samplerRECT samplerRECT

n1; n2; matColors; matAttribs;

uniform samplerRECT photonmapNormals; uniform samplerRECT irradiance; uniform samplerRECT shadows; uniform uniform uniform uniform float float float float addAmbientIlum; addDirectIlum; addIndirectIlum; addShadows;

#include "ray.cg" #include "common.cg" float3 lert(float3 a, float3 b, float3 c, float u, float v) { return a + u*(b - a) + v*(c-a); } const float ambientK=0.15; const float glossiness=15.0; void shader(in float2 rayIndex:TEXCOORD0, out float4 color:COLOR0) { const float minLightLevel=0; float3 origin = texRECT(origins, rayIndex).xyz; float3 direction = texRECT(directions, rayIndex).xyz; float4 state = texRECT(states, rayIndex).xyzw; float4 isectdata = texRECT(isectdatas, rayIndex); float4 photonhit = texRECT(photonhits, rayIndex); float4 shadow = texRECT(shadows, rayIndex); half3 irrad = texRECT(irradiance, rayIndex).xyz; color = float4(0,0,0,1); float3 lightLeftVec = cross(lightUpVec,lightNormalVec); if (state.x == STATE_SHADE) { float2 triangleIndex = isectdata.zw; //Fetch normal half3 normal0 = texRECT(n0, triangleIndex).xyz; half3 normal1 = texRECT(n1, triangleIndex).xyz; half3 normal2 = texRECT(n2, triangleIndex).xyz; //Fetch material color half3 matColor = texRECT(matColors, triangleIndex).xyz; half4 matAttrib = texRECT(matAttribs, triangleIndex); half half half half bool diffuseK=matAttrib.x; // prob. of diffuse reflection specularK=matAttrib.y; // prob. of specular reflection reflectK=matAttrib.z; smoothing=fmod(matAttrib.w,128); selfilum=(matAttrib.w>=128);

//calculate hit point ray r; r.o = texRECT(origins, rayIndex).xyz; r.d = texRECT(directions, rayIndex).xyz; float3 hit = evaluate(r,state.y); float3 lightVec = lightOrigin-hit;

88

float3 lightVecN = normalize(lightVec); // project light-hitpoint vector into light coordinates system float lx=dot(lightLeftVec,lightVecN); float ly=dot(lightUpVec,lightVecN); float lz=dot(lightNormalVec,lightVecN); float lightDistance=length(lightVec); float alfa=degrees(atan2(sqrt(lx*lx+ly*ly),-lz)); float lightPower=minLightLevel; if ((alfa<maxAngle) && (lz<0)) lightPower=(minLightLevel+smoothstep(maxAngle, maxAngle*0.8,alfa)*(1-inLightLevel)); float attenuation=1/(1+0.01*lightDistance*lightDistance); lightPower=lightPower*min(1,attenuation); //Calculate normal float ucoord=isectdata.x; float vcoord=isectdata.y; if (smoothing<1.0) {ucoord=0.5; vcoord=0.5;} // surface normal float3 normal = normalize(lert(normal0, normal1, normal2,ucoord,vcoord)); float3 halfVec = normalize(lightVecN - direction); float3 ambient=ambientK*matColor/255; // Ambient component // Diffuse component float noshadow=1; if ((addShadows==1.0) && (shadow.y+0.1<lightDistance)) noshadow=0; float d=dot(normal,lightVecN); float3 directDiffuse=noshadow*diffuseK*max(d,0)*(matColor/255)* lightPower*attenuation; //Specular component float3 directSpecular=float3(0,0,0); float s=dot(normal, halfVec); if ((s>0.0001) && (d>0)) directSpecular=noshadow*specularK*(max(0,pow(s,glossiness)) * lightPower*attenuation)*float3(1,1,1); // Indirect component float3 indirect=(matColor/255)*(irrad*0.1); if (selfilum){ color.xyz=matColor/255;color.w=1; } else{ color.xyz=colorscale*(addAmbientIlum*ambient+ addDirectIlum*(directDiffuse+directSpecular) +addIndirectIlum*(indirect)); color.w=max(0,1-reflectK); } } else if (state.x == STATE_BACKGROUND) { color = float4(0,0,0,1); } else if (state.x == STATE_DONT_TRACE) { color = float4(0,0,0,0); } else

89

{ discard; } }

ShadowsGenerator.cg
uniform samplerRECT origins; //Texture of ray origins uniform samplerRECT directions; //Texture of ray directions uniform samplerRECT states; //State vector uniform float3 lightOrigin; #include "ray.cg" #include "common.cg" void shadowsGenerator(in float2 rayIndex:TEXCOORD0, out float3 outrayOrig:COLOR0, out float3 outrayDirec:COLOR1, out float4 outrayState:COLOR2) { float3 inrayOrig= texRECT(origins, rayIndex).xyz; float3 inrayDirec= texRECT(directions, rayIndex).xyz; float4 inrayState= texRECT(states, rayIndex).xyzw; outrayOrig=float3(0,0,0); outrayDirec=float3(0,0,0); outrayState=float4(0,0,0,0); if (inrayState.x == STATE_SHADE) { //calculate hit point ray r; r.o = inrayOrig; r.d = inrayDirec; float3 hitpoint = evaluate(r,inrayState.y); outrayDirec=normalize(lightOrigin-hitpoint); outrayOrig=hitpoint+normalize(outrayDirec)*0.01f; outrayState.x=STATE_TRAV_SETUP; outrayState.y=INF; } else //if (inrayState.x == STATE_BACKGROUND) { outrayState.x=STATE_DONT_TRACE; } }

SpecularReflectionsGenerator.cg
uniform uniform uniform uniform samplerRECT samplerRECT samplerRECT samplerRECT origins; directions; states; isectdatas;

uniform samplerRECT n0; uniform samplerRECT n1;

90

uniform samplerRECT n2; uniform samplerRECT matAttribs; #include "ray.cg" #include "common.cg" float3 lert(float3 a, float3 b, float3 c, float u, float v) { return a + u*(b - a) + v*(c-a); }

void specularReflector(in float2 rayIndex:TEXCOORD0, out float3 outrayOrig:COLOR0, out float3 outrayDirec:COLOR1, out float4 outrayState:COLOR2) { float3 float3 float4 float4 inrayOrig= texRECT(origins, rayIndex).xyz; inrayDirec= texRECT(directions, rayIndex).xyz; inrayState= texRECT(states, rayIndex).xyzw; inrayIsectData= texRECT(isectdatas, rayIndex);

outrayOrig=float3(0,0,0); outrayDirec=float3(0,0,0); outrayState=float4(0,0,0,0); if (inrayState.x == STATE_SHADE) { float2 triangleIndex = inrayIsectData.zw; float4 matattribs = texRECT(matAttribs, triangleIndex); float specularity=matattribs.y; float reflectivity=matattribs.z; float smoothing=matattribs.w; if (reflectivity>0.0){ //Fetch normal float3 normal0 = texRECT(n0, triangleIndex).xyz; float3 normal1 = texRECT(n1, triangleIndex).xyz; float3 normal2 = texRECT(n2, triangleIndex).xyz; //calculate hit point ray r; r.o = inrayOrig; r.d = inrayDirec; float3 hitpoint = evaluate(r,inrayState.y); float u=0.5; float v=0.5; if (smoothing==1.0) { u=inrayIsectData.x; v=inrayIsectData.y; } float3 normal = normalize(lert(normal0, normal1, normal2,u,v));// surface normal outrayDirec=reflect(inrayDirec,normal); // specular outrayOrig=hitpoint+normalize(outrayDirec)*0.001f; outrayState.x=STATE_TRAV_SETUP; outrayState.y=INF; outrayState.z=0; outrayState.w=0; } else { outrayState.x=STATE_DONT_TRACE; }

91

} else //if (inrayState.x == STATE_BACKGROUND) { outrayState.x=STATE_DONT_TRACE; } }

SurfaceDataGenerator.cg
uniform samplerRECT states; uniform samplerRECT isectdatas; uniform uniform uniform uniform uniform samplerRECT samplerRECT samplerRECT samplerRECT samplerRECT n0; n1; n2; matAttribs; matColors;

#include "common.cg" float3 lert(float3 a, float3 b, float3 c, float u, float v) { return a + u*(b - a) + v*(c-a); }

void surfData(in float2 rayIndex:TEXCOORD0, out half3 surfnormal:COLOR0, out half4 surfdata:COLOR1) { float4 state = texRECT(states, rayIndex).xyzw; float4 isectdata = texRECT(isectdatas, rayIndex); surfnormal=half3(0,0,0); surfdata=half4(0,0,0,0); if (state.x == STATE_SHADE) { float2 triangleIndex = isectdata.zw; //Fetch normal half3 normal0 = texRECT(n0, triangleIndex).xyz; half3 normal1 = texRECT(n1, triangleIndex).xyz; half3 normal2 = texRECT(n2, triangleIndex).xyz; //Fetch material color half4 matAttrib = texRECT(matAttribs, triangleIndex); half4 matColor = texRECT(matColors, triangleIndex); half smoothing=matAttrib.w; float u=isectdata.x; float v=isectdata.y; if (smoothing<1.0) { u=0.5; v=0.5; } half3 normal = normalize(lert(normal0, normal1, normal2,u,v)); surfnormal=normal; surfdata.x=matColor.w;// Object ID } }

92

Integrator.cg
uniform samplerRECT directIlumination; uniform samplerRECT indirectIlumination; uniform samplerRECT specularReflections; uniform int addReflections; void integrator(in float2 rayIndex:TEXCOORD0,out float3 color:COLOR0) { float4 eyerays = texRECT(directIlumination, rayIndex); float4 reflections = texRECT(specularReflections, rayIndex); color=(eyerays.w)*(eyerays.xyz)+(reflections.xyz)*addReflections; }

93

Bibliografa
[1] J.T. Kajiya, The rendering equation. In Proceedings of the 13th annual conference on Computer graphics and interactive techniques (1986), ACM Press, pp. 143150. F. E. Nicodemus, J. C. Richmond, J. J. Hsia, I.W. Ginsberg, and T. Limperis, Geometric considerations and nomenclature for reflectance. Monograpgh 161, National Bureau of Standards (US), October 1977. Tuner Whitted. An improved illumination for shaded display. Communications of the ACM 23(6): 343 - 349 (June 1980). John M. Snyder and Alan H. Barr, Ray Tracing complex models containing surface tessellations. Computer Graphics (Proc. Siggraph 87) 21 (4): 119-128 (July 1987). Kryzsztof S. Ckilmansezewski and Thomas W. Sederberg. Faster Ray Tracing using adaptive grids. IEEE Computer Graphics & Applications 17(1): 42-51 (January-February 1997). T. J. Purcell. Ray Tracing on a Stream Processor PhD thesis, Stanford University, 2004. Frederik W. Jansen. Data structures for Ray Tracing. In Data structures for Raster Graphics, edited by L.R.A. Kessener, F.J. Peters, y m. L. P. van Lierop, pp. 57-73, Berlin: Springer-Verlag, 1985. T. J. Purcell, C. Donner, M. Cammarano, H. W. Jensen, and P. Hanrahan. Photon mapping on programmable graphics hardware. In Proceedings of the ACM SIGGRAPH/Eurographics Symposium on Graphics Hardware. Robert L. Cook, Thomas Porter, and Loren Carpenter. Distributed Ray Tracing. Computer Graphics (Proc. SIGGRAPH 84) 18(3): 137-45 (July 1984).

[2]

[3] [4]

[5]

[6] [7]

[8]

[9]

[10] Eric. P. Lafortune and Yves D. Willems. Bidirectional Path Tracing. In Compugraphics93, pp. 95-104, 1993. [11] Eric Veach and Leonidas Guibas. Bidirectional estimators for light transport. In Fifth Eurographics Workshop on Rendering, pp. 147-162, Eurographics, 1994. [12] C. M. Goral, K. E. Torrance, D. P. Greenberg, and B. Battaile, Modeling the interaction of light between diffuse surfaces. In Proceedings of the 11th annual conference on Computer Graphics and Interactive Techniques (1984), pp. 213 222.

94

[13]

M. F. Cohen, S. E. Chen, J. R. Wallace, and D. P. Greenberg, A progressive refinement approach to fast Radiosity image generation. In proceedings of the 15th annual conference on Computer graphics and interactive techniques (1988), ACM Press, pp. 7584.

[14] M. F. Cohen, and D. P. Greenberg, The hemi-cube: a Radiosity solution for complex environments. In Proceedings of the 12th annual conference on Computer graphics and interactive techniques (1985), ACM Press, pp. 31 40. [15] H. W. Jensen, Realistic Image Synthesis using Photon Mapping. A K Peters. ISBN 1568811470 (2001) [16] I. Wald, J. Gunther, and P. Slusallek, Balancing Considered Harmful Faster Photon Mapping using the Voxel Volume Heuristic. Computer Graphics Forum 22, 3 (2004), 595603. (Proceedings of Eurographics). [17] G. J. Ward, F. M. Rubinstein, and R. D. Clear, A Ray Tracing solution for diffuse interreflection. In SIGGRAPH 88: Proceedings of the 15th annual conference on Computer graphics and interactive techniques (New York, NY, USA, 1988), ACM Press, pp. 8592. [18] Niels Thrane, Lars Ole Simonsen. A Comparison of Acceleration Structures for GPU Assisted Ray Tracing. Masters thesis, University of Aarhus, August, 2005. [19] Framebuffer Object Extension. http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt [20] W. Strzlinger, R. Bastos, Interactive Rendering of Globally Illuminated Glossy Scenes. Eurographics Rendering Workshop 97. ISBN 3-211-83001-4. (June 1997) 93-102. [21] F. Lavignotte, M. Paulin, Scalable Photon Splatting for Global illumination. Graphite 2003 (International Conference on Computer Graphics and Interactive Techniques in Australasia and South East Asia). Melbourne, Australia. ACM SIGGRAPH. 1-11 [22] Framebuffer Object Class http://www.gpgpu.org/developer/ [23] G. Humphreys, M. Houston, Y.-R. Ng, R. Frank, S. Ahern, P. Kirchner, and J. T. Klosowski, "Chromium: A Stream Processing Framework for Interactive Graphics on Clusters," presented at SIGGRAPH, San Antonio, Texas, 2002 [24] Greg Humphreys, Ian Buck, Matthew Eldridge, and Pat Hanrahan, Distributed rendering for scalable displays. In Supercomputing, 2000.

95

[25] F. Randima and Mark J. Kilgard, The Cg Tutorial: The Definitive Guide to Programmable Real-Time Graphics.Addison-Wesley, 1996. ISBN 0-321-19496-9 [26] James Arvo, David B. Kirk Particle transport and image synthesis. Computer Graphics (Proc. SIGGRAPH 90) 24(4): 63-66 (August 1990). [27] T. R. Jozwowski, Real Time Photon Mapping. Master's thesis, Michigan Technological University, 2002. [28] Eric Veach and Leonidas J. Guibas, Metropolis Light Transport. In Proceedings of SIGGRAPH 97, Computer Graphics Proceedings, Annual Conference Series, edited by Turner Whitted, pp. 65-76, Reading, Ma: Addison Wesley, August 1997. [29] The NVIDIA Cg Toolkit. http://developer.nvidia.com/page/cg_main.html [30] Bui-Tuong Phong, Illumination for Computer Generated Pictures. Comm. ACM 18(6), 311-317. [31] H. Gouraud, "Continuous shading of curved surfaces". IEEE Transactions on Computers, 20(6):623628, 1971.

96

Вам также может понравиться