Proyecto Fin de Carrera PDF
Proyecto Fin de Carrera PDF
Proyecto Fin de Carrera PDF
Autor
Director
RESUMEN
Las modernas unidades de procesamiento grfico ofrecen capacidades operacionales de
clculo general. Este mbito est cobrando importancia ya que muchos clculos pueden
derivarse a la GPU, donde la existencia de numerosos ncleos trabajando en paralelo
permite obtener una mayor rapidez en la resolucin de algunos problemas, tanto de
ndole cientfico como para los videojuegos.
En este mbito es donde surge este Proyecto de Fin de Carrera. En concreto se ha
creado un paisaje procedural formado por varios elementos como montaas, playa,
agua, un planeta y nubes. Todos ellos se han creado utilizando el ruido de Perlin para
generar formas fractales. Dicho algoritmo est especialmente aconsejado para la
generacin de objetos naturales y adems es adecuado para aprovechar la capacidad de
clculo en paralelo de las unidades de procesamiento grfico, ya que cada vrtice puede
calcularse de manera individual.
Adems de los aspectos relacionados con la geometra de estos elementos se han tenido
en cuenta otros componentes de una pipeline grfica como son el modelo de
iluminacin y sombras, el texturizado de los objetos, el audio, el movimiento de la
cmara y la animacin de algunos elementos.
La aplicacin se ha desarrollado utilizando la API Direct3D 11 de Microsoft, ya que es
una de las ms usadas en el mundo de los grficos y nos permite aprovechar las
caractersticas de la GPU. Adems este API contiene varias herramientas que sirven
para controlar el estado de actividad de la unidad grfica, incluyendo el tiempo que est
trabajando, lo que nos ha permitido poner de manifiesto el beneficio de una ejecucin
en paralelo.
Finalmente, se ha integrado el algoritmo de ruido de Perlin en el entorno de desarrollo
de videojuegos UDK, Unreal Development Kit, donde se ha usado para crear un planeta
fractal. De esta manera se demuestra la capacidad tcnica para adaptar y aplicar los
conocimientos adquiridos en aplicaciones comerciales ya existentes.
NDICE DE CONTENIDOS
RESUMEN........................................................................................................................5
NDICE DE CONTENIDOS.............................................................................................7
NDICE DE TABLAS.......................................................................................................8
NDICE DE FIGURAS.....................................................................................................9
1. INTRODUCCIN.......................................................................................................13
1. 1. Contexto tecnolgico..........................................................................................13
1. 2. Objetivos.............................................................................................................15
1. 3. Estructura del documento...................................................................................16
2. TRABAJO REALIZADO...........................................................................................17
2. 1. Fractales y ruido..................................................................................................17
2. 2. Direct3D..............................................................................................................22
2. 3. Creacin de la escena..........................................................................................26
2. 4. Anlisis de rendimiento.......................................................................................36
2. 5. Integracin en UDK............................................................................................44
3. CONCLUSIONES.......................................................................................................47
3. 1. Resultados obtenidos..........................................................................................47
3. 2. Lneas futuras......................................................................................................47
3. 3. Valoracin personal.............................................................................................48
4. BIBLIOGRAFA.........................................................................................................49
ANEXOS
ANEXO A: GESTIN DEL PROYECTO......................................................................55
A. 1. Planificacin.......................................................................................................55
A. 2. Herramientas utilizadas......................................................................................56
ANEXO B: COMPARACIN DE MOTORES..............................................................57
B. 1. Herramientas disponibles...................................................................................57
B. 2. Imgenes comparativas......................................................................................64
ANEXO C: LA PIPELINE GRFICA...........................................................................71
C. 1. Etapas.................................................................................................................71
C. 2. HLSL..................................................................................................................72
ANEXO D: LA PIPELINE DE CLCULO....................................................................75
D. 1. Etapas.................................................................................................................75
D. 2. Caractersticas....................................................................................................75
ANEXO E: APLICACIN ESTUDIADA......................................................................79
E. 1. Contexto.............................................................................................................79
E. 2. Diseo.................................................................................................................80
E. 3. Aplicacin...........................................................................................................81
E. 4. Shader de clculo................................................................................................91
E. 5. Shaders de renderizado.......................................................................................94
E. 6. Resultados...........................................................................................................96
ANEXO F: RUIDO Y FRACTALES..............................................................................97
F. 1. Ruido...................................................................................................................97
F. 2. Tipos de ruido......................................................................................................97
F. 3. Fractales..............................................................................................................98
ANEXO G: DOCUMENTACIN DE LA APLICACIN...........................................101
G. 1. Lista de clases..................................................................................................101
G. 2. Documentacin de clases.................................................................................101
7
NDICE DE TABLAS
Tabla 1: Geometra de la escena......................................................................................34
Tabla 2: Llamada draw 1.................................................................................................36
Tabla 3: Llamada draw 2.................................................................................................37
Tabla 4: Llamadas draw 3 -12.........................................................................................37
Tabla 5: Llamada draw 13...............................................................................................37
Tabla 6: Equipos de prueba..............................................................................................38
Tabla 7: Dedicacin.........................................................................................................55
Tabla 8: Herramientas utilizadas.....................................................................................56
Tabla 9: Motores. Animacin..........................................................................................57
Tabla 10: Motores. Audio................................................................................................58
Tabla 11: Motores. Cinemticas......................................................................................58
Tabla 12: Motores. Networking.......................................................................................58
Tabla 13: Motores. Editor................................................................................................59
Tabla 14: Motores. Fsicas...............................................................................................59
Tabla 15: Motores. Iluminacin.......................................................................................60
Tabla 16: Motores. Inteligencia Artificial........................................................................60
Tabla 17: Motores. Programacin....................................................................................61
Tabla 18: Motores. Renderizado......................................................................................62
Tabla 19: Motores. Shaders y materiales.........................................................................63
Tabla 20: Motores. Terreno..............................................................................................63
Tabla 21: Motores. Otros.................................................................................................64
NDICE DE FIGURAS
Figura 1: Gradientes generados en 2 dimensiones..........................................................18
Figura 2: Malla en 2 dimensiones, n = 2.........................................................................19
Figura 3: Octavas de ruido...............................................................................................20
Figura 4: Ruido de Perlin, paso 1....................................................................................20
Figura 5: Ruido de Perlin, paso 2....................................................................................21
Figura 6: Ruido de Perlin, paso 3....................................................................................21
Figura 7: Arquitectura grfica..........................................................................................22
Figura 8: Pipeline grfica................................................................................................23
Figura 9: Pipeline computacional....................................................................................23
Figura 10: Threads en la GPU.........................................................................................24
Figura 11: Mip-mapping..................................................................................................25
Figura 12: Recursos en la pipeline grfica......................................................................25
Figura 13: Recursos en la pipeline computacional..........................................................26
Figura 14: Escena con un solo fractal..............................................................................27
Figura 15: Escena con 2 fractales....................................................................................27
Figura 16: Escena con los 3 fractales..............................................................................28
Figura 17: Escena completa.............................................................................................28
Figura 18: Clculo del fractal de la playa y las montaas...............................................29
Figura 19: Superficie del planeta fractal..........................................................................31
Figura 20: Planeta con nubes...........................................................................................31
Figura 21: Cielo...............................................................................................................32
Figura 22: Animacin de los pjaros...............................................................................32
Figura 23: Paisaje 100% - 649.800 vrtices....................................................................35
Figura 24: Paisaje 50% - 324.900 vrtices......................................................................35
Figura 25: Paisaje 25% - 162.450 vrtices......................................................................35
Figura 26: Paisaje 10% - 64.979 vrtices........................................................................36
Figura 27: Escena 1.........................................................................................................40
Figura 28: Escena 2.........................................................................................................40
Figura 29: Tiempo de inicio (s).......................................................................................41
Figura 30: Tiempos en la GPU (ms)................................................................................42
Figura 31: Tiempos en la CPU (ms)................................................................................43
Figura 32: Tiempos escena 1 GPU vs CPU (ms).............................................................44
Figura 33: Ruido de Perlin en UDK................................................................................45
Figura 34: Escena UDK...................................................................................................46
Figura 35: Muestra UDK 1..............................................................................................65
Figura 36: Muestra UDK 2..............................................................................................65
Figura 37: Muestra UDK 3..............................................................................................66
Figura 38: Muestra UDK 4..............................................................................................66
Figura 39: Muestra CryEngine 1.....................................................................................67
Figura 40: Muestra CryEngine 2.....................................................................................67
Figura 41: Muestra Cryengine 3......................................................................................68
Figura 42: Muestra CryEngine 4.....................................................................................68
Figura 43: Muestra Unity 1.............................................................................................69
Figura 44: Muestra Unity 2.............................................................................................69
Figura 45: Muestra Unity 3.............................................................................................70
Figura 46: Muestra Unity 4.............................................................................................70
Figura 47: Pipeline grfica..............................................................................................71
9
10
1. INTRODUCCIN
El presente documento tiene como objetivo presentar toda la informacin relacionada
con la realizacin de este Proyecto de Fin de Carrera (PFC) titulado Generacin de
paisajes procedurales con Direct3D y GPU. En este apartado titulado Introduccin se
describe el contexto tecnolgico en el que se inserta este proyecto as como sus
objetivos y la estructura general de la memoria.
1. 1. Contexto tecnolgico
1. 1. 1. Unidades de procesamiento grfico
Las unidades de procesamiento grfico (GPU) han evolucionado enormemente a lo
largo de los aos, pasando de ofrecer una pipeline fija a otra mucho ms flexible que
puede ejecutar programas, denominados shaders, realizados por cualquier
desarrollador usando alguno de los lenguajes existentes: HLSL, de Microsoft; CG, de
nVidia; o GLSL, libre, aunque realmente hay pocas diferencias conceptuales adems de
las sintcticas.
Es aqu donde se basa el concepto de clculo general en la unidad grfica, o GPGPU por
su nombre en ingls, General Purpose computing on Graphics Processing Units.
Debido a que las GPU no son ms que coprocesadores especializados en operaciones
con nmeros reales es tericamente posible utilizar su gran nmero de ncleos
trabajando en paralelo para cualquier tipo de problema paralelizable del tipo SIMD,
Single Instruction Multiple Data.
Para la programacin de las unidades grficas se usan distintas API, siendo Direct3D,
propiedad de Microsoft, y OpenGL, libre, las ms utilizadas para el apartado grfico.
Por otra parte, DirectCompute, tambin de Microsoft; CUDA, de nVidia, y OpenCL son
las usadas para la parte computacional. Todas ellas se pueden integrar fcilmente en
cualquier aplicacin.
1. 1. 2. Videojuegos
Entre las aplicaciones comunes que ms utilizan la GPU estn los videojuegos. Por ello
se ha querido enmarcar este proyecto en este mbito.
El desarrollo de un videojuego es un proceso complejo que no se limita tan solo a la
programacin de la parte visual. Recordemos algunas de las fases por las que se pasa
durante su creacin:
Concepcin: definir la idea, el gnero del juego, cmo y dnde va a ser jugado,
la historia, los personajes o la ambientacin.
13
14
La versin gratis es, no obstante, incompleta y solo la de pago ofrece todas las
caractersticas [1].
Puede verse una comparacin en detalle de las caractersticas que ofrece cada motor en
el ANEXO B: COMPARACIN DE MOTORES.
En este trabajo cabe mencionar que CryEngine deja de ser una opcin puesto que no
permite la programacin de shaders. En cuanto a Unity y UDK, es este ltimo el que
ofrece ms funcionalidades y por eso es el motor elegido.
El motor Unreal en PC utiliza Direct3D como API grfica, por lo que es obligatorio
elegir HLSL como lenguaje de programacin de shaders..
El motor puede usar tanto Direct3D 9 como 11, que son las dos ltimas versiones ms
extendidas de la API. La versin 10 es muy poco utilizada, ya que se cre para
funcionar en el sistema operativo Windows Vista, cuya penetracin en el mercado fue
escasa en comparacin con XP, que usa la versin 9. Direct3D 11 se desarroll para
funcionar con Windows 7 y es la elegida puesto que es la ms moderna y la que ms
funcionalidades incorpora, incluyendo el ltimo modelo de shaders que nos permite usar
compute shaders y utilizar la GPU para cmputo general [4].
1. 2. Objetivos
La idea de este proyecto es utilizar las unidades de procesamiento grfico y mostrar sus
capacidades en el mundo de los videojuegos.
Los objetivos concretos a alcanzar son:
15
16
2. TRABAJO REALIZADO
En esta seccin se detalla el trabajo realizado a lo largo del PFC. Se comienza
describiendo los fractales, seccin 2.1, y se sigue con el estudio de Direct3D, API
utilizada para crear nuestra aplicacin, en la seccin 2.2. Despus se explica la creacin
de la escena, seccin 2.3. A continuacin se compara el rendimiento obtenido usando
una CPU y una GPU, seccin 2.4. Por ltimo, se integra parte del trabajo realizado en el
motor Unreal Engine, seccin 2.5.
2. 1. Fractales y ruido
2. 1. 1. Fractales
Un fractal es un patrn que se repite a diferentes escalas para describir la forma de un
objeto irregular que no se podra obtener con los mtodos de la geometra clsica. stos
nos permiten, a travs de algoritmos, reproducir la complejidad de elementos tpicos de
la naturaleza como son las montaas, las nubes o incluso planetas enteros.
Aunque las ideas que existen tras estos mtodos se remontan al siglo 17 en esa poca los
matemticos estaban limitados a las imgenes que podan reproducir ellos mismos. Es
por eso que empiezan a cobrar importancia a partir de los aos 70, cuando aparecen los
primeros grficos por computador. Es en el ao 1979 cuando se crea la primera
animacin con elementos fractales, un corto de 2 minutos llamado Vol Libre de Loren
Carpenter [5].
No obstante, el primer trabajo formal en el que se define el concepto de los fractales tal
y como los conocemos ahora se debe a Benoit Mandelbrot en su libro The Fractal
Geometry of Nature, publicado en 1982 [6]. En ese ao tambin se crea el primer
planeta fractal mostrado en el cine en la pelcula Star Trek II, tambin por Carpenter y
su equipo de Pixar [7].
Desde entonces las imgenes creadas usando fractales han evolucionado junto con la
tecnologa, que cada vez permite alcanzar mayor realismo. Algunas de estas imgenes
pueden verse en el ANEXO F: RUIDO Y FRACTALES.
Es importante mencionar la aparicin en 1985 del Ruido de Perlin, ideado por Ken
Perlin [8]. Con l comenzaron los mtodos procedurales de generacin de fractales que
an hoy se siguen utilizando. En el mismo anexo citado se presenta una descripcin ms
detallada de las funciones usadas en estos mtodos.
Finalmente, comentar la existencia de la primera edicin del libro Texturing &
Modelling: A Procedural Approach en 1994 [9]. Es uno de los libros de referencia
sobre este tema y el que ha servido, en su tercera edicin, como gua e inspiracin para
el trabajo realizado en este PFC.
En ese mismo libro, adems de tratar los problemas tradicionales encontrados al trabajar
con fractales, tambin se presentan las tcnicas ms actuales y los nuevos retos
aparecidos al usar unidades grficas como herramienta de clculo.
17
2. 1. 2. Ruido de Perlin
El ruido de Perlin es una funcin matemtica que usa interpolacin entre varios
gradientes precalculados para obtener un valor entre -1 y 1 que vara pseudoaleatoriamente en el espacio o en el tiempo. Adems tiene la particularidad de ser
coherente, es decir, el ruido cambia suavemente y no existen discontinuidades [10].
La funcin puede definirse en cualquier espacio, sea cual sea su nmero de
dimensiones.
El espacio de n dimensiones que elijamos se divide en una malla definida para cada
punto con coordenadas enteras y a cada uno de ellos se le asigna uno de los gradientes
precalculados. Dichos gradientes se generaban inicialmente de manera aleatoria con
componentes entre -1.0 y 1.0, descartando aquellos cuya longitud sea superior a 1 y
normalizando el resto para evitar desviaciones alineadas con alguno de los ejes del
espacio.
En una revisin posterior Perlin decidi dejar de generar gradientes aleatorios ya que la
manera de asignarlos, comentada a continuacin, otorga suficiente aleatoriedad. Desde
entonces se utilizan gradientes que van desde el centro de un objeto de referencia de
dimensiones unidad, como un cuadrado en 2 dimensiones o un cubo en un espacio 3D, a
las aristas de dicho objeto y se normalizan, como vemos en la figura 1.
Usando este vector p1 obtenemos el resto de vectores que van desde las esquinas de la
celda al punto p, como se muestra en la figura 5.
p2 = p1 + (-1, 0);
p3 = p1 + (0, -1);
p4 = p1 + (-1, -1);
A = permutacin(P.x) + P.y;
B = permutacin(P.x + 1) + P.y;
g1 = gradiente(permutacin(A));
g2 = gradiente(permutacin(B));
g3 = gradiente(permutacin(A+1));
g4 = gradiente(permutacin(B+1));
d3 = dot(p3, g3);
21
d4 = dot(p4, g4);
2. 2. Direct3D
La API utilizada para interaccionar con la GPU en nuestra aplicacin es Direct3D 11, la
cual est diseada para poder ser accedida directamente mediante cdigo en C/C++ [4]
[13] [14] [15].
2. 2. 1. Arquitectura y pipeline
La arquitectura grfica seguida en Windows puede verse en la figura 7. La aplicacin
est en el nivel ms alto y es la que controla la escena: objetos 2D y 3D, animaciones,
texturas, etc. sta interacta principalmente con Direct3D, que convierte los datos de
alto nivel a un formato que pueda ser utilizado por el user mode driver, un driver de alto
nivel que no puede acceder directamente al kernel de la GPU para simplificar su
funcionamiento y reducir el nmero de errores.
Este driver se encarga de la traduccin a instrucciones que puedan ser ejecutadas por la
unidad de procesamiento grfico y sus resultados se pasan al siguiente nivel, DXGI, que
maneja los recursos de la GPU y se comunica directamente con la tarjeta grfica.
Este nivel est preparado para funcionar con prximas iteraciones de Direct3D, por lo
que tambin puede accederse directamente desde la aplicacin si necesitamos realizar
alguna operacin que an no est implementada en la API Direct3D 11.
Finalmente, el ltimo nivel es el propio hardware.
Ya que la aplicacin se comunica principalmente con Direct3D el programador puede
olvidarse del tipo de dispositivo grfico que est instalado, abstrayndose de la
complejidad del hardware disponible.
22
23
24
25
2. 2. 3. Ejemplo de estudio
Para comprender el funcionamiento de Direct3D se ha desarrollado una simulacin de
agua que nos ha permitido observar las distintas caractersticas comentadas. Una
descripcin detallada de sta se encuentra en el ANEXO E: APLICACIN
ESTUDIADA.
2. 3. Creacin de la escena
Se ha creado un paisaje con varios elementos generados de manera procedural: unas
montaas, una playa, un mar y un planeta. Adems en la escena se presentan otros
objetos no procedurales como el cielo, unos pjaros y varias palmeras.
Los objetos procedurales se crean usando varias octavas de ruido de Perlin que se
suman para dar lugar a un fractal que calcule cierto valor: la altura de un vrtice para la
playa y la montaa, la posicin completa de un vrtice en el caso del agua y el color del
planeta. En todos ellos los datos de la funcin fractal se han ajustado para conseguir las
26
distintas formas naturales por ensayo y error, pues es la mejor manera para conseguirlos,
ya que con solo las funciones matemticas y sus factores no es fcil prever el resultado.
Los 3 primeros elementos parten originalmente de 3 planos distintos y a partir de ellos
se calculan los 3 fractales, que se superponen para crear el paisaje, como se ve en las
figuras 14, 15 y 16. Aunque es la manera ms costosa, es la nica forma de conseguir
intersecciones realistas entre las distintas partes.
27
2. 3. 1. Montaas y playa
Las montaas se calculan inicialmente a partir de un plano dividido en tringulos. Un
fractal bsico con 10 octavas de ruido de Perlin en 2 dimensiones se utiliza para calcular
la altura de cada vrtice, la cual se escala para obtener el tamao deseado [16]. Tras
haber obtenido las nuevas posiciones de cada vrtice debemos calcular las normales en
cada uno de ellos para que luego la visualizacin sea posible.
28
La playa se calcula de manera similar, con 8 octavas de ruido de Perlin que nos dan la
altura del vrtice.
Al hacer los clculos de la altura guardamos informacin de todos aquellos vrtices que
superen una altura lmite. Estos datos se utilizan durante el clculo del agua para reducir
operaciones, ya que en esos puntos el nivel del agua siempre estar por debajo de los
otros elementos y no se ver, por lo que no necesitamos hacer la simulacin.
Estos pasos se realizan en la GPU en dos compute shaders, uno para el clculo de la
altura y otro para el de las normales. Se ejecutan al inicio de la aplicacin ya que nos
basta con hacerlos una vez. Como ambos objetos son planos divididos en vrtices
aprovechamos esta disposicin y organizamos los threads de la GPU en 3 dimensiones
como dos planos de igual tamao, mostrados en la figura 18. Cada grupo se compone de
un nico thread ya que no necesitamos una organizacin ms compleja y a cada hilo se
le asigna un vrtice.
Gracias a esta disposicin podemos tener todos los ncleos de la unidad grfica
trabajando en paralelo, cada uno con un vrtice distinto, algo que en una CPU debera
hacerse de manera secuencial y tardara ms.
2. 3. 2. Agua
De nuevo partimos de un plano de tringulos cuyos vrtices se van moviendo con el
tiempo. Ya que debemos actualizarla en cada momento el agua es el componente que
ms influye en el rendimiento de la aplicacin, por eso es importante no calcular zonas
que no se ven, para lo que utilizamos los datos guardados en el paso anterior, o no
aadir el mximo detalle en zonas muy alejadas de la cmara.
Para comenzar se utiliza una funcin sinusoidal para modificar la altura de cada vrtice,
lo que nos da un oleaje base. A continuacin, en funcin de la distancia a la cmara, se
utilizan una o dos octavas de ruido de Perlin en 3 dimensiones que modifican la
posicin del vrtice. Se aade una dimensin respecto a los casos anteriores para utilizar
29
el tiempo como factor dinmico. Adems en este caso no se utiliza directamente el valor
del ruido, sino que se usa la inversa de su valor absoluto para acentuar los bordes.
Para aadir algo ms de detalle se suma otro fractal que simula la influencia del viento.
En su clculo se utilizan 2 octavas de ruido de Perlin distorsionado, es decir,
desplazamos el punto inicial una distancia aleatoria en la direccin (1,1,1) antes de
calcular el valor del ruido. Como obtener esto cada instante incrementara el tiempo de
procesamiento lo calculamos una vez al inicio de la aplicacin y lo guardamos en una
textura. Esto nos obliga a tener un viento fijo en cada posicin, pero los cambios que el
fractal del agua sufre con el tiempo ya otorgan suficiente dinamismo a la superficie.
Tras haber actualizado la posicin de los vrtices debemos calcular la normal igual que
hacemos con la playa y las montaas.
Cuando hacemos los clculos de la posicin tambin guardamos 2 texturas de
informacin. Una de ellas sirve para marcar las zonas de la playa que estn, o han
estado alguna vez, por debajo del nivel de agua y as poder tratarlas como si estuvieran
mojadas. La otra sirve para guardar la distancia que hay entre el nivel de playa y el
agua, que se utilizar para la espuma.
Todos los clculos se hacen en compute shaders en la GPU, cuyos threads se organizan
de manera similar a la comentada en el apartado anterior. En este caso hay un compute
shader inicial para el viento y dos que se ejecutan cada frame para la posicin y las
normales del agua.
2. 3. 3. Planeta
El planeta est representado por una esfera de tringulos que va rotando sobre s misma
y su modelado consta de dos partes, el clculo de la superficie, que es esttica, y el de
las nubes, que son dinmicas.
Para obtener la superficie utilizaremos una tabla de colores que represente cada tipo de
terreno: agua, desiertos, praderas, montaas, etc. Se empieza por utilizar un fractal con 8
octavas de ruido de Perlin en 3 dimensiones que nos da la altura, la cual nos sirve para
separar los ocanos de los continentes. A continuacin se usa otro fractal de 6 octavas
que, junto con la altura previamente calculada y la latitud del punto, nos sirve para
obtener el color que representa nuestro tipo de terreno en funcin del clima. Finalmente,
para evitar que las zonas sean demasiado uniformes y queden poco realistas, utilizamos
un fractal de 5 octavas para motear y distorsionar ligeramente el color. El resultado
puede verse en la figura 19.
Esta parte se hace al inicio de la aplicacin, ya que no vara, en un compute shader.
Como la esfera est organizada en paralelos y meridianos, existiendo vrtices en los
puntos en los que se cortan, disponemos los threads de manera similar, usando la latitud
y la longitud para que cada vrtice sea tratado en un hilo distinto.
30
El clculo de las nubes se hace cada instante puesto que cambia con el tiempo. Se usa
un fractal de 6 octavas con ruido de Perlin en 3 dimensiones distorsionado, igual que el
viento que empuja el agua. Este valor se usa para interpolar entre el blanco de las nubes
y el color ya calculado en el paso anterior, obteniendo as cielos despejados o zonas
cubiertas, como se observa en la figura 20.
A diferencia de todos los clculos comentados hasta ahora este ltimo se hace
directamente en un pixel shader por dos motivos. El primero es que la esfera est muy
alejada, podramos decir que fuera del planeta que contiene nuestro paisaje, y por eso no
se ilumina de la misma forma, por lo que el color final del pixel es directamente el
calculado. La segunda razn es que en el pixel shader solo es visible una porcin del
planeta, por lo que el nmero total de operaciones para obtener el fractal es menor.
2. 3. 4. Objetos no procedurales
Para recrear el cielo de nuestra escena se usa una esfera, siempre centrada alrededor de
la cmara, a la cual se le aplica una textura que representa un fondo de cielo algo
nublado con una cordillera de montaas rodeando el paisaje [17]. Podemos verlo en la
figura 21. Este objeto tampoco interacciona con la luz de la manera habitual, por lo que
no necesitamos calcular las normales.
Tambin se han aadido varias palmeras para tener una referencia del tamao de la
escena [18]. Tanto los modelos como las texturas aplicadas han sido obtenidos de una
pgina externa1. Las texturas que se aplican a las hojas tienen partes que deben ser
transparentes, por lo que ha sido necesario configurar la pipeline para usar el canal
alpha [19].
http://www.loopix-project.com
31
Iluminacin: la escena est iluminada por una luz direccional que simula la
procedente de un sol lejano, adems de existir una luz ambiental para evitar
zonas de total oscuridad. De la misma manera que con la cmara es posible
cambiar la direccin de la luz utilizando el teclado. Adems en el pixel shader se
usa el modelo de iluminacin de Phong, que usa las 3 componentes tpicas para
calcular la interaccin de la luz con un objeto: luz ambiental, luz difusa y luz
especular.
32
2. 3. 6. Detalles de la geometra
Salvo los pjaros todos los objetos mostrados por pantalla se definen usando listas de
tringulos. Estas constan de dos partes, una lista de vrtices, que se guarda en un vertex
buffer, y una lista de punteros a los vrtices, guardados en un index buffer. De esta
manera cada 3 ndices tenemos definido un nuevo tringulo y no es necesario repetir los
vrtices que formen parte de varios polgonos a la vez.
El caso de los pjaros es especial porque son objetos muy sencillos. En este caso solo
definimos los vrtices, guardados en un vertex buffer. Los 3 primeros vrtices sirven
para definir el primer tringulo y a partir de ese momento cada nuevo vrtice suma otro
tringulo, formado por este nuevo vrtice y los 2 inmediatamente anteriores.
A continuacin, en la tabla 1, vamos a detallar el nmero de vrtices, ndices y
tringulos de cada uno de los objetos que acabamos de mencionar.
2
3
4
5
http://www.texturex.com
http://www.blendswap.com
http://www.colorburned.com
http://www.soundjax.com
33
Elemento
Vrtices
ndices
Tringulos
Montaas
324.900
1.942.566
647.522
Playa
324.900
1.942.566
647.522
Agua
324.900
1.942.566
647.522
16
14
152.202
955.200
318.400
82
480
160
Palmera 1
1.008
1.008
336
Palmera 2
1.008
1.008
336
Palmera 3
1.008
1.008
336
Palmera 4
1.008
1.008
336
Palmera 5
276
276
92
1.131.452
6.787.686
2.262.702
Pjaro (x10)
Planeta
Cielo
Total:
34
35
2. 4. Anlisis de rendimiento
Una vez finalizada la aplicacin se van a tomar varias medidas de tiempos que nos
permitan ver el comportamiento de la CPU y la GPU en varios equipos distintos.
2. 4. 1. Definicin de la escena
La escena est compuesta por los elementos mencionados en el apartado anterior y,
como a la hora de renderizar la geometra se usan varias llamadas draw distintas para
ejecutar la pipeline grfica, vamos a mostrar la siguiente informacin agrupada de esta
manera. Para cada llamada se indicarn los polgonos dibujados y el espacio en
memoria de la GPU, en bytes, que ocupan todos los datos de entrada necesarios: buffers
de vrtices e ndices, programas shaders, resto de buffers y texturas.
Las tablas 2 - 5 muestran cada llamada en el orden en que se ejecutan.
Cielo: tabla 2
Tringulos dibujados
160
5.576 B
1.920 B
15.256 B
14.512 B
192 B
66.354.240 B
66.391.696 B
36
Planeta: tabla 3
Tringulos dibujados
318.400
10.825.736 B
3.820.800 B
19.660 B
46.536 B
208 B
4.288 B
14.717.228 B
Pjaro: tabla 4
Tringulos dibujados
14
1088 B
0B
15.108 B
14.336 B
192 B
0B
30.724 B
Tringulos dibujados
1.944.002
66.572.544 B
23.328.024 B
23.720 B
33.992 B
464 B
335.229.192 B
425.187.936 B
37
Podemos ver que la ltima llamada es la que ms memoria consume y, por tanto, en la
que nos deberamos fijar si queremos disminuir el espacio a ocupar, no solo en
polgonos, como ya hemos mencionado anteriormente, sino tambin en el nmero de
texturas y su resolucin. En este caso los datos de entrada ocupan unos 400 MB, por lo
que en GPUs con poca memoria podra aparecer la necesidad de mover datos entre la
memoria grfica y la principal del sistema, con el consecuente tiempo adicional.
Otra posible opcin sera dividir la ltima en varias llamadas distintas, cada una ms
pequea que la original, puesto que hay objetos distintos. La pega de esta solucin es
que aade ms operaciones en la CPU, ya que hay cambiar ms veces de contexto, y
esto puede ser el cuello de botella de la aplicacin.
2. 4. 2. Equipos
Se han utilizado 4 equipos distintos para realizar las pruebas, los tres primeros de
sobremesa y uno ltimo porttil, que vamos a definir en funcin de su CPU, GPU y
memoria RAM, ya que son los componentes que ms pueden influir en los resultados.
En la tabla 6 tenemos las especificaciones de todos ellos.
Equipo 1
Equipo 2
Equipo 3
Equipo 4
Intel Core
i7-4770
Intel Core
i7-2600
AMD Phenom
II X4 955
Intel Core
i5-430M
Ncleos
Threads
Frecuencia
3,40 GHz
3,40 GHz
3,20 GHz
2,27 GHz
Cach L1
4 x 64 KB
4 x 64 KB
4 x 128 KB
2 x 64 KB
Cach L2
4x 256 KB
4x 256 KB
4 x 512 KB
2 x 256 KB
Cach L3
8 MB
8 MB
6 MB
3 MB
NVIDIA
GeForce GTX
660
NVIDIA
GeForce GTX
570
AMD
Radeon HD
6850
ATI Mobility
Radeon HD
5470
960
480
960
80
980 MHz
732-1464 MHz
grficos-shaders
775 MHz
750 MHz
Tamao VRAM
2 GB DDR5
1,25 GB DDR5
1 GB DDR5
512 MB DDR5
Ancho de banda
144,2 GB/s
152 GB/s
128 GB/s
24,6 GB/s
RAM
8 GB DDR3
6 GB DDR3
8 GB DDR3
4 GB DDR3
Ancho de banda
12.800 MB/s
12.800 MB/s
12.800 MB/s
8.500 MB/s
CPU
GPU
Ncleos
Frecuencia
38
2. 4. 3. Pruebas
Para realizar las pruebas van a recolectarse datos sobre el tiempo de inicio de la
aplicacin, con operaciones ejecutadas en la CPU, y de varios tiempos obtenidos de dos
vistas distintas de la escena, calculadas en la GPU. Para obtener los datos de la unidad
grfica usamos la interfaz Query de Direct3D 11, que permite obtener informacin
sobre el estado de la ejecucin de la tarjeta grfica [26].
Estos son los datos recogidos:
En todos los equipos se harn pruebas usando la CPU y la GPU en conjunto as como
con la CPU en solitario, ya que Direct3D permite que un procesador normal simule el
funcionamiento de una unidad grfica. Aunque es posible implementar nuestro propio
software de virtualizacin Microsoft ofrece uno en el propio SDK de DirectX, conocido
como Windows Advanced Rasterization Platform (WARP), que es el que usaremos [27].
En cuanto a las imgenes escogidas, se ha elegido una vista area del paisaje, que podra
encajar en una escena de una pelcula o un videojuego, y otra ms alejada donde se ven
todos los elementos pero donde tambin se observan los lmites del propio paisaje.
Cada vista est definida por los siguientes factores, que tambin se obtienen usando la
interfaz Query :
39
2. 4. 4. Tiempos de inicio
En la figura 29 puede verse el tiempo en segundos necesario para iniciar la aplicacin, o
lo que es lo mismo, crear todos los objetos necesarios durante la ejecucin de la
pipeline. Se presentan los resultados cuando el dispositivo a ejecutar los comandos
Direct3D es la GPU y cuando es la CPU.
41
42
43
2. 5. Integracin en UDK
Con objeto de demostrar que el uso de shaders es de inmediata aplicacin al mundo de
los videojuegos, parte del trabajo realizado se ha integrado en una escena creada con el
entorno de desarrollo del motor Unreal.
2. 5. 1. Ruido y materiales
Para usar nuestro ruido de Perlin debemos utilizar el editor de materiales, que usa una
red de nodos para crear cada material [28]. Este editor ofrece varios tipos de nodos,
cada uno con un cdigo HLSL asociado y que se van uniendo hasta formar el cdigo
final de los shaders [29]. Entre estos tipos de nodos existe uno que nos permite escribir
nuestras propias instrucciones en HLSL y que se combina con el resto de la misma
manera. Hay que tener en cuenta que este editor tiene sus particularidades y no es tan
44
simple como copiar y pegar desde nuestra aplicacin. Para empezar solo pueden
construirse vertex y pixel shaders, no es posible utilizar compute shaders. Esto nos
impide precalcular y guardar algunos datos, de manera que los clculos se repiten cada
pasada. Adems cada nodo personalizado solo puede contener una funcin, por lo que
las llamadas a otras funciones deben sustituirse por el cdigo entero o hacerlas en otros
nodos anteriores y propagar los resultados hacia delante. Tambin debemos mencionar
que el editor solo acepta texturas con tamaos que sean potencia de dos y que sigan el
formato clsico RGBA, por lo que cualquier otro tipo de textura debe ser adaptado.
Tras estas consideraciones pasamos a mostrar nuestra implementacin del ruido de
Perlin en 3 dimensiones. Aprovechando que el editor ofrece un recuento de las
instrucciones de cada material se ha hecho una versin que tiene los datos necesarios
para el clculo, permutacin y gradientes, como variables dentro del propio cdigo y
otra con ellos guardados en texturas. En la figura 33 se observan los resultados
obtenidos.
2. 5. 2. Escena
Tras la implementacin, para obtener cualquier fractal que queramos integrar en nuestra
escena solo hay que crear un material que sume varias octavas de ruido y aplicarlo a un
objeto. Como ejemplo se ha decidido usar el fractal del planeta aplicado a una bola del
mundo que va rotando y cuyo modelo se ha conseguido en internet 6, que se ha integrado
6
http://www.3delicious.net/
45
en un mapa ya existente y que viene con el motor: Epic Citadel, usado por Epic como
demo tcnica. El resultado final puede verse en la figura 34.
46
3. CONCLUSIONES
En este ltimo apartado de la memoria se analizan los resultados obtenidos y si se han
cumplido los objetivos, se indican posibles lneas de trabajo a seguir en el futuro y se
realiza una valoracin personal del PFC.
3. 1. Resultados obtenidos
Los objetivos marcados al inicio del proyecto se han conseguido. Hemos podido crear
un paisaje completo usando algoritmos fractales que utilizan ruido de Perlin. Esto nos
ha permitido comprender como se implementan y utilizan distintos tipos de ruido y el
potencial de algoritmos fractales para la generacin de elementos naturales.
Adems se han estudiado las caractersticas de Direct3D, tanto a nivel de grficos como
de clculo general, viendo as como se organiza la API, su flexibilidad y su relacin con
los elementos del hardware.
Los resultados obtenidos en el anlisis de rendimiento nos han ofrecido una visin de la
potencia de las unidades grficas y nos han permitido comprobar de primera mano por
qu su uso para clculo general ha cobrado fuerza y as lo sigue haciendo cada da que
pasa.
Tambin hemos conseguido implementar nuestro algoritmo de ruido dentro del entorno
de desarrollo del motor Unreal, demostrando que los conocimientos adquiridos pueden
adaptarse y aprovecharse en casi cualquier otro tipo de aplicacin, en este caso del
mundo de los videojuegos.
3. 2. Lneas futuras
Tras finalizar el proyecto surgen ideas sobre como se podra continuar trabajando en el
mismo mbito en el futuro.
Una de estas ideas es el uso de la pipeline de teselado, caracterstica nueva en Direct3D
11, en la generacin del paisaje. Ya que las tarjetas grficas modernas implementan la
divisin de polgonos por hardware podra ser interesante reducir la resolucin de la
malla a la hora de calcular los fractales, disminuyendo as el tiempo necesario, algo que
se notara especialmente en los objetos dinmicos como el agua, que deben calcularse
constantemente. Con la malla subdividida podramos aadir ms detalle usando algn
mapa de desplazamiento, que variara en funcin de la distancia y as poder ahorrar
espacio en la memoria de la GPU.
Tambin sera posible mejorar el rendimiento de los compute shader. En el caso del
clculo de las posiciones cada vrtice se trata de manera aislada y no hay posibilidad de
mejorar la comunicacin con los vecinos, ya que es inexistente, pero cuando calculamos
las normales podramos utilizar grupos de threads, que comparten un espacio en
memoria. Esto nos permitira calcular las normales de un tringulo y guardar la
47
3. 3. Valoracin personal
La realizacin de este proyecto me ha permitido aplicar muchos de los conocimientos
adquiridos a lo largo de estos 5 aos de carrera, suponiendo la culminacin de un largo e
importante periodo de mi vida, el cual me marcar durante los aos que estn por llegar.
Adems me ha otorgado la oportunidad de estudiar, comprender y trabajar con
herramientas que se usan en el mundo actual, concretamente con tecnologas que se
usan en el mundo de los videojuegos, donde espero poder trabajar. De especial utilidad
creo que van a ser los conocimientos adquiridos sobre Direct3D y, sobretodo, las
pipelines grfica y computacional, ya que es algo ms reciente y que cada vez se usa
ms, por lo que acabar la carrera habiendo usado stas puede suponer una diferenciacin
positiva de cara al futuro.
No obstante el hecho de que sean tecnologas propietarias tiene sus pegas. Aunque sean
las dominantes en la situacin actual del mercado y por eso es importante conocerlas y
saber usarlas, la comunidad de software libre, y en concreto la de OpenGL, suele ser
mucho ms participativa, por lo que es ms fcil encontrar documentacin y ayuda ante
los problemas. La parte positiva de esto es que hemos aprendido a manejarnos con la
documentacin de Microsoft, que, aunque sea ms escueta y en ocasiones parezca
escasa, es la oficial y por tanto la que se debera usar como referencia.
Finalmente, ha sido interesante ver el funcionamiento de un motor de videojuegos y
como sus componentes trabajan en conjunto para crear el producto final. Es una pena
que los kits de desarrollo de motores conocidos y potentes que se ofrecen de manera
gratuita no permitan acceder al cdigo del motor. Aunque es algo comprensible ya que
las compaas ponen muchos recursos en su desarrollo me hubiera gustado estudiar sus
partes internas con ms detalle.
48
4. BIBLIOGRAFA
[1] Unity License Comparisons
http://unity3d.com/unity/licenses
[2] CryEngine Overview
http://mycryengine.com/?conid=2
[3] Unreal Engine Features
http://www.unrealengine.com/en/features/
[4]: Jason Zink, Matt Petineo, Jack Hoxley (2011). Practical Rendering & Computation
with Direct3D 11. CRC Press
[5] The World's First Fractal Movie - "Vol Libre" 1979 - Loren Carpenter
http://www.liveleak.com/view?i=b75_1371314878
[6]: Benoit B. Mandelbrot (1982). The Fractal Geometry of Nature. W. H. Freeman and
Company
[7] The First Completely Computer-Generated (CGI) Cinematic Image Sequence in a
Feature Film
http://www.historyofinformation.com/expanded.php?id=3584
[8] Making Noise
http://www.noisemachine.com/talk1/
[9]: David S. Ebert, F. Kenton Musgrave, Darwyn Peachey, Ken Perlin, Steven Worley
(2002). Texturing & Modelling: A Procedural Approach. Third edition. Morgan
Kaufman Publishers
[10] The Perlin noise math FAQ
http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-mathfaq.html
[11] Procedural Noise Categories
http://physbam.stanford.edu/cs448x/old/Procedural_Noise%282f%29Categories.html
[12]: Matt Pharr, Randima Fernando, Tim Sweeney (2005). GPU Gems 2:
Programming Techniques for High-Performance Graphics and General-Purpose
Computation. Addison-Wesley Professional
[13] MSDN: Direct3D 11 Graphics
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476080(v=vs.85).aspx
[14] MDSN: HLSL
http://msdn.microsoft.com/en-us/library/windows/desktop/bb509561(v=vs.85).aspx
49
[15] Dark Secrets of Shader Development or What Your Mother Never Told You About
Shaders
http://developer.amd.com/wordpress/media/2012/10/Dark_Secrets_of_shader_DevMojo.pdf
[16] Scape 2: Procedural Basics
http://www.decarpentier.nl/scape-procedural-basics
[17] DirectX 11 Skybox
http://www.braynzarsoft.net/index.php?p=D3D11CUBEMAP
[18] Direct3D 11: Loading Static 3D models
http://www.braynzarsoft.net/index.php?p=D3D11OBJMODEL
[19] DirectX 10: Blending and Alpha Blending
http://takinginitiative.wordpress.com/2010/04/09/directx-10-tutorial-6-transparencyand-alpha-blending/
[20] Direct3D 11 Normal (Bump) Maps
http://www.braynzarsoft.net/index.php?p=D3D11NORMMAP
[21] DirectX10: Shadow Mapping
http://takinginitiative.wordpress.com/2011/05/15/directx10-tutorial-10-shadowmapping/
[22]: Randima Fernando, David Kirk (2004). GPU Gems: Programming Techniques,
Tips and Tricks for Real-Time Graphics. Addison-Wesley Professional
[23] MSDN: XAudio2 APIs
http://msdn.microsoft.com/en-us/library/hh405049(v=vs.85).aspx
[24] Procedural Shape Synthesis on Subdivision Surfaces
http://lvelho.impa.br/spd/spd.pdf
[25] Beautiful, Yet Friendly Part 1: Stop Hitting the Bottleneck
http://www.ericchadwick.com/examples/provost/byf1.html
[26] MSDN: ID3DQuery interface
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476578(v=vs.85).aspx
[27] MSDN: Windows Advanced Rasterization Platform (WARP) Guide
http://msdn.microsoft.com/en-us/library/windows/desktop/gg615082(v=vs.85).aspx
[28] Material Editor User Guide
http://udn.epicgames.com/Three/MaterialEditorUserGuide.html
[29] Materials Compendium
http://udn.epicgames.com/Three/MaterialsCompendium.html
50
II ANEXOS
A. 1. Planificacin
El desarrollo se ha dividido en 5 fases distintas. La primera ha sido el estudio de las
herramientas y tcnicas que bamos a usar.
El siguiente paso ha sido implementar la creacin del paisaje fractal usando C++ y el
entorno de desarrollo Visual Studio 2013. Se ha seguido un desarrollo iterativo e
incremental que ha permitido partir de una idea bsica de lo que queramos hacer, el
paisaje, para ir refinando el objetivo conforme avanzbamos y aadamos
caractersticas. Adems de esta manera podemos modificar los elementos ya existentes
conforme agregamos nuevos. El lmite de los detalles adicionales implementados viene
marcado por el tiempo disponible, ya que tambin debamos finalizar el resto del
proyecto antes de la fecha lmite marcada y podramos haber seguido aadiendo ms
elementos a la escena.
Posteriormente se ha estudiado el desempeo de la aplicacin en la CPU y la GPU,
analizando el rendimiento en ambos casos.
A continuacin se ha implementado el ruido de Perlin en el entorno UDK para poder
crear un fractal. Tambin hemos seguido un desarrollo iterativo e incremental, aunque
con pocas iteraciones y ms cortas que en la creacin de la escena principal.
Por ltimo se ha escrito la memoria y preparado la presentacin del proyecto.
En la tabla 7 pueden verse las distintas tareas planificadas, su duracin y el tiempo en
horas dedicado para su finalizacin.
Descripcin
Fecha inicio
Fecha fin
Dedicacin (h)
Estudio de tcnicas y
herramientas
1/09/2013
8/10/2013
100
Creacin de la escena
9/10/2013
16/02/2014
195
Anlisis de rendimiento
3/02/2014
10/02/2014
35
Integracin en UDK
24/01/2014
5/02/2014
30
1/10/2013
19/02/2014
90
Preparar presentacin
21/02/2014
10/03/2014
30
Total
1/09/2013
10/03/2014
480
Tabla 7: Dedicacin
55
A. 2. Herramientas utilizadas
A continuacin, en la tabla 8, se indican las herramientas utilizadas en el desarrollo del
proyecto junto con una breve descripcin.
Herramienta
Descripcin
Sistema Operativo
Windows 7
Windows 8
Unreal Development Kit (Julio 2013) Entorno de desarrollo del motor Unreal para
integrar el ruido en una escena.
DirectX SDK (Junio 2010)
CrazyBump 1.2
Paint
Edicin de imgenes.
Gestin
Google Drive
Anlisis de rendimiento.
Creacin de imgenes
DoxyGen 1.8.6
Documentacin de la aplicacin.
Otros
FRAPS 3.5.99
B. 1. Herramientas disponibles
En este apartado se van a comparar las distintas herramientas que ofrecen los motores y
sus diferentes caractersticas. Para ello stas sern listadas y se presentar una tabla que
permite hacer la comparacin de manera rpida y sencilla.
B. 1. 1. Animacin
1.
2.
3.
4.
5.
6.
7.
8.
Caracterstica
UDK
CryEngine 3
Unity
57
B. 1 . 2. Audio
1.
2.
3.
4.
5.
6.
Caracterstica
UDK
CryEngine 3
Unity
Hasta 5.1
Hasta 7.1
Hasta 7.1
B. 1. 3. Cinemticas
1.
2.
3.
4.
Caracterstica
UDK
CryEngine 3
Unity
B. 1 . 4. Networking
1. Soporte para conexin LAN e Internet.
2. Modelo cliente-servidor.
3. Descarga y cach de contenidos automticas.
Caracterstica
UDK
CryEngine 3
Unity
58
B. 1. 5. Editor
1.
2.
3.
4.
Caracterstica
UDK
CryEngine 3
Unity
B. 1. 6. Fsicas
1.
2.
3.
4.
5.
6.
7.
8.
Caracterstica
UDK
CryEngine 3
Unity
59
B. 1. 7. Iluminacin
1.
2.
3.
4.
5.
6.
7.
8.
9.
Iluminacin global.
Ambient occlusion.
Iluminacin per-pixel.
Luces dinmicas.
Luces precalculadas.
Reflejos en tiempo real.
Sombras dinmicas.
Sombras precalculadas.
Deferred Lighting.
Caracterstica
UDK
CryEngine 3
Unity
B. 1. 8. Inteligencia artificial
1.
2.
3.
4.
Grafos de navegacin.
Generacin automtica de caminos.
Bsqueda de caminos.
Obstculos y restricciones.
Caracterstica
UDK
CryEngine 3
Unity
60
B. 1. 9. Programacin
1. Lenguaje de programacin usado.
2. Paradigma.
3. Acceso al cdigo del motor.
4. Atributos especficos de las clases para juegos.
5. Sensible a maysculas.
6. Herencia.
7. Manejo de excepciones.
8. Sobrecarga de funciones.
9. Sobrescritura de funciones.
10. Sobrecarga de operadores.
11. Sobrescritura de operadores.
12. Recolector de basura y creacin/destruccin de objetos de manera automtica
13. Comprobacin de tipos.
Caracterstica
UDK
CryEngine 3
Unity
UnrealScript
C++ ( y Lua)
C # (Javascript y
Boo)
Orientado a objetos
Orientado a objetos
Orientado a objetos
Indirecto
Indirecto
Indirecto
Estados, tiempo y
red
Simple
Simple y mltiple
Simple
10
11
12
13
61
B. 1. 10. Renderizado
1. Direct3D.
2. OpenGL.
3. HDR de 64-bit.
4. Modelo de iluminacin.
5. Teselado.
6. Correccin gamma.
7. Normal mapping.
8. Depth of field.
9. Filtros anisotrpicos.
10. Desplazamientos.
11. Atenuacin.
12. Niebla.
13. Texturas.
14. Efectos de post-procesado.
15. Distintos niveles de detalle.
Caracterstica
UDK
CryEngine 3
Unity
9 y 11
9, 10 y 11
9 y 11
Phong
Phong
Phong / Gouraud
10
11
12
13
14
15
62
Editor de materiales.
Factores bsicos.
Funciones para combinar shaders.
Texturas.
Subsurface Scattering.
Creacin automtica de shaders en funcin de la plataforma.
Custom shaders.
Anti-aliasing.
Caracterstica
UDK
CryEngine 3
Unity
Grfico (nodos)
Grfico (rbol)
Cdigo
Difuso, especular,
emisor y opacidad
Difuso, especular,
brillo, emisor y
opacidad
Difuso, especular,
emisor, brillo y
transparencia
Suma
HLSL
HLSL, GLSL y CG
B. 1. 12. Terreno
1.
2.
3.
4.
5.
6.
Caracterstica
UDK
CryEngine 3
Unity
63
B. 1. 13. Otros
1.
2.
3.
4.
5.
6.
7.
Caracterstica
UDK
CryEngine 3
Unity
Windows y IOs
Windows, Linux,
Mac, Web player,
Xbox 360, PS3,
WiiU, IOs y Android
B. 2. Imgenes comparativas
A continuacin, en las figuras 35 - 46, se presentan algunas imgenes de juegos
comerciales o demostraciones tcnicas creadas con los motores comparados para as
poder comprobar la calidad grfica que se puede obtener con ellos y ver en
funcionamiento las caractersticas comentadas.
64
65
66
B. 2. 2. CryEngine 3
67
68
B. 2. 3. Unity
69
70
C. 1. Etapas
En la figura 47 podemos observar la pipeline grfica de Direct3D 11, siendo las etapas
enmarcadas en rectngulos las programables y donde, por tanto, podemos ejecutar
nuestro propio cdigo. Las otras, aunque ms o menos configurables, harn siempre las
mismas operaciones y por ello ofrecen una flexibilidad ms limitada.
C. 1. 1. Input Assembler
La primera etapa es la encargada de construir los vrtices que se utilizarn en el resto de
la pipeline, as como de las uniones entre ellos.
71
C. 1. 4. Tesselator
Crea una serie de coordenadas en funcin de la configuracin que hayamos indicado en
el paso previo, independientemente de la posicin o cualquier otro atributo de los puntos
de control.
C. 1. 7. Stream Output
El nico objetivo de esta etapa es guardar el resultado obtenido hasta ahora en un buffer
externo para su futuro uso o inspeccin. Realmente la etapa no realiza ningn tipo de
operacin puesto que la copia se hace durante la anterior, el geometry shader o el vertex
shader si el primero est desactivado.
C. 1. 8. Rasterizer
En esta etapa la geometra se convierte a un formato adecuado para poder ser presentado
en pantalla, es decir, los tringulos se convierten en pxeles. Aqu tambin se elimina la
parte de la escena que no debe ser mostrada en pantalla en funcin del tamao de la
cmara, su posicin o qu parte de los objetos no se vern por no mirar a sta.
C. 2. HLSL
High Level Shading Language, HLSL, es un lenguaje derivado de C++ pero con una
serie de caractersticas particulares para la programacin de tarjetas grficas, como el
soporte para vectores o matrices y la inclusin de operaciones tpicas con ellos, aunque
carece de otras como el uso de punteros o la reserva dinmica de memoria.
72
73
D. 1. Etapas
La pipeline de clculo consta de una sola etapa, el Compute Shader, que se ejecuta de
manera totalmente separada de la pipeline grfica tradicional. Este shader debe
escribirse en HLSL, como cualquier otro, y ser el encargado de ejecutar el algoritmo
que queramos implementar en la GPU.
D. 2. Caractersticas
Para comprender como podemos utilizar la GPU para la ejecucin de un algoritmo de
tipo general y aprovechar su potencia es necesario comentar algunas de sus
particularidades.
D. 2. 1. Modelo de threading
El trabajo a ejecutar en la GPU se divide en grupos de threads. stos se distribuyen en
un array de 3 dimensiones comprendidas entre 1 y 64K, teniendo cada uno un ndice
para ser identificado. A su vez cada grupo est formado por varios threads, con su
propio identificador, distribuidos en otro array de 3 dimensiones comprendidas entre 1
y 64, siendo 1024 el nmero mximo de threads a ejecutar en cada grupo. Esta
disposicin se puede observar en la figura 48.
Ya que cada thread ejecutar el mismo shader es necesario que cada uno acte sobre
unos datos distintos. Tambin en la figura 48 es fcil ver la importancia de organizar
nuestros threads para aprovechar las caractersticas del algoritmo y como se van a
dividir los datos.
Para ello disponemos de los ndices mencionados anteriormente, tanto el de grupo como
el de thread dentro de grupo, as como la posicin global del thread y la posibilidad de
identificar a qu grupo pertenece. Estos ndices contendrn la posicin del grupo o el
thread en los 3 ejes, as que con toda esta informacin podemos acceder sin problemas a
la porcin de los datos que necesitemos.
Por supuesto el nmero de shaders que se ejecutarn realmente en paralelo depender
del hardware empleado, pero siempre hay que tratar de ajustar al mximo las
propiedades del problema a la organizacin de los threads.
75
D. 2. 2. Memoria
Como en cualquier otro shader es posible acceder a los recursos guardados en distintos
buffers y texturas, que estarn dentro la memoria de la GPU, si es posible, o en memoria
externa si no caben. Todos los threads tendrn acceso a los mismos recursos, ya sean
lecturas o escrituras, por ello habr que sincronizarlos, como se comenta en el siguiente
apartado.
Adems todos los threads del mismo grupo pueden compartir hasta 32 KB de memoria
dentro de la disponible en la GPU. Esta memoria, llamada Group Shared Memory
(GSM), tambin debe ser sincronizada para evitar conflictos y es la manera ms rpida
de compartir informacin entre threads.
D. 2. 3. Sincronizacin
Podemos evitar los problemas de sincronizacin en ambos tipos de memoria de varias
maneras, siendo la ms sencilla la que ya hemos comentado, que cada thread trabaje con
una parte distinta de los datos.
Tambin podemos utilizar barreras para sincronizar los accesos a memoria de un mismo
grupo. Es posible sincronizar la memoria de grupo, la externa o ambas a la vez. Adems
en los 3 casos se pueden utilizar 2 tipos de barreras distintos. El primero espera a que
todas las escrituras pendientes en ese momento acaben antes de seguir, puesto que hay
un lapso de tiempo desde que la instruccin se ejecuta en el shader y ste es realmente
realizado a nivel hardware. El segundo tipo, adems de garantizar lo anterior, espera a
que todos los threads del grupo lleguen a la llamada a la funcin de barrera.
76
Finalmente, es posible utilizar varias funciones atmicas disponibles que garantizan que
su ejecucin se completa antes de que cualquier otra operacin se vaya a realizar sobre
los mismos datos.
Tambin debemos comentar que aunque todas estas maneras de sincronizacin son
tiles solo la primera es deseable, ya que es la nica que nos evita tener tiempos ociosos
en la GPU y por tanto aprovecha al mximo sus capacidades.
77
E. 1. Contexto
E. 1. 1. Contexto tecnolgico
La simulacin y renderizado en tiempo real de fluidos, en este caso agua, suele ser uno
de los aspectos ms costosos de una escena. Es debido a esta complejidad que puede ser
beneficioso usar la potencia de una GPU para realizar los clculos.
Hacer una representacin fsicamente perfecta es algo imposible para el hardware
actual, pero no es necesaria para conseguir una aproximacin que sea eficiente y
visualmente capaz de dar la impresin adecuada. En nuestro caso el agua est formada
por millones de molculas pero solo nos interesa ver el comportamiento de la superficie
para poder renderizarla. Tambin podemos acotar el nmero de partculas reduciendo
todo a una red cuadriculada de columnas de agua, cuya altura ser la de la superficie.
E. 1. 2. Base matemtica
Usando estas columnas es posible que el agua fluya de unas a otras si consideramos que
las vecinas estn conectadas por tuberas virtuales situadas al pie de cada columna. Para
calcular este flujo necesitamos saber la presin Pij ejercida en el fondo de cada
columna, la cual podemos hallar con la altura Hij de sta, la densidad del agua d, la
gravedad g y la presin atmosfrica p.
Pij=Hijdg+ p
c( H ij H kl )
m
79
V ij = t (
kl nij
t + t
Qij kl +Qij kl
)
2
V ij
Aij
E. 2. Diseo
E. 2. 1. Datos
Viendo las consideraciones anteriores llegamos a la conclusin de que para cada
columna debemos mantener dos tipos de informacin: su altura y el flujo de las tuberas.
Como cada columna tiene 8 conexiones pero hay informacin compartida nos basta con
utilizar 4 datos, la tubera de la derecha y las de abajo, como se muestra en la figura 49.
E. 2. 2. Threading
Observando la figura 49 es fcil pensar que cada columna puede asociarse con un
thread, que a su vez sern organizados en grupos cuadrados, en este caso de dimensin
16x16. Puesto que los threads vecinos comparten informacin es posible usar la
memoria compartida de grupo para almacenar estos datos y mejorar el acceso a ellos. El
problema aparece en los threads del borde del grupo, que deben comunicarse con otros
que estn fuera del grupo y, por tanto, fuera de la memoria compartida.
Para evitar tener que escribir y leer todos los datos en la memoria de la GPU en cada
pasada aadimos una fila al permetro del grupo, quedando 18x18, que se solapa con los
grupos adyacentes. Estos threads cargarn las alturas correspondientes y realizarn los
clculos de flujo, que si podrn ser guardados en memoria de grupo, pero no
actualizarn el estado de la simulacin, ya que de eso se encargarn los threads
correspondientes de los grupos vecinos. En resumen, para evitar tener que hacer ms
accesos a memoria lenta repetimos algunos clculos en distintos grupos, que suponen
una penalizacin menor.
80
E. 3. Aplicacin
Con la teora y el diseo en mente solo queda la implementacin. Para empezar,
analizaremos la aplicacin. La original utilizada en el ejemplo del libro usa una serie de
libreras creadas por los autores que no permiten ver las llamadas a Direct3D
claramente, por ello se ha escrito una nueva donde se pueden apreciar.
// Incluimos los archivos necesarios
#include <windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <directxmath.h>
// Incluimos las librerias necesarias
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dcompiler.lib")
using namespace DirectX;
// Variables globales
HWND hWnd;
//
D3D11_VIEWPORT viewport;
//
IDXGISwapChain *swapchain = NULL;
//
ID3D11Device *dev = NULL;
//
ID3D11DeviceContext *devcon = NULL;
//
ID3D11RenderTargetView *rtv = NULL;
//
ID3D11VertexShader *pVS = NULL;
//
ID3D11PixelShader *pPS = NULL;
//
ID3D11ComputeShader *pCS = NULL;
//
ID3D11Buffer *pVBuffer = NULL;
//
ID3D11Buffer *pIBuffer = NULL;
//
ID3D11InputLayout *pLayout = NULL;
//
ID3D11RasterizerState *pRState=NULL;
//
rasterizado
ID3D11Buffer *pCBufferMat = NULL;
//
transformacion
ID3D11Buffer *pCBufferDis = NULL;
//
utilizados
ID3D11Buffer *pCBufferDisTime = NULL;
//
tiempo
ID3D11Buffer *pWaterSim1 = NULL;
//
actual de la simulacin
ID3D11Buffer *pWaterSim2 = NULL;
//
estado de la simulacin
ID3D11ShaderResourceView *pSRVWater= NULL; //
la simulacin
ID3D11UnorderedAccessView *pUAVWater= NULL;//
informacin de la simulacin
int numVertices = 0;
//
int numIndices = 0;
//
XMMATRIX myWorld;
//
XMMATRIX myView;
//
XMMATRIX myProjection;
//
int ThreadGroupsX = 16;
//
int ThreadGroupsY = 16;
//
const int DispatchSizeX = 16;
//
const int DispatchSizeZ = 16;
//
int SizeX= ThreadGroupsX*DispatchSizeX;
//
81
Controlador de la ventana
Vista
Swap chain
Direct3D device interface
Direct3D device context
Render Target View
Vertex Shader
Pixel Shader
Compute Shader
Buffer de los vrtices
Buffer de ndices
Formato de entrada a la pipeline
Configuracin de la etapa de
Constant buffer de las matrices de
Buffer con la info de threads
Buffer con la info de threads y de
Buffer para guardar el estado
Buffer para guardar el prximo
Vista para leer la informacin de
Vista para leer/escribir la
Nmero de vertices a dibujar
Nmero de indices
Matriz del mundo
Matriz de la vista
Matriz de proyeccin
Nmero de thread groups, x
Nmero de thread groups, y
Nmero de threads por grupo, x
Numeo de threads por grupo, Z
Nmero de vrtices en X
// Nmero de vrtices en Z
// Tiempo transcurrido desde la ltima
// Frecuencia de la CPU, usada para
// Estructuras a usar
// Vrtice
struct VERTEX {
float x, y, z; // Posicin
};
// Informacin de un punto de la simulacin
struct GridPoint
{
float height;
float flow[4];
};
// Buffer constante de las matrices de transformacin
struct ConstantBufferMatrix
{
XMMATRIX World;
XMMATRIX View;
XMMATRIX Projection;
};
// Buffer constante con la informacin de threads
struct ConstantBufferDis
{
float DispatchSize[4];
};
// Buffer constante con al informacin de threads y tiempo
struct ConstantBufferDisTime
{
float TimeFactor;
float padding[3]; // Los buffers constantes deben estar alineados a 16bytes,
as que rellenamos
float DispatchSize[4];
};
// Declaracin de las funciones a usar
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void InitPipeline();
void InitScene();
void InitSim();
void InitCamera();
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam);
void Calculate();
void Render();
void CleanD3D();
// Punto de entrada a la aplicacin
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{
82
// Creacin de la ventana
if( FAILED (InitWindow(hInstance,nCmdShow)) )
return 0;
// Creacin del dispositivo y swap chain
if( FAILED (InitDevice()) )
return 0;
// Inicializar la pipeline
InitPipeline();
// Inicializar la escena
InitScene();
// Iniciar la simulacin
InitSim();
// Inicializar la cmara
InitCamera();
// Inicio de la informacin del timer
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&tiempo);
// Bucle principal
MSG msg; // Mensaje de los eventos de Windows
while(TRUE)
{
// Comprobar si hay mensajes esperando
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// Traducir al formato de Windows
TranslateMessage(&msg);
// Mandar mensaje a WindowProc para procesarlo
DispatchMessage(&msg);
83
Tamao de la clase
Estilo
Puntero al controlador de
Instancia de la aplicacin
Cursor
Color del fondo
Nombre de la clase
// Registramos la clase
if (! RegisterClassEx(&ventana))
return E_FAIL;
// Creamos una ventana y obtenemos el controlador
RECT wr = {0, 0, 800, 600}; // Indicamos el tamao de la zona de la ventana
disponible para nuestra aplicacin
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); // Obtenemos el tamao
completo de la ventana
hWnd = CreateWindowEx(NULL, // Estilo
L"ClaseVentana",
L"Agua-Columnas",
WS_OVERLAPPEDWINDOW,
100,
100,
wr.right - wr.left,
wr.bottom- wr.top,
NULL,
NULL,
hInstance,
con la ventana
NULL);
//
//
//
//
//
//
//
//
//
//
if (!hWnd)
return E_FAIL;
// Mostrar ventana por pantalla
ShowWindow(hWnd, nCmdShow);
return S_OK;
}
// Funcin para crear el dispositivo y la swapchain
HRESULT InitDevice()
{
// Informacin de la swap chain
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
la pipeline
scd.OutputWindow = hWnd;
scd.SampleDesc.Count = 1;
scd.Windowed = TRUE;
completa
84
// 1 back buffer
// Usar colores de 32 bit
// Modo de uso: salida de
// Ventana a usar
// Multisamples
// Modo ventana/!pantalla
Adaptador grfico a
Tipo de driver a usar
Puntero al cdigo del
Flags de
Feature levels.
hardware
Nmero de feature
Versin de DirectX
Info de la swap chain
Swap chain
Device
Mximo feature level
Device context
85
// Configuramos el rasterizado
D3D11_RASTERIZER_DESC rs;
ZeroMemory(&rs, sizeof(rs));
rs.FillMode = D3D11_FILL_WIREFRAME; // Modo malla
rs.CullMode = D3D11_CULL_BACK; // No mostrar las caras traseras
dev->CreateRasterizerState( &rs, &pRState);
86
// Generar ndices
for ( int j = 0; j < SizeZ-1; j++ )
{
for ( int i = 0; i < SizeX-1; i++ )
{
indices[j*6*(SizeX-1)+i*6] = j*SizeX + i;
indices[j*6*(SizeX-1)+i*6+1] = (j*SizeX + i) + SizeX;
indices[j*6*(SizeX-1)+i*6+2] = (j*SizeX + i) + 1;
indices[j*6*(SizeX-1)+i*6+3] = (j*SizeX + i) + 1;
indices[j*6*(SizeX-1)+i*6+4] = (j*SizeX + i) + SizeX;
indices[j*6*(SizeX-1)+i*6+5] = (j*SizeX + i) + SizeX + 1;
}
// Crear el index buffer
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( WORD ) * numIndices; // Tamao
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
InitData.pSysMem = indices; // Datos iniciales
dev->CreateBuffer( &bd, &InitData, &pIBuffer ); // Crear el buffer
}
// Funcin para inicializar la simulacin
void InitSim()
{
// Creamos datos iniciales para la simulacin
GridPoint* pData;
pData = new GridPoint[numVertices];
for (int j = 0; j <
{
for (int i = 0;
{
int x = i int y = j -
SizeZ; j++)
i < SizeX; i++)
32;
96;
87
}
// Datos iniciales
D3D11_SUBRESOURCE_DATA InitialData;
InitialData.pSysMem = pData;
// Creamos los buffer que contendrn el estado de la simulacin
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.ByteWidth = numVertices*sizeof(GridPoint);
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
bd.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
bd.StructureByteStride = sizeof(GridPoint);
bd.Usage = D3D11_USAGE_DEFAULT;
bd.CPUAccessFlags = 0;
dev->CreateBuffer(&bd, &InitialData, &pWaterSim1);
dev->CreateBuffer(&bd, &InitialData, &pWaterSim2);
// Ya no necesitamos la memoria de la CPU, pues la simulacin es manejada por
la GPU
delete[] pData;
// Crear el constant buffer con la info de los threads usados
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBufferDis);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
dev->CreateBuffer(&bd, NULL, &pCBufferDis);
// Actualizar los datos del buffer
ConstantBufferDis cd;
cd.DispatchSize[0] = float(DispatchSizeX);
cd.DispatchSize[1] = float(DispatchSizeZ);
cd.DispatchSize[2] = float(DispatchSizeX*ThreadGroupsX);
cd.DispatchSize[3] = float(DispatchSizeZ*ThreadGroupsY);
devcon->UpdateSubresource(pCBufferDis, 0, NULL, &cd, 0, 0);
88
// Actualizar buffer
ConstantBufferMatrix cb;
cb.World = XMMatrixTranspose(myWorld);
cb.View = XMMatrixTranspose(myView);
cb.Projection = XMMatrixTranspose(myProjection);
devcon->UpdateSubresource(pCBufferMat, 0, NULL, &cb, 0, 0);
89
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
desc.Buffer.ElementOffset = 0;
desc.Buffer.NumElements = numVertices;
dev->CreateShaderResourceView(pWaterSim1, &desc, &pSRVWater);
devcon->CSSetShaderResources(0, 1, &pSRVWater);
// Creamos la unordered access view para poder escribir los gridpoints desde
la pipeline
D3D11_UNORDERED_ACCESS_VIEW_DESC uesc;
uesc.Format = DXGI_FORMAT_UNKNOWN;
uesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uesc.Buffer.FirstElement = 0;
uesc.Buffer.NumElements = numVertices;
uesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_COUNTER;
dev->CreateUnorderedAccessView(pWaterSim2, &uesc, &pUAVWater);
devcon->CSSetUnorderedAccessViews(0, 1, &pUAVWater, 0);
// Actualizar variables
ConstantBufferDisTime cb;
cb.TimeFactor = paso / freq.QuadPart;
cb.DispatchSize[0] = float(DispatchSizeX);
cb.DispatchSize[1] = float(DispatchSizeZ);
cb.DispatchSize[2] = float(SizeX);
cb.DispatchSize[3] = float(SizeZ);
devcon->UpdateSubresource(pCBufferDisTime, 0, NULL, &cb, 0, 0);
// Simular en la GPU
devcon->Dispatch(ThreadGroupsX, ThreadGroupsY, 1);
// Intercambiar buffers
ID3D11Buffer *Temp = pWaterSim1;
pWaterSim1 = pWaterSim2;
pWaterSim2 = Temp;
}
Temp->Release();
90
E. 4. Shader de clculo
El clculo de la simulacin se hace en un compute shader utilizando las ideas
introducidas en los apartados de contexto y diseo. A partir de la diferencia de alturas
entre columnas, que tenemos disponibles, se calcularn las diferencias de presin,
aceleracin y nuevo flujo, que es lo que se necesita para modificar la altura de cada
columna.
91
// Estructuras usadas
// Estado de una columna de la simulacion
struct GridPoint
{
float Height;
float4 Flow;
};
// Buffers usados
// Buffer constante con la informacion de tiempo de la simulacion y threads
usados
cbuffer TimeParameters
{
float TimeFactor;
float4 DispatchSize;
};
// Estados de la simulacion, el actual y el nuevo a calcular
RWStructuredBuffer<GridPoint> NewWaterState
: register( u0 );
StructuredBuffer<GridPoint>
CurrentWaterState : register( t0 );
// Datos a usar
// Tamao de la simulacion
#define size_x 16
#define size_y 16
// Tamao de grupo con perimetro extra
#define padded_x (1 + size_x + 1)
#define padded_y (1 + size_y + 1)
// Memoria de grupo para compartir informacion
groupshared GridPoint loadedpoints[padded_x * padded_y];
// Numero de threads por grupo
[numthreads(padded_x, padded_y, 1)]
// Compute shader
void CSMAIN( uint3 GroupID : SV_GroupID, uint3 DispatchThreadID :
SV_DispatchThreadID, uint3 GroupThreadID : SV_GroupThreadID, uint GroupIndex :
SV_GroupIndex )
{
// Tamao de una rejilla (vista)
int gridsize_x = DispatchSize.x;
int gridsize_y = DispatchSize.y;
// Tamao total del mapa de alturas
int totalsize_x = DispatchSize.z;
int totalsize_y = DispatchSize.w;
// Hacemos todos los accesos a la memoria con el estado de la simulacion
actual para guardarlos en la memoria compartida
// Datos iniciales a 0
loadedpoints[GroupIndex].Height = 0.0f;
loadedpoints[GroupIndex].Flow = float4( 0.0f, 0.0f, 0.0f, 0.0f );
// Calcular la posicion dentro del buffer usando los IDs del thread
int3 location = int3( 0, 0, 0 );
location.x = GroupID.x * size_x + ( GroupThreadID.x - 1 );
location.y = GroupID.y * size_y + ( GroupThreadID.y - 1 );
92
93
E. 5. Shaders de renderizado
El renderizado de la superficie obtenida es sencillo y solo utiliza un vertex y un pixel
shader. El vertex shader transforma la posicin del vrtice, cuya altura obtendr de los
clculos previamente realizados, y elige un color en funcin del grupo de threads donde
se ha realizado la simulacin. El pixel shader simplemente usa este color como color
definitivo.
// Estructuras usadas
// Entrada al vertex shader
struct VS_INPUT
{
float3 position : POSITION; // Posicon del vertice
};
94
95
E. 6. Resultados
El resultado final puede verse en la figura 50
96
F. 1. Ruido
En nuestro mbito el ruido es una funcin que vara de manera aparentemente aleatoria.
Decimos que es aparente porque aunque no se observe ninguna pauta la funcin debe
ser repetible. Esta aleatoriedad se usa para evitar la aparicin de patrones que, aunque s
existen, no llegan a ser apreciables. Adems el rango de salida de la funcin debe ser
conocido y su ancho de banda limitado.
El ruido se usa habitualmente para generar objetos naturales como agua, montaas o
nubes, ya sea para la construccin de su forma o para la de las texturas que se aplicarn
a su superficie.
F. 2. Tipos de ruido
A continuacin se hace una breve diferenciacin de algunos de los tipos de ruido ms
usados.
F. 2. 1. Ruido de rejilla
Uno de los tipos de ruido ms sencillo y eficiente. Se define una malla para cada punto
de nuestro espacio cuyas coordenadas son enteras y se le asigna un nmero
pseudoaleatorio, normalmente con una permutacin aleatoria previamente calculada de
nmeros enteros en el rango deseado. Para obtener el valor en cualquier punto solo hay
que interpolar entre los puntos de la rejilla que lo rodean. Dependiendo del mtodo
usado para interpolar y del nmero de vecinos utilizados se conseguirn unos resultados
u otros.
F. 2. 2. Ruido de valores
Similar al anterior, en este caso el valor de cada punto de la malla es un nmero
aleatorio entre -1 y 1.
F. 2. 3. Ruido de gradientes
En este caso tenemos tambin una permutacin de nmeros enteros, pero esta vez se usa
para asignar a cada punto de la malla un gradiente pseudoaletorio. Estos gradientes son
generados usando vectores unitarios distribuidos de manera aleatoria en la esfera
unidad. Para calcular el ruido en un punto se usan los puntos de la celda en que se
encuentra, obteniendo el producto escalar del gradiente por el vector que va desde cada
punto de la celda de la rejilla al propio punto e interpolando.
97
F. 2. 4. Ruido de Perlin
Tipo particular del ruido anterior que usa gradientes fijos ya que la permutacin de
enteros ya otorga suficiente aleatoriedad. En cuanto a la funcin usada para interpolar,
esta era originalmente 3t2 2t3 pero la segunda derivada de sta no es 0 ni en t=1 ni en
t=0, por lo que el propio Perlin decidi ms adelante cambiar y usar 6t5 15t4 + 10t3.
F. 2. 5. Ruido de valores-gradientes
El ruido de gradientes es siempre 0 para las coordenadas enteras, por lo que es posible
que aparezca algn patrn. Para tratar de evitarlo el ruido de valores gradientes hace
una suma ponderada de un ruido de valores y un ruido de gradientes.
F. 2. 8. Ruidos explcitos
En los ruidos explcitos el valor del ruido se precalcula antes y se guarda, de manera que
a la hora de utilizarlos solo hay que buscar el valor en una tabla, textura o cualquier
lugar donde est almacenado. Esto disminuye el tiempo necesario para obtener el ruido,
pero limita la flexibilidad.
F. 3. Fractales
Un fractal es un patrn que se repite a diferentes escalas y que se utiliza para obtener la
forma de un objeto irregular que no se podra conseguir con los mtodos de la geometra
clsica. Si a su construccin aadimos algn tipo de aleatoriedad tenemos un fractal
aleatorio.
En nuestro caso el patrn viene marcado por una funcin de ruido sumada a distintas
frecuencias y con diferentes escalas.
Una de las funciones fractales aleatorias ms sencillas y utilizadas es la conocida como
fBm, fractal brownian motion, definida por los siguientes parmetros:
98
En este caso el patrn viene marcado directamente por el valor del ruido, pero podran
usarse funciones ms complejas como senos o polinomios.
En las figuras 51, 52 y 53 se presentan imgenes de MojoWorlds, mundos enteramente
construidos usando fractales y ruido, para comprobar la potencia de estas tcnicas.
99
100
ANEXO G: DOCUMENTACIN DE LA
APLICACIN
A continuacin se presenta la documentacin referente a la aplicacin implementada
para la generacin del paisaje procedural. La documentacin se ha generado de manera
automtica usando el programa DoxyGen.
G. 1. Lista de clases
AudioEngine (Motor de audio )
Camera (Una camara )
Camera::ConstantBufferCam (Buffer con la posicion de la camara )
Camera::ConstantBufferMatrix (Buffer con las matrices de la camara )
Cielo (Cielo de la escena )
D3D11Manager (Controlador de Direct3D 11 )
Datos (Clase con varios datos necesarios )
Datos::ConstantBufferDatos (Buffer con datos para los shaders )
GPUProfiler (Profiler de la ejecucion de la GPU )
Light (Luz )
Light::ConstantBufferLight (Buffer con los datos de una luz )
ObjManager (Manejo de archivos .obj )
Paisaje (Paisaje de la escena )
Pajaros (Controlador de los pajaros )
Pajaros::InfoPajaro (Informacion de un pajaro )
Perlin (Datos del ruido de Perlin )
Planeta (Planeta fractal )
SamplerManager (Clase para el manejo de samplers de texturas
SceneManager (Controlador de la escena )
Shadow (Sombras )
Shadow::ConstantBufferMatrixShadow (Buffer con las matrices de la camara-luz )
TextureManager (Manejo de texturas externas )
VERTEX (Vertice )
WaveLoader (Cargador de archivos .wav )
G. 2. Documentacin de clases
AudioEngine Class Reference
Motor de audio.
2. void LoadSounds ()
Cargar los sonidos.
3. void Play ()
Iniciar reproduccion de sonidos.
101
4. void Clean ()
Liberar recursos.
Public Attributes
1. IXAudio2 * audioeng
Motor de audio.
2. IXAudio2MasteringVoice * audiodev
Audio device.
Classes
1. struct ConstantBufferCam
Buffer con la posicion de la camara.
1. struct ConstantBufferMatrix
Buffer con las matrices de la camara.
2. void IniciarPaseoAereo ()
Iniciar paseo Aereo.
3. void IniciarPaseoPersona ()
Iniciar paseo Persona.
4. void ZoomIn ()
Acercar la camara.
5. void ZoomOut ()
Alejar la camara.
6. void MoveUp ()
Mover la camara hacia arriba.
7. void MoveDown ()
Mover la camara hacia abajo.
8. void MoveRight ()
Mover la camara hacia la derecha.
9. void MoveLeft ()
Mover la camara hacia la izquierda.
102
Public Attributes
1. XMVECTOR camPos
Posicion de la camara.
2. bool camPaseoAereo
Variable que nos indica si estamos en medio del recorrido aereo.
3. bool camPaseoPersona
Variable que nos indica si estamos en medio del recorrido de la persona.
4. ID3D11Buffer * pCBufferMat
Constant buffer de las matrices de mundo, vista y proyeccion.
5. ID3D11Buffer * pCBufferCam
Constant buffer con la posicion de la camara.
Public Attributes
1. XMVECTOR CameraPos
Posicion de la camara.
Public Attributes
1. XMMATRIX World
Mundo.
103
2. XMMATRIX View
Vista.
3. XMMATRIX Projection
Proyeccion.
4. void Clean ()
Liberar recursos.
2. void Clean ()
Liberar recursos.
Public Attributes
1. D3D11_VIEWPORT viewport
Viewport.
2. IDXGISwapChain * swapchain
Swap chain.
104
4. ID3D11DeviceContext * devcon
Direct3D device context.
5. IDXGIFactory * factory
Interfaz para crear objetos DXGI.
6. IDXGIAdapter * adapter
Tarjeta grafica.
7. IDXGIOutput * adapterOutput
Monitor.
8. ID3D11RenderTargetView * rtv
Render Target View.
9. ID3D11Texture2D * pDSB
Depth stencil buffer.
Classes
1. struct ConstantBufferDatos
Buffer con datos para los shaders.
2. void UpdateData (float d0, float d1, float d2, float d3)
Actualizar buffer de datos.
3. void Clean ()
Liberar recursos.
Public Attributes
1. int PaisajeX
Dimension X del paisaje.
105
2. int PaisajeZ
Dimension Z del paisaje.
3. int SizeX
Numero de puntos en X.
4. int SizeZ
Numero de puntos en Z.
5. ID3D11Buffer * pCBufferDat
Constant buffer con datos para los shaders.
Public Attributes
1. float data [4]
Tiempo, Tamao de la permutacion, SizeX/Latitud , SizeZ/Longitud.
2. void SaveFrame1 ()
Guardar info de la imagen 1.
3. void SaveFrame2 ()
Guardar info de la imagen 2.
4. void Profile ()
Recoger y presentar los datos de un frame.
5. void InitEncloser ()
Inicio del frame encloser.
6. void EndEncloser ()
Fin del frame encloser.
7. void InitFrame ()
Inicio del frame.
8. void EndFrame ()
Final del frame.
106
9. void InitCalc ()
Inicio del calculo del agua.
Classes
1. struct ConstantBufferLight
Buffer con los datos de una luz.
2. void RotateRight ()
Girar luz hacia la derecha.
3. void RotateLeft ()
Girar luz hacia la izquierda.
4. void Home ()
Posicion inicial.
5. void UpdateLight ()
Actualizar la luz.
6. void Clean ()
Liberar recursos.
Public Attributes
1. XMFLOAT3 lightDir
Direccion de la luz.
2. XMVECTOR lightPos
Posicion de la luz.
3. XMVECTOR lightAt
Lugar al que mira.
4. XMMATRIX lightView
Matriz de vista de la luz.
107
5. XMMATRIX lightProjection
Matriz de proyeccion de la luz.
6. ID3D11Buffer * pCBufferLight
Buffer con los datos de la luz.
7. bool luzActualizada
Acabamos de actualizar la luz.
Public Attributes
1. XMFLOAT3 dirLight
Direccion de la luz.
2. float pad
Alineacion del buffer.
3. XMFLOAT4 colorLight
Color de la luz direccional.
4. XMFLOAT4 ambientLight
Componente ambiental.
2. void SaveObj (VERTEX *vertices, UINT SizeX, UINT SizeZ, const char *name)
Crea un archivo .obj.
108
void ObjManager::SaveObj (VERTEX * vertices, UINT SizeX, UINT SizeZ, const char * name)
Parameters:
vertices
IN: Array con los vertices del objeto
SizeX
IN: Tamao en X del array
SizeZ
IN: Tamao en Z del array
name
IN: Nombre del fichero a crear
Actualizar agua.
6. void EscribirPaisaje ()
Guardar .obj del paisaje.
7. void Clean ()
Liberar recursos.
Public Attributes
1. ID3D11Buffer * pVBufferPaisaje
Buffer de vertices del paisaje.
2. ID3D11Buffer * pIBufferPaisaje
Buffer de indices del paisaje.
3. XMMATRIX paisajeWorld
Mundo del paisaje.
4. int numIndices
Numero total de indices.
109
Classes
1. struct InfoPajaro
Informacion de un pajaro.
2. void UpdatePajaros ()
Actualizar posicion de los pajaros.
4. void Clean ()
Liberar recursos.
110
Public Attributes
1. XMMATRIX pajaroWorld
Mundo del pajaro.
2. XMMATRIX pajaroRotation
Rotacion del pajaro.
3. XMMATRIX pajaroTranslation
Translacion de los pajaros.
4. XMVECTOR pajaroPos
Posicion del pajaro.
5. int pajaroEstadoActual
Estado actual de las alas del pajaro.
6. LARGE_INTEGER pajaroTEstado
Tiempo para controlar el estado del pajaro.
7. LARGE_INTEGER pajaroTPosicion
Tiempo para controlar la posicion de los pajaros.
9. int pajaroActualGoal
Actual objetivo del movimiento del pajaro.
2. void Clean ()
Liberar recursos.
Public Attributes
1. ID3D11ShaderResourceView * pSRVTexPerm
Vista con la textura de la permutacion de numeros enteros.
2. ID3D11ShaderResourceView * pSRVTexGrad3
Vista con la textura de los gradientes 3D.
3. ID3D11ShaderResourceView * pSRVTexGrad2
Vista con la textura de los gradientes 2D.
111
3. void Render (Camera *Cam, Perlin *PerlinData, SamplerManager *SamplerMan, Datos *Data)
Renderizar el planeta.
4. void UpdatePlaneta ()
Actualizar planeta.
5. void Clean ()
Liberar recursos.
2. void Clean ()
Liberar recursos.
Public Attributes
1. ID3D11SamplerState * pPointMirrorSampler
Sampler por puntos, mirror.
2. ID3D11SamplerState * pLineMirrorSamplerComp
Sampler linear con comparacion, mirror.
3. ID3D11SamplerState * pLineWrapSampler
Sampler lineal, wrap.
112
3. void InitFrame ()
Marcar inicio de frame.
6. void EndFrame ()
Marcar final de frame.
7. void ShowFrameInfo ()
Mostrar informacion del frame.
9. void Clean ()
Liberar recursos.
113
Classes
1. struct ConstantBufferMatrixShadow
Buffer con las matrices de la camara-luz.
4. void Clean ()
Librerar recursos.
Public Attributes
1. ID3D11Buffer * pCBufferShadow
Constant buffer de las matrices de mundo, vista y proyeccion para las sombras.
2. ID3D11ShaderResourceView * pSRVShadow
Vista para leer el mapa de sombras.
Public Attributes
1. XMMATRIX World
Mundo.
2. XMMATRIX View
Vista.
3. XMMATRIX Projection
Proyeccion.
114
2. void Clean ()
Liberar recursos.
Public Attributes
1. ID3D11ShaderResourceView * pSRVTexMon
Vista de la textura de la montaa
2. ID3D11ShaderResourceView * pSRVTexNormalMon
Vista de la textura con las normales de la montaa
3. ID3D11ShaderResourceView * pSRVTexSand
Vista de la textura de la playa.
4. ID3D11ShaderResourceView * pSRVTexNormalSand
Vista de la textura con las normales de la playa.
5. ID3D11ShaderResourceView * pSRVTexWetSand
Vista de la textura de la playa, zona mojada.
6. ID3D11ShaderResourceView * pSRVTexNormalWetSand
Vista de la textura con las normales de la playa, zona mojada.
7. ID3D11ShaderResourceView * pSRVTexPalmera1
Vista de la textura de la palmera 1.
8. ID3D11ShaderResourceView * pSRVTexPalmera2
Vista de la textura de la palmera 2.
9. ID3D11ShaderResourceView * pSRVTexPalmera3
Vista de la textura de la palmera 3 y 4.
Public Attributes
1. float x
Posicion.x.
2. float y
Posicion.y.
3. float z
Posicion.z.
4. float nx
Normal.x.
115
5. float ny
Normal.y.
6. float nz
Normal.z.
7. float u
Coordenada u de la textura.
8. float v
Coordenada v de la textura.
9. float w
Coordenada w de la textura.
116