UNIVERSIDAD AUTÓNOMA DE CIUDAD JUÁREZ
Instituto de Ingeniería y Tecnología
Departamento de Ingeniería Eléctrica y Computación
CREACIÓN DE TERRENO VIRTUAL UTILIZANDO ALGORITMOS GENERADORES DE RUIDO
Reporte Técnico de Investigación presentado por:
Fernando Zapata Barron — 113083
Requisito para la obtención del título de
INGENIERO EN SISTEMAS COMPUTACIONALES
Profesor responsable: Javitt Higmar Nahitt Padilla Franco Noviembre 2015
Autorización de Impresión
Los abajo firmantes, miembros del comité evaluador autorizamos la impresión del proyecto de titulación
CREACIÓN DE TERRENO VIRTUAL UTILIZANDO ALGORITMOS GENERADORES DE RUIDO
elaborado por el alumno:
Fernando Zapata Barron 113083
Profesor de la Materia
Ivonne Haydee Robledo Portillo
Asesor Técnico
Javitt Higmar Nahitt Padilla Franco
Declaración de Originalidad
Yo, Fernando Zapata Barron, declaro que el material contenido en esta publicación fue generado con la revisión de los documentos que se mencionan en la sección de Referencias y que el Programa de Cómputo (Software) desarrollado es original y no ha sido copiado de ninguna otra fuente, ni ha sido usado para obtener otro título o reconocimiento en otra Institución de Educación Superior.
Fernando Zapata Barron
Dedicatoria
Dedico este proyecto a mi familia, que me soporto durante tantos años y al unicornio rosa invisible, que me acompaño durante todo ese tiempo y no existe forma de probar que no fue así.
Agradecimientos
Agradezco a todos los profesores que tuve durante esta carrera, de los que aprendí mucho de lo que me ayudó a llegar a este punto, así como a mi maestra de seminario de titulación, Ivonne Robledo y mi asesor, Nahitt Padilla, por ayudarme a que este proyecto tenga al menos un poco de coherencia.
Índice general
Autorización de Impresión iii
Declaración de Originalidad iv
Dedicatoria v
Agradecimientos vi
Índice general vii
Índice de figuras x
Índice de tablas xi
Índice de listados de código xii
Introducción 1
Capítulo 1. Planteamiento del problema 3
1.1 Antecedentes . . . 3
1.2 Definición del problema . . . 5
1.3 Objetivo de la investigación . . . 5
1.4 Preguntas de investigación . . . 5
1.5 Justificación de la investigación . . . 6
1.6 Limitaciones y delimitaciones de la investigación . . . 6
1.6.1 Limitaciones . . . 6
1.6.2 Delimitaciones . . . 6
Capítulo 2. Marco Teórico 7 2.1 Creación de contenido procedimental . . . 7
2.1.1 Terreno virtual . . . 8
2.1.2 Creación de terreno en tiempo real . . . 9
2.1.3 Creación de terreno a través de ruido coherente . . . 10
2.2 Algoritmos generadores de ruido . . . 10
2.2.1 Perlin . . . 11
2.2.2 Simplex . . . 13
2.2.3 Otros algoritmos . . . 14
2.3 Tecnologías y herramientas . . . 15
2.3.1 Gráficos . . . 16
2.3.2 Generación de ruido . . . 17
2.3.3 Generación de terreno . . . 17
Capítulo 3. Materiales y Métodos 19 3.1 Descripción del área de estudio . . . 19
3.2 Materiales . . . 20
3.2.1 Vala . . . 20
3.2.2 Clutter . . . 20
3.2.3 Cogl . . . 20
3.2.4 Mx . . . 20
3.3 Métodos . . . 21
3.3.1 Diseño . . . 21
3.3.2 Desarrollo . . . 27
Capítulo 4. Resultados de la investigación 33 4.1 Presentación de resultados . . . 33
4.2 Análisis e interpretación . . . 33
Capítulo 5. Discusiones, conclusiones y recomendaciones 38 5.1 Con respecto a las preguntas de investigación . . . 38
5.2 Con respecto al objetivo de la investigación . . . 39
5.3 Recomendaciones para futuras investigaciones . . . 39
Apéndice A. Protocolo 44
Apéndice B. Código de la aplicación 47
Índice de figuras
Figura 2.1. Ejemplo de terreno . . . 8
Figura 2.2. Ruido coherente y no coherente . . . 11
Figura 2.3. Ruido de Perlin . . . 12
Figura 2.4. Ruido Simplex . . . 13
Figura 3.1. Módulos de generación de ruido . . . 21
Figura 3.2. Cambios en los valores de los parámetros . . . 23
Figura 3.3. Relación entre los chunks y el área definida . . . 24
Figura 3.4. Grafo de escena . . . 25
Figura 3.5. Bosquejo de la interfaz de usuario del programa . . . 26
Figura 4.1. Ejemplo de la salida de una corrida del programa . . . 33
Figura 4.2. Muestras de mapas de altura generados . . . 37
Índice de tablas
Tabla 4.1. Resultados del algoritmo de Perlin . . . 35 Tabla 4.2. Resultados del algoritmo Simplex . . . 36
Índice de listados de código
Listado 3.1 Función que combina las octavas de ruido generado . . . 27
Listado 3.2 Función generadora de ruido de Perlin . . . 28
Listado 3.3 Función que mide el tiempo transcurrido . . . 29
Listado 3.4 Función que dibuja el terreno . . . 30
Listado 3.5 Creación de la interfaz de usuario . . . 31
Listado B.1 blocks.conf . . . 47
Listado B.2 blocks-application.vala . . . 47
Listado B.3 blocks-chunk.vala . . . 48
Listado B.4 blocks-misc.vala . . . 48
Listado B.5 blocks-noise-dummy.vala . . . 49
Listado B.6 blocks-noise-grad3.vala . . . 49
Listado B.7 blocks-noise-module.vala . . . 50
Listado B.8 blocks-noise-perlin.vala . . . 50
Listado B.9 blocks-noise-simplex.vala . . . 53
Listado B.10 blocks-terrain.vala . . . 58
Listado B.11 blocks-window.vala . . . 61
Introducción
El terreno virtual es uno de los componentes que pueden formar el espacio donde se desarrolla un juego o una simulación, el cual es el entorno que el usuario navega y dentro del que puede interactuar con otros objetos presentes en el mismo. La creación de este terreno puede realizarse a través algoritmos de generación de ruido coherente, con los cuales se crean mapas de altura que describen las características del suelo.
Cuando el proceso de generación de terreno descrito ocurre en tiempo real, es necesario que los algoritmos de generación de ruido se ejecuten de la manera más rápida posible, sin sacrificar la apariencia del ruido generado. Este proyecto analiza dos algoritmos, Perlin y Simplex, buscando encontrar cual de los dos se comporta de manera más optima para la creación de terreno virtual.
El reporte del proyecto abarca cinco capítulos: el planteamiento del problema, el marco teórico, los materiales y métodos, los resultados de la investigación y Discusiones, conclusiones y recomendaciones acerca de los resultados obtenidos. Las secciones y el contenido especifico de cada capítulo se muestra a continuación.
En el primer capítulo se abordarán los antecedentes, proyectos e investigaciones previas que establecen el contexto sobre el que se desarrolla el proyecto actual. Seguido, se ve la definición del problema a tratar, el objetivo que tiene la investigación, las preguntas que se van a responder durante su desarrollo y la justificación del mismo. Por último se ven las limitaciones y delimitaciones que marcan el alcance que tiene el proyecto.
En el segundo capítulo se introducen los conceptos necesarios para el entendimiento del desarrollo del proyecto. Se inicia con las definiciones y conceptos de la creación de contenido procedimental, específicamente la generación de terreno en tiempo real y los distintos métodos disponibles para llevarla a cabo. En la siguiente sección se describen algunos de los algoritmos de generación de ruido que que son aptos para la generación de terreno, el enfoque del proyecto. Finalmente, se muestran las distintas tecnologías que se van a usar durante el desarrollo del proyecto y otras herramientas relacionadas con el tema.
En el siguiente capítulo se describen los elementos de los que esta formado el proyecto.
Se inicia con una descripción del área de estudio que abarca el proyecto, en este caso, la generación de terreno virtual. En la siguiente sección se muestran los elementos de software elegidos para el desarrollo del proyecto, junto con sus características. La última sección trata con los métodos de diseño y desarrollo que se utilizaron en este proyecto;
describe las especificaciones del diseño de los módulos del programa y contiene ejemplos del código que se desarrolló para la implementación de los mismos.
En el cuarto capítulo se tratan los resultados obtenidos durante el proyecto. En la primera sección se describe el método que se utilizó para obtener la información generada por el programa, junto con tablas que muestran los datos generados en varias corridas del mismo. La sección siguiente contiene el análisis sobre los datos generados y lo que se interpretó acerca de los mismos.
En el último capítulo se ven los puntos a los que se llegó a través de la realización de este proyecto. En la primera sección se muestra la forma en la que se contestaron las preguntas de investigación que se definieron para este proyecto. En la siguiente sección se trata la manera en la que el desarrollo de este proyecto llevó al cumplimiento de su objetivo. La última sección muestra recomendaciones a considerar en proyectos futuros y puntos a expandir mediante investigación adicional.
Capítulo 1. Planteamiento del problema
En este capítulo se abordarán los antecedentes, proyectos e investigaciones previas que establecen el contexto sobre el que se desarrolla el proyecto actual. Seguido, se ve la definición del problema a tratar, el objetivo que tiene la investigación, las preguntas que se van a responder durante su desarrollo y la justificación del mismo. Por último se ven las limitaciones y delimitaciones que marcan el alcance que tiene el proyecto.
1.1 Antecedentes
Partiendo del tema raíz de la creación de terreno virtual, que es la generación de contenido procedimental, se pueden encontrar varios artículos, tales como una investigación que define conceptos básicos acerca del tema, además de tratar sus características, como la aleatoriedad y la adaptabilidad e intenta aclarar las diferencias entre otros conceptos similares, como lo es el contenido generado por el usuario [1]. Sobre el tema, también una vista sobre los métodos disponibles para la creación de contenido en videojuegos, que abarca recursos como la historia, las texturas, los sonidos, el comportamiento o el terreno [2], que es el enfoque de este proyecto.
Una de las áreas más importantes para el contenido procedimental es la generación de ruido, tema dentro del cual ha habido constantes publicaciones a lo largo del tiempo.
Estas incluyen artículos dedicados a clasificar y evaluar algunas de las varias funciones de generación de ruido disponibles, junto con sus aplicaciones dentro de otros ámbitos, como el modelado o la creación de texturas para superficies [3].
También es posible encontrar algunas publicaciones más especificas, como la patente del algoritmo de generación de ruido creado por Kenneth Perlin, en la que se muestran los antecedentes del algoritmo, se documenta el funcionamiento interno del mismo y se atienden varias deficiencias presentes en el algoritmo original, algunas técnicas, tales como la complejidad o la presencia de artefactos y otras pertinentes a la documentación, como la falta de una implementación de referencia [4, 5].
Solamente sobre el algoritmo de Perlin, es posible encontrar una cantidad significativa de investigaciones, que van desde libros mostrando detalles de su implementación y sus usos en los gráficos por computadora [6], hasta análisis sobre sus capacidades y deficiencias, que han generado múltiples mejoras y modificaciones de su funcionamiento [7, 8] e incluso han impulsado el desarrollo de nuevos algoritmos diseñados para sobrepasar estas deficiencias [9], como lo es el ruido Wavelet.
Entrando al tema de la generación de terreno, también pueden encontrarse varias in- vestigaciones. Varias de ellas tratan acerca de los varios métodos disponibles para generar terreno, no necesariamente de manera procedimental, ya que estos pueden abarcar téc- nicas como el diseño manual, generación totalmente aleatoria o la creación por parte del usuario de un videojuego [10].
Por lo general, los métodos para la creación de terreno de forma procedimental se basan en la generación de ruido, como puede verse en investigaciones que muestran como estas funciones pueden utilizarse para para la generación de datos de elevación, ubicación y características de cuerpos de agua, vegetación, redes de carreteras y entornos urbanos [11] o en un estudio que muestra el desarrollo de un algoritmo nuevo basado en la evalua- ción perezosa, que incluye detalles de implementación de toda la aplicación [12], desde el mecanismo de almacenamiento del terreno, hasta la visualización del entorno por medio de gráficos por computadora.
Dentro de las investigaciones acerca de los métodos procedimentales se encuentran artículos que demuestran métodos además que la utilización de ruido, tal como el diseño evolutivo [13], que le permite a los diseñadores definir terrenos de acuerdo a una estética o características específicas. Este método permite generar terrenos que siempre son dife- rentes, pero que comparten características consistentes, como valles o lagos. Otro ejemplo de técnicas alternativas se basa en la simulación física [14], que utiliza la erosión termal o hidráulica para sintetizar terreno en tiempo real
Entre estas publicaciones, puede verse que la generación de terreno no se limita a entornos naturales como bosques, montañas o planicies, sino que también puede aplicarse para la creación de áreas urbanas, incluyendo la recreación de caminos, redes de carreteras y la generación de edificios con función y diseño arquitectónico diverso [15].
A pesar de las investigaciones publicadas sobre el tema, la generación de contenido procedimental y aún más la generación de terreno en tiempo real, son áreas que no se han explotado a su totalidad. Aunque las técnicas están en uso, generalmente se aplican para facilitar el diseño de contenido estático y son pocos los proyectos que las aprovechan para brindar una experiencia más única para los usuarios.
1.2 Definición del problema
Cuando en áreas tales como el entretenimiento y la simulación militar se presenta la necesidad de crear entornos virtuales de manera dinámica, como en el caso de mundos que se crean conforme son explorados por el usuario o mapas extensos con características realistas; entonces es necesario el uso de algoritmos generadores de ruido aplicados a la generación de terreno. Al trabajar en tiempo real, estos algoritmos necesitan ejecutarse de la manera más rápida posible, sin sacrificar notablemente la calidad del ruido generado.
1.3 Objetivo de la investigación
Analizar datos sobre las características de dos algoritmos generadores de ruido, con el propósito de aplicarlos a la creación procedimental de terreno virtual en tiempo real.
1.4 Preguntas de investigación
¿Qué parámetros llevan al mejor desempeño de cada algoritmo?
¿Cómo es el desempeño de los algoritmos analizados?
¿Cuál algoritmo es más óptimo para la generación de terreno en tiempo real?
¿Cuál de los algoritmos genera el terreno más realista?
1.5 Justificación de la investigación
Existen dos áreas principales que se beneficiarían del conocimiento sobre los algoritmos disponibles para la generación de terreno tridimensional en tiempo real.
En primer lugar, está el área del entretenimiento, específicamente, el desarrollo de videojuegos, donde se utiliza la generación de terreno con el fin de crear entornos únicos para cada jugador. Conocer acerca de los algoritmos dedicados a esta tarea puede ayudar a optimizar la generación del terreno en el juego, presentándole al jugador un ambiente con una apariencia más responsiva.
La otra área es la simulación de situaciones de emergencia o militares. Al utilizar terreno virtual en este tipo de simulaciones, es posible generar una mayor cantidad de en- tornos con características inesperadas en las que un diseñador humano no habría pensado.
1.6 Limitaciones y delimitaciones de la investigación
1.6.1 Limitaciones
• La información disponible sobre la generación de ruido aplicada a la creación de terreno es relativamente poca, en comparación a otras áreas como los gráficos por computadora.
1.6.2 Delimitaciones
• El proyecto se mantendrá dentro del tema de la creación de terreno y no se expandirá a otras aplicaciones de los algoritmos de generación de ruido.
• El método utilizado para la creación del terreno usará unicamente la generación de ruido y no otras técnicas, como la simulación física.
• Los algoritmos de generación de ruido a tratar consistirán en el algoritmo de Perlin y el algoritmo Simplex.
Capítulo 2. Marco Teórico
En este capítulo se introducen los conceptos necesarios para el entendimiento del desa- rrollo del proyecto. Se inicia con las definiciones y conceptos de la creación de contenido procedimental, específicamente la generación de terreno en tiempo real y los distintos métodos disponibles para llevarla a cabo. En la siguiente sección se describen algunos de los algoritmos de generación de ruido que que son aptos para la generación de terreno, el enfoque del proyecto. Finalmente, se muestran las distintas tecnologías que se van a usar durante el desarrollo del proyecto y otras herramientas relacionadas con el tema.
2.1 Creación de contenido procedimental
La creación de contenido procedimental se refiere a la generación de contenido mediante algoritmos, para medios tales como videojuegos, películas, simulaciones, entre otros. Que es lo que se puede considerar contenido puede variar [1], pero puede incluir cosas tales como texturas, mapas, edificios, comportamiento, vegetación, personajes e historias [2].
Este contenido puede ser generado en línea o fuera de línea, lo que significa que la generación ocurre durante la ejecución del programa o durante el desarrollo del mismo, respectivamente [16]. Un ejemplo de lo primero es cuando un usuario de un videojuego recorre un mundo que va generando nuevas áreas que no se encontraban ahí anteriormente, mientras que en el segundo caso, el contenido es generado previamente y se incluye como contenido estático del juego.
Una de las características posibles, pero no inherentes a la creación de contenido pro- cedimental, es la aleatoriedad [1]. Cuando el contenido se genera, puede estar basado en parámetros aleatorios, lo que lleva a que se genere contenido único cada vez, de otra forma, estos parámetros pueden estar predefinidos, por lo que se generan los mismos recursos en todas las ejecuciones del proceso. En relación a esto, la generación puede ser adaptativa, lo que significa que los parámetros utilizados incluyen datos provenientes del usuario, de manera que la creación de contenido se adapte a sus deseos o acciones.
A pesar de la gran variedad de contenido que es posible generar con técnicas proce- dimentales, el enfoque de este proyecto de investigación es la creación de terreno virtual, específicamente, aquel que se genera utilizando métodos basados en la generación de ruido, como los algoritmos de Perlin, Simplex o Wavelet [3].
2.1.1 Terreno virtual
El terreno virtual es uno de los componentes que pueden formar el espacio donde se desarrolla un juego o una simulación. Este espacio es el entorno que el usuario navega y dentro del cual puede interactuar con otros objetos presentes en el mismo. Estos entornos están relacionados con la manera en que el ser humano percibe los lugares, ya que pueden representar locaciones tales como un bosque, una caverna o un laberinto [2]. Un ejemplo de esto puede observarse en la figura 2.1.
En entornos que representan locaciones al aire libre, es donde se presenta el uso del terreno virtual [2]. Este se representa utilizando mapas que contienen información tal como la elevación o la geometría del terreno; los símbolos presentes en el mapa, que representan objetos concretos como árboles, casas o puentes; las texturas que le dan su apariencia al terreno y a los símbolos y efectos especiales que ayudan a simular la naturaleza, tales como una simulación de las nubes, el clima o la apariencia del sol [17].
Figura 2.1: Ejemplo de terreno virtual [18].
2.1.2 Creación de terreno en tiempo real
Como se mencionó al inicio de la sección 2.1, el contenido puede generarse en línea o fuera de línea, esto incluye, por supuesto, al terreno virtual. Cuando el terreno se crea en línea, es necesario usar técnicas adecuadas para el uso en tiempo real, las cuales necesitan ejecutarse de la manera más rápida y eficaz posible, aunque esto signifique sacrificar la calidad del terreno generado.
Debido a las restricciones impuestas por la necesidad de ejecutarse en tiempo real, estos algoritmos tienden a presentar limitaciones tales como la falta de control, ya que suelen ser algoritmos simples sin parámetros dedicados a características específicas del terreno [13] o el bajo realismo, que sólo puede solucionarse efectivamente con procesamiento adicional, que puede tener una complejidad demasiado alta para usarse en tiempo real.
A pesar de sus limitaciones, existen varias técnicas, que son efectivas en mayor o menor medida. A continuación, se mencionan las más notables:
Simulación física
Este método es el que genera el terreno con características más realistas, dado que está basado en la simulación de eventos del mundo real, como la erosión del agua o el viento, sin embargo, este es uno de los métodos más complejos disponibles y sólo recientemente se ha vuelto viable para su aplicación en tiempo real [14].
Diseño evolutivo
Un método desarrollado recientemente, consiste en la aplicación de los algoritmos gené- ticos para la evolución de terreno que, si bien se genera de manera aleatoria, mantiene características constantes de acuerdo a parámetros preestablecidos [13]. De las técnicas mencionadas, es esta la que ofrece mayor control.
Generación de ruido
Esta es la manera tradicional de generar terreno y la que posiblemente se ejecuta de manera más eficiente. En este método, se parte de ruido en 2D generado por una función,
tal como el algoritmo de Perlin, que se usa como una representación de un mapa de alturas, a partir del que se genera la geometría del terreno [11].
2.1.3 Creación de terreno a través de ruido coherente
Como se explicó al final de la sección 2.1.2, la generación de terreno a partir de ruido está basada en un mapa de alturas. Este mapa es creado a través de una función de ruido, la cual genera valores en una matriz de dos dimensiones, que se toman como valores de altura para crear el terreno o en una matriz de tres dimensiones, a partir de la cual se puede generar terreno más complejo, que puede incluir estructuras como túneles o cavernas.
Adicionalmente a la generación de ruido, existen otras técnicas comunes entre las aplicaciones que utilizan este método para generar terreno. Generalmente, el terreno se almacena en una estructura matricial, dividida en secciones de tamaños iguales, llamados chunks o patches. Estas secciones se crean de acuerdo a las acciones del usuario [12], generándose conforme navega el terreno y se acerca a una región que no se ha generado aún.
2.2 Algoritmos generadores de ruido
El término algoritmos o funciones generadoras de ruido se refiere a un mapeo RN → R 1 que se utiliza para introducir irregularidad a un patrón que de otra forma sería regular [19]. Esto suele implementarse como un procedimiento, que llevado a cabo por una computadora, tiene como resultado una estructura de datos que contiene valores numéricos aleatorios, de acuerdo a ciertos parámetros. Estas funciones tienen su origen en el área de los gráficos por computadora, donde se usan para tareas tales como la generación de texturas o la simulación de efectos como nubes, humo o movimientos incidentales [3].
Para el objetivo de este proyecto, el enfoque se centrará sobre el ruido coherente, que se caracteriza por tener una apariencia más suavizada que el ruido generado completamente al azar [20], como por ejemplo, el ruido blanco. Esto significa que la onda que representa el
1Una relación de un punto deN dimensiones a un valor real R
ruido generado está formada de valores cercanos unos a los otros, como se puede observar en la figura 2.2.
(a) Ruido Coherente. (b) Ruido no coherente.
Figura 2.2: Comparación entre ruido coherente y no coherente [20].
2.2.1 Perlin
El primero de los algoritmos de interés para este proyecto es el algoritmo de Perlin, nom- brado así por su inventor, Kenneth Perlin [4]. Este algoritmo es inicialmente ideado para la generación de texturas, en los tiempos en que Perlin trabajaba en la película Tron, producida por la compañía Pixar.
El ruido de Perlin, también conocido como ruido clásico, es una función de ruido gra- diente. Esto significa que funciona a través de la generación de un enrejado de gradientes aleatorias, a los cuales se les aplica un proceso de interpolación para obtener el valor del ruido en los puntos intermedios del enrejado. Los valores generados tienen una apariencia aleatoria, pero contienen detalles visuales del mismo tamaño, lo cual puede verse de ma- nera gráfica en la figura 2.3. Estas características lo hacen fácilmente controlable y apto para la generación de contenido procedimental.
Como se mencionó al inicio de la sección 2.2, el ruido puede representarse por matrices de varias dimensiones, siendo 2, 3 y 4 dimensiones lo más común para este algoritmo. Sin importar las dimensiones, una implementación de este algoritmo generalmente consiste de 3 pasos:
Figura 2.3: Ejemplo de ruido de Perlin [21].
Definición del enrejado
Se define un enrejado deN dimensiones y se le asigna un vector gradiente unitario aleatorio a cada una de sus coordenadas, conformando un conjunto de nodos. Los gradientes pueden generarse de varias maneras, como tomando valores al azar de un cubo unitario [22] o utilizando una tabla hash con valores precalculados [20], entre otros métodos.
Influencia de cada nodo
Se determina que nodos tienen influencia sobre el punto del que se desea obtener el valor del ruido [4]. Esto se hace calculando el producto punto entre el gradiente del nodo y un vector que representa la distancia del punto al nodo. El cálculo debe realizarse una vez por cada nodo que rodea al punto, dependiendo del número de dimensiones del enrejado, e.g. se hace cuatro veces para dos dimensiones y ocho para 3.
Interpolación
El último paso es la interpolación de los valores obtenidos anteriormente. Este proceso se realiza a través de una función de interpolación, que es una función que tiene como resultado un valor intermedio entre dos valores a y b, dado un valor de peso w [20]. Una de las funciones más simples que existen para este propósito es la interpolación lineal.
2.2.2 Simplex
El algoritmo Simplex, también llamado algoritmo de Perlin mejorado, es un descendiente del algoritmo de ruido clásico, diseñado por el mismo Kenneth Perlin para tratar con varios de los problemas presentes en la implementación original [4, 5], a la vez que genera ruido con características similares, como se ve en la figura 2.4. Este nuevo algoritmo parte del método descrito al final de la subsección 2.2.1 e intenta mejorarlo en varios aspectos, algunos de los cuales se muestran a continuación [5]:
Figura 2.4: Ejemplo de ruido Simplex [23].
Falta de una implementación de referencia
Aunque la situación actual de las funciones generadoras de ruido no lo refleja, idealmente, todas las implementaciones de un mismo algoritmo deberían tener como salida el mismo resultado, siempre y cuando reciban la misma entrada, sin importar en qué plataforma se ejecuten. El ruido clásico de Perlin no esta definido hasta este punto y las múltiples implementaciones disponibles difieren una de la otra.
Cálculo de una gran cantidad de multiplicaciones
La definición original requiere la evaluación de un gradiente por cada una de las esquinas del área que rodea al punto de entrada. El número de evaluaciones aumenta en un orden de 2N, siendo N las dimensiones del ruido; cada una de estas evaluaciones conlleva el cálculo
de un producto punto, el cual se conforma de tres multiplicaciones, que son operaciones relativamente costosas desde el punto de vista del hardware.
Anisotropía visible
De forma ideal, la función de ruido es isotrópica, es decir, es uniforme desde cualquier dirección desde la que se le visualize, pero el algoritmo de Perlin original presenta arte- factos direccionales que permiten percibir discontinuidades en el ruido y hacen evidentes transformaciones como la rotación.
Para este proyecto se seleccionó el ruido de Perlin debido a su gran popularidad y disponibilidad de documentación acerca de su funcionamiento e implementación, lo que lo hace un excelente punto de referencia para la prueba de otros algoritmos. El ruido Simplex fue seleccionado porque a pesar de que se le puede considerar como una mejora general al algoritmo de Perlin, se ha difundido en mucha menor magnitud que el mismo, llegando al punto en que parece tener pocos o ningún antecedente en el área de la generación de terreno, por lo que aún está abierto a una cantidad significativa de investigación.
2.2.3 Otros algoritmos
Además de los algoritmos mencionados, existen otros disponibles que pueden ser aptos para los propósitos de este proyecto:
OpenSimplex
Función generadora de ruido creada con el propósito explícito de utilizarse para la gene- ración de terreno [24]. El ruido OpenSimplex es un desarrollo relativamente reciente, que surge debido a que el algoritmo Simplex se encuentra restringido por patentes [5] y tiene el propósito de hacer disponible una función similar para los desarrollos independientes.
Wavelet
De manera similar al algoritmo Simplex, esta función generadora de ruido es creada en el estudio de animación Pixar para resolver las frustraciones causadas por las faltas del
algoritmo original de Perlin [9]. El algoritmo se basa en la teoría de los wavelets para generar ruido con una menor cantidad de artefactos, problemas de aliasing y pérdida de detalle.
Worley
El ruido de Worley es una función de generación de ruido diseñada para generar texturas complementando a otras funciones, como lo son el ruido de Perlin o Simplex. Su método se basa en la partición del espacio en un arreglo aleatorio de células que puede ser computado sin necesidad de usar valores precalculados [25]. Sus características la hacen apta para generar terrenos montañosos o texturas similares a las de la superficie del agua.
2.3 Tecnologías y herramientas
En el ámbito de la generación de terreno virtual se involucran varias tecnologías: desde las librerías que implementan las funciones que generan el ruido del que se parte para crear el terreno, hasta herramientas de alto nivel que tienen funcionalidad de modelado en 3D o creación de efectos especiales y se utilizan para la generación de contenido para películas o videojuegos.
En esta subsección se describirán las piezas de tecnología que se van a usar durante el desarrollo del proyecto y otras herramientas que, si bien, no tendrán un uso directo, se encuentran disponibles para objetivos relacionados con el tema de la generación de terreno.
GObject
El Sistema de Objetos de GLib o GObject es una librería que provee un sistema de objetos y facilidades para la interoperabilidad entre varios lenguajes de programación [26]. Puede usarse directamente desde el lenguaje C para producir otras librerias con APIs orientadas a objetos, las cuales pueden utilizarse facilmente desde otros lenguajes, como Python, Ruby o Scheme.
Vala
Vala es un lenguaje orientado a objetos con un compilador hecho para generar código en C usando GObject. Este lenguaje tiene una sintaxis y capacidades similares a C♯ o Java, soportando interfaces, propiedades, eventos, ciclosforeach, inferencia de tipos, expresiones lambda, genéricos, tipos no nulos, manejo de memoria asistido, excepciones y módulos.
Está diseñado para permitir el acceso a las librerías de C ya existentes, sin necesidad de un runtime u otro tipo de dependencias [27], solamente necesitando un archivo que describa la API de la librería en sintaxis de Vala. En el caso contrario, también es posible utilizar clases o métodos hechos con Vala desde programas de C, ya que su compilador genera librerías basadas en GObject que son compatibles con la ABI de C común.
2.3.1 Gráficos
OpenGL
OpenGL es una interfaz de desarrollo de aplicaciones, una librería de software creada para acceder a la funcionalidad del hardware de gráficos. Está diseñado como una interfaz independiente del hardware, que puede implementarse sobre distintos tipos de sistemas de gráficos, sin importar el sistema operativo o de ventanas que utilice la computadora [28, 29]. Precisamente por esto, OpenGL no provee facilidades para manejar ventanas, entrada del usuario o leer archivos de imágenes o modelos 3D, para esto es necesario hacer uso de la funcionalidad del sistema que corre en la computadora.
Cogl
Librería que provee acceso al hardware de gráficos con una interfaz orientada a objetos.
Cogl está diseñado para alejarse de la maquina de estados de OpenGL y permitir el acceso y el manejo del estado mediante objetos [30], facilitando la construcción de componentes reutilizables.
Horde3D
Horde3D es un motor de renderizado 3D de código abierto, creada con el fin de hacer disponible un motor gráfico que ofrece la capacidad visual que se espera de videojuegos de nueva generación, a la vez que se mantiene lo más ligera y conceptualmente simple posible [31]. Este motor se presta para la visualización de grandes grupos de entidades animadas y es accesible a través de una interfaz basada en C, lo que le permite estar disponible para una gran variedad de lenguajes.
2.3.2 Generación de ruido
Libnoise
Libnoise es una librería para C++ que se usa para generar ruido coherente. Puede generar ruido de Perlin y ruido multifractal, entre otros [20]. Trabaja en base a generadores de ruido encapsulados en en clases llamadas módulos de ruido; hay varios tipos de módulos, los cuales pueden combinarse y modificarse entre si, lo cual permite generar ruido complejo mediante la unión de distintos módulos.
Accidental
La Accidental noise library es una librería modular para la generación de ruido de Perlin, entre otros tipos de ruido [32]. Provee variantes en dos, tres, cuatro y seis dimesiones de sus funciones de ruido, junto con una interfaz que permite encadenar estas funciones para crear funciones más complicadas a partir de componentes sencillos. También incluye varios modulos para generar, modificar, combinar y transformar funciones con el fin de obtener una salida compleja.
2.3.3 Generación de terreno
VUE
VUE es un paquete de software dedicado a la generación de terreno. Se usa para la creación, animación y renderizado de entornos naturales en 3D, particularmente escenarios
al aire libre [33]. Es utilizado por estudios de efectos visuales, como Industrial Light and Magic, que le dio uso para crear fondos en películas como Indiana Jones and the Crystal Skull o DreamWorks, que le dio uso para la película Kung Fu Panda.
Bryce
Bryce es un programa de modelado en 3D, renderizado y animación que se especializa en los terrenos fractales. Este software tiene origen en un conjunto inicial de programas generadores de fractales, creados por Ken Musgrave [34]. Actualmente, se extiende más allá de esto, incluyendo características como la edición de fuentes de luz, animación, texturas y efectos atmosféricos.
Capítulo 3. Materiales y Métodos
En este capítulo se describen los elementos de los que esta formado el proyecto. Se inicia con una descripción del área de estudio que abarca el proyecto, en este caso, la generación de terreno virtual. En la siguiente sección se muestran los elementos de software elegidos para el desarrollo del proyecto, junto con sus características. La última sección trata con los métodos de diseño y desarrollo que se utilizaron en este proyecto; describe las especificaciones del diseño de los módulos del programa y contiene muestras del código que se desarrolló para la implementación de los mismos. El código completo de la aplicación puede encontrarse en el apéndice B.
3.1 Descripción del área de estudio
La generación de terreno virtual se refiere al proceso realizado por una pieza de software para la creación de paisajes y geometría tridimensional. Para ello existen varias técnicas, como se mencionó en la sección 2.1.2, entre las cuales la generación de ruido es una de las más usadas.
En el ámbito de la generación de terreno en tiempo real, uno de los algoritmos gene- radores de ruido más usados es el algoritmo de Perlin [11, 3], sin embargo, existen otros algoritmos creados posteriormente, que a pesar de que tienen uso en ámbitos como la generación de texturas, han visto poca adopción en el área del terreno.
Este proyecto tomó uno de estos nuevos algoritmos, específicamente el algoritmo Sim- plex, y lo comparó con el algoritmo clásico de Perlin, con el propósito de encontrar los méritos que estos algoritmos tienen aplicados específicamente a la creación de terreno en tiempo real.
3.2 Materiales
3.2.1 Vala
Vala es un lenguaje de programación creado para acercar las características presentes en lenguajes modernos a C, sin requisitos adicionales en tiempo de ejecución [27]. Utilizar Vala permite el acceso a bibliotecas ya existentes que son compatibles con C y la creación de programas que se compilan a código nativo sin necesidad de usar entornos de runtime como los de Java o C♯.
3.2.2 Clutter
Clutter es una librería de gráficos basada en GObject y OpenGL para crear interfaces de usuario. Esta librería no provee elementos de control, tal como botones o barras de desplazamiento, sino que que consiste en un lienzo virtual en el que se dibujan objetos como cuadros o lineas, a partir de los cuales se construyen los elementos más complejos que conforman la interfaz de usuario [35, 36].
3.2.3 Cogl
Cogl es un conjunto de utilidades para desplegar gráficos en tercera dimensión. Provee utilidades para matemáticas, matrices, texturas, renderizado de texto, integración de vi- deo, entre otras [30]. Cogl está diseñado para permitir el uso de hardwaregráfico a través de la manipulación de objetos y sus propiedades, alejándose del modelo de máquina de estados tradicionalmente utilizado por OpenGL.
3.2.4 Mx
Mx es untoolkitconstruido sobre Clutter que provee elementos estándar para interfaces de usuario, tales como botones, barras de progreso o barras de desplazamiento, entre otros [37]. Los componentes de Mx pueden utilizarse en conjunto con los componentes más sencillos de Clutter y los elementos tridimensionales creados a través de Cogl.
3.3 Métodos
A continuación se describen los métodos utilizados para el diseño y el desarrollo de este proyecto.
3.3.1 Diseño
Investigación de algoritmos
Se investigaron los detalles de implementación de los algoritmos de generación de ruido elegidos para el proyecto. La información obtenida a través de esta investigación fue de utilidad durante la etapa de desarrollo del proyecto, donde sirvió para la implementación de los algoritmos de generación de ruido usados en la aplicación.
Investigación de librerías
Se realizó una investigación sobre las librerías de software que se utilizaron para el desarro- llo del proyecto. Como se vió en la sección 3.2, las librerías seleccionadas fueron Clutter, Cogl y Mx, usadas para manejar video, dispositivos de entrada y gráficos en 3D. Otra librería que fue de utilidad para el proyecto fue Libnoise, que sirvió como base para el diseño de los módulos de generación de ruido.
Diseño de módulos de generación de ruido
Figura 3.1: Módulos de generación de ruido
Los algoritmos de generación de ruido se diseñaron de manera que tuvieran una interfaz en común, como se muestra en la figura 3.1. Se crearon en forma de módulos que poseen un método llamado get, que retorna un valor del ruido generado dado una coordenada tridimensional. Adicionalmente, los módulos tienen propiedades que permiten ajustar las características del ruido generado [20], como se describen a continuación:
Semilla: La semilla es un número a partir del cual se crea un generador de números al azar. Para el caso de este proyecto, esto se usa para que el terreno creado tenga una apariencia aleatoria.
Frecuencia: La frecuencia del ruido generado en la primera octava. Por defecto, la frecuencia de cada octava es el doble que la de la octava anterior. El valor de este parámetro afecta la densidad del ruido generado, cuanto mayor sea la frecuencia, el ruido adquiere una apariencia más densa; también se le puede considerar como la escala a la que esta el ruido.
Cantidad de octavas: La cantidad de octavas es el número de iteraciones de la función generadora de ruido que se combinan para crear el valor del ruido final. Este pará- metro controla la cantidad de detalle que presenta el ruido, más octavas crean ruido con más variación en los detalles pequeños.
Lagunaridad: La lagunaridad es el multiplicador de la frecuencia de cada octava. La frecuencia de cada octava es la frecuencia de la octava anterior multiplicada por la lagunaridad. Como se mencionó anteriormente, el valor por defecto de este multi- plicador es 2.
Persistencia: La persistencia es el número por el que se multiplica la amplitud de cada octava. Si la persistencia es 0.5, entonces la amplitud de la primera octava será 1, la de la segunda 0.5, la tercera 0.25, etc. El valor de este parámetro controla la aspereza del ruido, mientras más alto, el ruido generado tiene una apariencia más áspera y granular.
El cambio en el ruido que provoca el cambio de los valores de estos parámetros se
(a) Referencia (b) Frequencia: 0.1
(c) Lagunaridad: 4 (d) Cantidad de octavas: 1
(e) Persistencia: 0.8 (f) Semilla: 10
Figura 3.2: Cambios en los valores de los parámetros
Referencia: frecuencia: 0.03, lagunaridad: 2, octavas: 6, persistencia: 0.5, semilla: 0
Diseño del sistema de evaluación comparativa
Area generada: 16×16 Área generada: 16×16 Area denida: 14×14 Área denida: 14×14 Tamaño del chunk: 4×4 Tamaño del chunk: 4×4
Figura 3.3: Relación entre los chunksy el área definida
Para realizar la comparación entre los algoritmos de generación de ruido, la aplicación genera una tabla de tiempos dados los parámetros designados para la generación del terreno. Además de los parámetros que se mencionan en la subsección 3.3.1, estas tablas incluyen la siguiente información:
Tamaño del chunk: Un chunk representa un segmento del terreno. Estos segmentos son todos de las mismas dimensiones y se generan de forma dinámica conforme el usuario se mueve y se acerca a ellos. El tamaño de los chunks afecta el rendimiento de la generación del terreno, dado que este se genera alrededor del usuario; chunks de mayor tamaño tardan más tiempo en generarse, pero se requieren menos para representar una mayor cantidad de terreno, mientras que cuando son más pequeños, cada uno se genera a mayor velocidad, pero se requieren máschunkspara representar terreno de la misma extensión.
Tamaño del área generada: Al utilizar algoritmos de generación de ruido es posible crear terreno de extensión infinita, pero, de forma que el desempeño de los algorit- mos pueda ser comparado, se necesita definir un área finita a generar. Durante la ejecución de la aplicación, los algoritmos se usan para crear un cuadrado de terreno formado de chunks, el cual tiene este parámetro como medida por lado. Si el área a generar no es un múltiplo del tamaño del chunk, se generará el área más chica que
Cuando la generación del terreno se realiza en tiempo real, el entorno se crea alrededor del usuario y si este se mueve, más terreno debe ser generado, sin embargo, para que los resultados de las pruebas sean comparables es necesario que el usuario se mantendrá estático, por lo que para este proyecto, se consideró que el usuario se encuentra en el origen del mapa y el terreno se genera alrededor de este punto.
Diseño del sistema de gráficos en 3D
Figura 3.4: Grafo de escena
La visualización del terreno generado se hace a través de gráficos tridimensionales. El funcionamiento de estos se organizó en forma de grafo de escena o Scene graph, como se ve en la figura 3.4. Esto es una estructura de datos que contiene los objetos a mostrar en una escena [38].
El grafo de escena tiene forma de árbol, en la que sus nodos representan las entidades presentes en el entorno tridimensional. En esta aplicación se utiliza un objeto Scene, que contiene los nodos de la escena, tiene un método update, que actualiza la lógica de los nodos y un método draw, que muestra la apariencia gráfica de los mismos. Los nodos usados en el programa son los siguientes:
Mapa: El mapa es el nodo que contiene el terreno generado a través de los algoritmos generadores de ruido y se encarga de mostrar la malla tridimensional creada a partir del mismo.
Cámara: Este nodo representa el punto de vista del usuario y es la perspectiva desde la que se visualiza el terreno en la aplicación. La cámara puede hacer zoom y rotar alrededor del terreno.
Diseño visual de la interfaz de usuario
Información
Generar
Mapa de alturas Algoritmo: ###
Frecuencia: ###
Lagunaridad: ###
Octavas: ###
Persistencia: ###
Area: ##×##
Chunk: ##×##
Duración: ##:##
Visualización del terreno
Figura 3.5: Bosquejo de la interfaz de usuario del programa
Para mostrar la información obtenida acerca de los algoritmos, la aplicación hace uso de una interfaz gráfica organizada como se ve el el bosquejo mostrado en la figura 3.5.
La mayor parte de esta interfaz es ocupada por la visualización del terreno, en la que se puede ver el terreno generado de manera tridimensional.
A la izquierda, contiene una caja que muestra la información correspondiente al algo- ritmo utilizado, esto incluye los parámetros mencionados en la subsección 3.3.1, además del tamaño delchunk, el tamaño del área generada y el tiempo transcurrido entre el inicio y el fin de la generación del terreno. A la derecha, muestra un mapa de alturas del terreno, en el cual se ve su apariencia en 2D con una vista desde arriba.
3.3.2 Desarrollo
Desarrollo de los módulos de generación de ruido
Se desarrollaron los módulos correspondientes a los algoritmos seleccionados, tomando como base el diseño descrito en la sección 3.3.1. Los algoritmos se implementaron de manera que generen ruido de tres dimensiones. Este puede utilizarse como ruido de dos dimensiones al ignorar el tercer valor de la coordenada del ruido, lo cual permite que sea apropiado para crear los mapas de alturas que se requieren para generar el terreno.
La función que combina las octavas del ruido es idéntica para ambos algoritmos. Este método se encarga de unir las octavas de ruido generado por el procedimiento específico al algoritmo y modifica el valor final de acuerdo a los parámetros seleccionados, como se ve en el listado de código 3.1.
1 public new double get (double x , double y , double z ) { 2 double v a l = 0 ;
3 double s i g = 0 ; 4 double cur_pers = 1 ; 5
6 x *= frequency ;
7 y *= frequency ;
8 z *= frequency ;
9
10 for ( var cur_oct = 0 ; cur_oct < octave_count ; ++cur_oct ) { 11 s i g = n o i s e ( x , y , z ) ;
12 v a l += s i g * cur_pers ; 13
14 x *= l a c u n a r i t y ; 15 y *= l a c u n a r i t y ; 16 z *= l a c u n a r i t y ;
17 cur_pers *= p e r s i s t e n c e ;
18 }
19
20 return v a l ;
21 }
Listado 3.1: Función que combina las octavas de ruido generado [20]
El ruido usado como base por la función anterior se genera en una función adicional, cuya implementación es dependiente del algoritmo utilizado. La función genera el ruido de acuerdo a las coordenadas requeridas y una lista de números generada al azar basándose
en el número semilla ingresado en los parámetros del ruido. Como ejemplo se muestra la implementación del algoritmo de Perlin en el listado 3.2.
1 private double n o i s e (double x , double y , double z ) {
2 // Encontrar l a c e l d a t r i d i m e n s i o n a l que c o n t i e n e e l punto 3 int X = (int)Math . f l o o r ( x ) ;
4 int Y = (int)Math . f l o o r ( y ) ; 5 int Z = (int)Math . f l o o r ( z ) ; 6
7 // Encontrar l a s coordenadas r e l a t i v a s d e l punto dentro de l a c e l d a 8 x−= X;
9 y−= Y;
10 z−= Z ;
11 // Envolver e l número en 255 12 X &= 2 5 5 ;
13 Y &= 2 5 5 ; 14 Z &= 2 5 5 ; 15
16 // C al cu l a r un conjunto de 8 i n d i c e s g r a d i e n t e s 17 int gi000 = perm [X + perm [Y + perm [ Z ] ] ] % 1 2 ; 18 int gi001 = perm [X + perm [Y + perm [ Z + 1 ] ] ] % 1 2 ; 19 int gi010 = perm [X + perm [Y + 1 + perm [ Z ] ] ] % 1 2 ; 20 int gi011 = perm [X + perm [Y + 1 + perm [ Z + 1 ] ] ] % 1 2 ; 21 int gi100 = perm [X + 1 + perm [Y + perm [ Z ] ] ] % 1 2 ; 22 int gi101 = perm [X + 1 + perm [Y + perm [ Z + 1 ] ] ] % 1 2 ; 23 int gi110 = perm [X + 1 + perm [Y + 1 + perm [ Z ] ] ] % 1 2 ; 24 int gi111 = perm [X + 1 + perm [Y + 1 + perm [ Z + 1 ] ] ] % 1 2 ; 25
26 // C al cu l a r l a c o n t r i b u c i o n a l ruido de cada una de l a s 8 e s q u i n a s 27 // de l a c e l d a
28 double n000= dot ( grad3 [ gi000 ] , x , y , z ) ; 29 double n100= dot ( grad3 [ gi100 ] , x−1, y , z ) ; 30 double n010= dot ( grad3 [ gi010 ] , x , y−1, z ) ; 31 double n110= dot ( grad3 [ gi110 ] , x−1, y−1, z ) ; 32 double n001= dot ( grad3 [ gi001 ] , x , y , z−1) ; 33 double n101= dot ( grad3 [ gi101 ] , x−1, y , z−1) ; 34 double n011= dot ( grad3 [ gi011 ] , x , y−1, z−1) ; 35 double n111= dot ( grad3 [ gi111 ] , x−1, y−1, z−1) ; 36
37 // Se c a l c u l a e l v a l o r de l a curva de fundido para l a coordenada 38 double u = fade ( x ) ;
39 double v = fade ( y ) ; 40 double w = fade ( z ) ; 41
42 // I n t e r p o l a c i o n l i n e a l e n t r e l a s c o n t r i b u c i o n e s de cada esquina
43 double nx00 = l e r p ( n000 , n100 , u) ; 44 double nx01 = l e r p ( n001 , n101 , u) ; 45 double nx10 = l e r p ( n010 , n110 , u) ; 46 double nx11 = l e r p ( n011 , n111 , u) ; 47
48 // I n t e r p o l a c i o n de l o s r e s u l t a d o s sobre e l e j e Y 49 double nxy0 = l e r p ( nx00 , nx10 , v ) ;
50 double nxy1 = l e r p ( nx01 , nx11 , v ) ; 51
52 // I n t e r p o l a c i o n de l o s r e s u l t a d o s sobre e l e j e Y 53 double nxyz = l e r p ( nxy0 , nxy1 , w) ;
54
55 return nxyz ;
56 }
Listado 3.2: Función generadora de ruido de Perlin [39]
Desarrollo del sistema de evaluación comparativa
La comparación entre los algoritmos se hace midiendo el tiempo transcurrido entre el inicio y el fin de la generación del ruido. Para lograr esto se utiliza un temporizador que mide el tiempo que tarda en generarse cada uno de los chunks que conforman el terreno, para luego sumar los tiempos obtenidos y así obtener el tiempo final, el cual se muestra en un reporte junto con los parámetros utilizados para generar el ruido. Un ejemplo de este proceso se muestra en el listado de código 3.3.
1 public double generate_area (uint r ) { 2 this. ar e a_s i ze = r ;
3 this. chunks =new Blocks . Chunk [ r , r ] ; 4 double t = 0 ;
5
6 // Se generan l o s chunks y s e mide e l tiempo que toma cada uno 7 for ( var i = 0 ; i < r ; ++i )
8 for ( var j = 0 ; j < r ; ++j ) {
9 this. chunks [ j , i ] =new Blocks . Chunk( noise , chunk_size , j , i ) ; 10 t += this. chunks [ j , i ] . g en er a t e ( ) ;
11 }
12 this. generated =true; 13
14 // Se r e g r e s a l a suma de l o s tiempos por chunk 15 return t ;
16 }
Listado 3.3: Función que mide el tiempo transcurrido
Desarrollo del sistema de gráficos en 3D
Como se mencionó en la sección 3.2, el terreno se visualiza de forma tridimensional uti- lizando la liberia Cogl. Para lograr esto, se creó un elemento personalizado de Clutter, dentro del cual se hace uso de Cogl para dibujar el terreno tridimensional a partir de la matriz de alturas generadas a partir del ruido. Este procedimiento se ve en la función mostrada en el listado 3.4.
1 public override void paint ( ) {
2 // Se interrumpe e l proceso s i e l t e r r e n o aun no s e ha generado 3 i f ( !this. generated )
4 return;
5
6 // Se e s t a b l e c e n l a s t r a n s f o r m a c i o n e s n e c e s a r i a s para v i s u a l i z a r e l 7 // terr eno , como l a r o t a c i o n
8 Cogl . push_matrix ( ) ;
9 Cogl . t r a n s l a t e ( px , py , pz ) ; 10 Cogl . r o t a t e ( rx , 1 , 0 , 0) ; 11 Cogl . r o t a t e ( ry , 0 , 1 , 0) ;
12 Cogl . set_depth_test_enabled (true) ; 13
14 var r = this. ar ea _si ze * this. chunk_size ; 15 Cogl . t r a n s l a t e ( r /−2.0 f , r /−2.0 f , 0) ; 16
17 // Se dibuja un po l i g o n o por cada cuatro puntos d e l t e r r e n o 18 for ( var i = 0 ; i < r−1; ++i ) {
19 for ( var j = 0 ; j < r−1; ++j ) { 20 Cogl . TextureVertex node [ 4 ] ; 21 fl o at c ;
22
23 node [ 0 ] . x = j ; 24 node [ 0 ] . y = i ;
25 node [ 0 ] . z = (fl o a t)this[ j , i ] * 8 ; 26 c = (fl oat)this[ j , i ]/2+0.5 f ;
27 node [ 0 ] . c o l o r = Cogl . Color . from_4f ( c , c , c , 1) ; 28
29 node [ 1 ] . x = j +1;
30 node [ 1 ] . y = i ;
32 c = (fl oat)this[ j , i ]/2+0.5 f ;
33 node [ 1 ] . c o l o r = Cogl . Color . from_4f ( c , c , c , 1) ; 34
35 node [ 2 ] . x = j +1;
36 node [ 2 ] . y = i +1;
37 node [ 2 ] . z = (fl o a t)this[ j +1, i +1]*8;
38 c = (fl oat)this[ j , i ]/2+0.5 f ;
39 node [ 2 ] . c o l o r = Cogl . Color . from_4f ( c , c , c , 1) ; 40
41 node [ 3 ] . x = j ; 42 node [ 3 ] . y = i +1;
43 node [ 3 ] . z = (fl o a t)this[ j , i +1]*8;
44 c = (fl oat)this[ j , i ]/2+0.5 f ;
45 node [ 3 ] . c o l o r = Cogl . Color . from_4f ( c , c , c , 1) ; 46
47 Cogl . polygon ( node , true) ;
48 }
49 }
50
51 Cogl . set_depth_test_enabled (f a l s e) ; 52 Cogl . pop_matrix ( ) ;
53 }
54 }
Listado 3.4: Función que dibuja el terreno
Desarrollo de la interfaz de usuario
La interfaz de usuario se desarrolló utilizando Mx y Clutter, tal como se mencionó en la sección 3.2. Para mostrar la información textual requerida, tal como los parámetros del ruido y el tiempo de generación, se usaron componentes de Mx, específicamente, cajas de texto y un contenedor colapsable que las contiene. La forma en la que esto se logra se muestra en el listado de código 3.5.
1 // Se c r e a e l contenedor que c o n t i e n e l a s c a j a s de t e x t o 2 var exp =newMx. Expander ( ) ;
3 exp . s e t _ p o s i t i o n ( 1 5 , 15) ; 4 exp . l a b e l = ” Información ”; 5 s t a g e . add_child ( exp ) ; 6
7 var g r i d =newMx. BoxLayout ( ) ; 8 g r i d . spacing = 1 0 ;
9 g r i d . o r i e n t a t i o n = Mx. O r i e n t a t i o n .VERTICAL;
10 exp . add_child ( g r i d ) ; 11
12 // Se crean l a s c a j a s de t e x t o y s e pone l a informacion sobre 13 // l o s parametros d e l ruido dentro de e l l a s
14 Mx. Label l a b e l s [ 7 ] ;
15 l a b e l s [ 0 ] =new Mx. Label . with_text (@” Algoritmo : $algorithm ”) ;
16 l a b e l s [ 1 ] =new Mx. Label . with_text (” Frecuencia : %f ”. p r i n t f ( n o i s e . frequency ) ) ; 17 l a b e l s [ 2 ] =new Mx. Label . with_text (” Lagunaridad : %f ”. p r i n t f ( n o i s e . l a c u n a r i t y ) ) ; 18 l a b e l s [ 3 ] =new Mx. Label . with_text (” Octavas : %u”. p r i n t f ( n o i s e . octave_count ) ) ; 19 l a b e l s [ 4 ] =new Mx. Label . with_text (” P e r s i s t e n c i a : %f ”. p r i n t f ( n o i s e . p e r s i s t e n c e ) ) ; 20 l a b e l s [ 5 ] =new Mx. Label . with_text (@”Área a generar : $area x $area ”) ;
21 l a b e l s [ 6 ] =new Mx. Label . with_text (@”Tamaño d e l chunk : $chunk”) ; 22 foreach ( var l in l a b e l s )
23 g r i d . add_child ( l ) ; 24
25 label_time =new Mx. Label . with_text (” Duración : ”) ; 26 g r i d . add_child ( label_time ) ;
27
28 button_gen =new Mx. Button . with_label (” Generar ”) ; 29 g r i d . add_child ( button_gen ) ;
Listado 3.5: Creación de la interfaz de usuario
Capítulo 4. Resultados de la investigación
En este capítulo se tratan los resultados obtenidos durante el proyecto. En la primera sección se describe el método que se utilizó para obtener la información generada por el programa, junto con tablas que muestran los datos generados en varias corridas del mismo.
La sección siguiente contiene el análisis sobre los datos generados y lo que se interpretó acerca de los mismos.
4.1 Presentación de resultados
Para la obtención de los resultados, la aplicación imprime los parámetros que se utiliza- ron para la generación del terreno, junto con el tiempo que tomó la misma, utilizando un formato como el que se muestra en la figura 4.1. Para asegurar que esta informa- ción reportada por el programa fue representativa del algoritmo analizado, se recolectó la información generada en treinta ejecuciones distintas[40].
1 P e r l i n , 0 ,030000 , 2 ,000000 , 6 , 0 ,500000 , 50 , 16 , 0 ,053899
Figura 4.1: Ejemplo de la salida de una corrida del programa
El formato utilizado para el reporte del programa es una lista de datos separados por comas que representan los parámetros usados para la generación del terreno: el algoritmo elegido, la frecuencia del ruido, la lagunaridad, la cantidad de octavas, la persistencia, el largo del lado del terreno generado, el largo del lado delchunk y el tiempo requerido para la generación del terreno.
Los resultados obtenidos se muestran en las tablas 4.1 y 4.2, para los algoritmos de Perlin y Simplex, respectivamente.
4.2 Análisis e interpretación
A partir de los resultados obtenidos como se describe en la sección 4.1, es notable que el tamaño del área generada y la cantidad de octavas son los parámetros que tienen
más impacto sobre el tiempo que tarda la generación del terreno. Esto se debe a que estos dos parámetros afectan directamente la cantidad de ruido que es necesario generar, mientras que el resto de los parámetros afectan la apariencia del ruido, pero no requieren procesamiento adicional.
En lo referente a la comparación entre los dos algoritmos, so observó que el algoritmo Simplex generalmente presentó mejor desempeño. Esto se ve en las tablas 4.1 y 4.2, en las cuales se observa que con valores bajos en parámetros como la cantidad de octavas o el tamaño del área, el tiempo de generación para ambos algoritmos es muy similar, pero conforme estos van subiendo, el algoritmo Simplex es el que muestra los menores tiempos entre los dos algoritmos para los mismos parámetros. Esto es debido a que el algoritmo Simplex tiende a ser computacionalmente menos costoso que el algoritmo de Perlin[4, 39].
Finalmente, en el área de la forma del terreno, ambos algoritmos tienen capacidades muy similares, teniendo parámetros que, al modificarlos, cambian de ruido generado de manera similar, tal como se aprecia en la figura 4.2. A simple vista, la única diferencia entre el ruido producido por el algoritmo Simplex presenta una apariencia más densa que aquel generado por el algoritmo de Perlin con los mismos parámetros.
Tabla 4.1: Resultados del algoritmo de Perlin
Frecuencia Lagunaridad Octavas Persistencia Área Chunk Tiempo
0.030000 2.000000 6 0.500000 50 16 0.054398
0.030000 2.000000 6 0.500000 50 16 0.039774
0.030000 2.000000 6 0.500000 50 16 0.043083
0.030000 2.000000 6 0.500000 50 16 0.039669
0.030000 2.000000 6 0.500000 50 16 0.044462
0.030000 2.000000 6 0.500000 50 16 0.053791
0.030000 2.000000 6 0.500000 50 16 0.041090
0.030000 2.000000 6 0.500000 50 16 0.053830
0.030000 2.000000 6 0.500000 50 16 0.047261
0.030000 2.000000 6 0.500000 50 16 0.053917
0,030000 2,000000 12 0,500000 50 16 0,120686
0,030000 2,000000 12 0,500000 50 16 0,088709
0,030000 2,000000 12 0,500000 50 16 0,120172
0,030000 2,000000 12 0,500000 50 16 0,095687
0,030000 2,000000 12 0,500000 50 16 0,095852
0,080000 6,000000 12 0,800000 50 16 0,105451
0,080000 6,000000 12 0,800000 50 16 0,082051
0,080000 6,000000 12 0,800000 50 16 0,086919
0,080000 6,000000 12 0,800000 50 16 0,077629
0,080000 6,000000 12 0,800000 50 16 0,078269
0,030000 2,000000 6 0,500000 100 16 0,164199
0,030000 2,000000 6 0,500000 100 16 0,121214
0,030000 2,000000 6 0,500000 100 16 0,121388
0,030000 2,000000 6 0,500000 100 16 0,121144
0,030000 2,000000 6 0,500000 100 16 0,121005
0,030000 2,000000 6 0,500000 100 16 0,120972
0,030000 2,000000 6 0,500000 100 16 0,121412
0,030000 2,000000 6 0,500000 100 16 0,160825
0,030000 2,000000 6 0,500000 100 16 0,121205
0,030000 2,000000 6 0,500000 100 16 0,121086
Tabla 4.2: Resultados del algoritmo Simplex
Frecuencia Lagunaridad Octavas Persistencia Área Chunk Tiempo
0,030000 2,000000 6 0,500000 50 16 0,039976
0,030000 2,000000 6 0,500000 50 16 0,040258
0,030000 2,000000 6 0,500000 50 16 0,032959
0,030000 2,000000 6 0,500000 50 16 0,039983
0,030000 2,000000 6 0,500