CALIFORNIA STATE UNIVERSITY, NORTHRIDGE

Procedural Generation of Planetary-Scale Terrains in Virtual Reality

A thesis submitted in partial fulfillment of the requirements

For the degree of Master of Science in Software Engineering

By

Ryan J. Vitacion

December 2018 The thesis of Ryan J. Vitacion is approved:

______Professor Kyle Dewey Date

______Professor Taehyung Wang Date

______Professor Li Liu, Chair Date

California State University, Northridge

ii Acknowledgment

I would like to express my sincere gratitude to my committee chair, Professor Li

Liu, whose guidance and enthusiasm were invaluable in the development of this thesis. I would also like to thank Professor George Wang and Professor Kyle Dewey for agreeing to be a part of my committee and for their support throughout this research endeavor.

iii Dedication

This work is dedicated to my parents, Alex and Eppie, whose endless love and support made this thesis possible. I would also like to dedicate this work to my sister

Jessica, for her constant encouragement and advice along the way. I love all of you very dearly, and I simply wouldn’t be where I am today without you by my side.

iv Table of Contents

Signature Page...... ii

Acknowledgment...... iii

Dedication...... iv

List of Tables...... vii

List of Figures...... viii

List of Illustrations...... ix

Abstract...... x

Chapter 1: Introduction...... 1

Background...... 1

Objective...... 3

Chapter 2: Overview of Procedural Terrain Generation...... 4

Heightmaps...... 5

Noise...... 6

Chapter 3: Procedurally Generating a Planet...... 9

Spherical Terrains...... 9

Chapter 4: Algorithms Tested...... 12

Value Noise...... 12

Cubic Noise...... 13

Perlin Noise...... 14

Simplex Noise...... 15

Diamond Square Algorithm...... 16

v Chapter 5: Technical Approach...... 18

Chapter 6: Noise Benchmarking...... 20

The NoiseBenchmark Program...... 20

Testing Methodology...... 22

Chapter 7: Benchmark Results...... 25

Computational Complexity...... 25

Memory Usage...... 30

Hardware Dependence...... 35

Overall Recommendations...... 44

Chapter 8: Rendering Procedural Planets in VR...... 45

Achieving Planetary Scale...... 45

The Rendering Prototype...... 49

Output Quality Samples...... 51

Chapter 9: Conclusion...... 58

Further Work...... 59

References...... 61

Appendix: Data Averages...... 63

vi List of Tables

Table 1: NoiseBenchmark Parameters...... 21

Table 2: Test System Specifications...... 35

Table 3: Hardware Dependence Summary...... 43

Table 4: Output Quality Comparison...... 57

vii List of Figures

Figure 1: Generation Time vs. Octaves...... 26

Figure 2: Generation Time vs. Resolution...... 28

Figure 3: Memory Usage vs. Resolution...... 31

Figure 4: Heightmap Memory Usage as Percentage of Heap...... 33

Figure 5: Hardware Comparison...... 36

Figure 6: Cubic Noise Hardware Comparison...... 37

Figure 7: Hardware Comparison...... 39

Figure 8: Hardware Comparison...... 40

Figure 9: Diamond Square Hardware Comparison...... 42

viii List of Illustrations

Illustration 1: A Procedurally Generated Terrain With the Mesh Visible...... 4

Illustration 2: vs. Coherent Noise...... 6

Illustration 3: Mandelbrot Fractal vs. Satellite Image of the Nile River...... 8

Illustration 4: Icosahedral Approximation of a Sphere...... 10

Illustration 5: Value Noise...... 12

Illustration 6: Cubic Noise...... 13

Illustration 7: Perlin Noise...... 14

Illustration 8: Simplex Noise...... 15

Illustration 9: Diamond Square Noise...... 16

Illustration 10: The NoiseBenchmark GUI...... 20

Illustration 11: Simplex, 4 Octaves vs Diamond Square...... 27

Illustration 12: Varying Levels of Detail...... 46

Illustration 13: Quadtree Parent Node With Two Children...... 47

Illustration 14: Pole Compression and Edge Seams...... 50

Illustration 15: Value Noise VR Sample...... 52

Illustration 16: Cubic Noise VR Sample...... 53

Illustration 17: Perlin Noise VR Sample...... 54

Illustration 18: Simplex Noise VR Sample...... 55

Illustration 19: Diamond Square VR Sample...... 56

ix Abstract

Procedural Generation of Planetary-Scale Terrains in Virtual Reality

By

Ryan J. Vitacion

Master of Science in Software Engineering

Hand-crafted 3D environments are limited in scale; creating vast virtual areas requires many weeks or even months of manual modeling, especially considering the demands of environments on the scale of an entire planet. Procedural generation techniques aim to alleviate the time, personnel, and scalability requirements of crafting such environments by generating them algorithmically. These techniques are able to create environments an order of magnitude larger than those crafted by hand in a fraction of the time. Despite these advantages, adapting procedural generation techniques to modern virtual reality platforms presents a great challenge. In recent years, VR technology has expanded rapidly with numerous platforms made available at the consumer level. However, VR applications often exhibit considerable hardware and performance requirements which act as constraints on the rendering of procedurally generated terrains.

x This thesis aims to analyze the feasibility of applying procedural terrain generation techniques to the creation of 3D terrains on a planetary scale for virtual reality applications. The thesis surveys existing generation techniques in the field and examines their ramifications regarding output quality, computational complexity, and scalability in terms of execution time and memory requirements. In order to accomplish this, a C# benchmarking program was developed for the Unity graphical engine that creates randomly seeded terrain heightmaps using Value Noise, Cubic Noise, Perlin Noise,

Simplex Noise, and the Diamond Square Algorithm. The program generates hundreds of heightmaps using each algorithm at various resolutions and fractal iterations while tracking execution time and memory usage. The results are then used to assess the viability of each algorithm for use in a VR environment. In addition, in order to demonstrate the practical use of the heightmaps generated by the algorithms, a VR prototype application was created using C#, Unity, and the SteamVR API for rendering on the HTC Vive virtual reality headset. The prototype features a dynamic LOD system and renders the entire procedural planet, allowing for the comparison of output quality for each algorithm.

xi Chapter 1: Introduction

Background

The creation of three-dimensional virtual terrains is a constantly evolving topic in the field of . Virtual terrains have diverse applications in many fields, ranging from movies and video games to simulation. These virtual environments are often hand-crafted by 3D artists and modelers. However, hand-crafting virtual terrains can prove to be an extremely complex task depending on the physical scale of the desired environment, not to mention the necessary artistic talent and experience. Consequently, crafting vast virtual terrains on a large scale, such as that of an entire planet, can take a team of talented 3D artists many weeks or even months of manual modeling [12]. Such an endeavor is undoubtedly very costly with regards to the personnel and time required.

Thus it is evident that the primary challenge of crafting such vast virtual environments is one of scalability.

Procedural terrain generation techniques alleviate the time, personnel, and scalability requirements of crafting virtual terrains by generating them algorithmically.

These techniques mathematically shape each point of the terrain according to a deterministic mathematical function that can be applied over an infinite coordinate space.

Consequently, a computer can utilize such techniques to create terrains an order of magnitude larger than those crafted by hand in a fraction of the time [3]. In addition, the various algorithms used for procedural terrain generation can often be parameterized, offering a degree of control over the appearance of the output terrain. Given these advantages over manually modeling terrains, procedural generation is an integral component in the creation of large scale virtual terrains.

1 In recent years, rapid advancements graphics hardware and rendering technology have given rise to easily accessible virtual reality hardware available at the consumer level. Evident from the already numerous experiences available to users, VR offers an unprecedented level of interactivity and immersion within virtual environments. Thus

VR constitutes a new and rapidly evolving medium with great potential not only in entertainment and media, but also in practical applications such as simulation and training. For example, consider a VR simulation for training aircraft pilots or a VR application for the imaging of the surfaces of distant planetary bodies. Such applications would directly benefit from the use of vast procedurally generated terrains. However, with VR being a young and emerging technology, even the first generation VR headsets come with steep hardware requirements due to the demanding nature of rendering in VR.

Consequently, in order to adapt large scale procedural terrain generation techniques to virtual reality, it is important to consider the performance constraints and limitations that they operate within.

2 Objective

The primary objective of this thesis is to analyze the feasibility of applying procedural terrain generation techniques to the creation of planetary-scale 3D terrains for use in virtual reality applications. The thesis shall first survey several widely used algorithms for procedural generation and then compare and contrast their computational complexity, output quality, and scalability in terms of execution time and memory usage.

The thesis shall accomplish this using a benchmarking program that tracks these performance dimensions for each algorithm, providing a sufficiently large and diverse data set through which empirical conclusions can be made. Once this analysis has been completed, the resulting conclusions can be used to illuminate the feasibility of applying these techniques in virtual reality applications. In addition, in order to further demonstrate the practical capabilities of procedural terrain generation techniques in VR, a prototype rendering application shall be developed and run on a consumer-grade VR hardware setup. This prototype shall render complete procedurally generated planets using the noise algorithms tested with the benchmarking application. This will provide a practical comparison of the output quality of each algorithm when used in actual VR applications.

3 Chapter 2: Overview of Procedural Terrain Generation

Most procedural terrain generation techniques follow a consistent and systematic process in order to achieve geometry resembling natural terrain features. The process begins with a basic geometric shape represented by a 3D mesh. Traditionally, procedural terrain generation algorithms are applied to flat horizontal planes composed of a lattice of vertices. Each vertex is assigned an elevation value relative to its height above this plane, usually represented by the vertex’s Y-coordinate. Initially, all vertices are assigned an elevation value of zero and thus form a completely flat terrain. At this point, the mesh is systematically deformed by introducing pseudorandom variation to each vertex’s elevation value through the use of a deterministic mathematical function. Where all procedural terrain generation techniques differ is in the exact function used to calculate this variation in elevation and the specific ways through which this function can be parameterized. There are many different algorithms for assigning vertex elevation values, each producing unique visual results with their own advantages and disadvantages. The end result is a completely new terrain geometry represented by the successfully deformed mesh.

Illustration 1: A Procedurally Generated Terrain With the Mesh Visible [1]

4 Heightmaps

In order to store the elevation value of each vertex in the mesh’s 3D geometry, some sort of data structure is required. The principle data structure used in procedural terrain generation is known as the heightmap. At the most basic level, heightmaps are simply a two dimensional grid of numerical values, each representing the elevation value of a vertex at specific coordinates. Consequently, the size and coordinate system of the heightmap mirrors that of the mesh targeted for deformation. Traditionally, heightmaps are created in the form of an image file, using the individual color values of each pixel to represent the height of the corresponding vertex in the mesh [11]. For example, traditional heightmaps take the form of grayscale images, with the brightness or darkness of each pixel representing the height of a specific vertex. Completely black pixels represent vertices at the lowest possible elevation in the mesh, while completely white pixels represent the highest possible elevation. Furthermore, heightmaps in the form of images provide a visual representation of the output terrain prior to application to the base mesh. In addition, another benefit of formatting heightmaps as images is the ability to be manually edited by a 3D artist for the refinement of the finer details of the terrain, or even completely created by hand if so desired. However, a significant limitation of heightmaps is that each pixel can only represent a single elevation value. This renders heightmaps unable to represent more complex terrain features such as caves or overhangs, where any vertex located within would need to represent the height of the terrain both at the surface and below. In spite of this, heightmaps constitute a simple and straightforward structure that can be used to precisely assign and store elevation values for mesh deformation.

5 Noise

At the very core of procedural terrain generation techniques are the noise algorithms used to actually assign elevation values to each pixel in the heightmap programatically. The most basic method to produce these values is to simply iterate through the entire heightmap and assign random values to each pixel, a concept known as white noise. This approach, however, results in volatile elevation values and coarse terrain since there are no constraints present on how much variation can exist between nearby pixels. In the worst case scenario, a completely black pixel may be assigned directly adjacent to a completely white pixel, resulting in a rapid change from the lowest elevation value to the very highest. Once the heightmap is applied, this would present itself as a sharp vertical spike in the mesh that is undesirable for representing natural-like terrain.

Illustration 2: White Noise (Left) vs. Coherent Noise (Right)

6 The solution to this problem is to provide a mechanism through which each vertex can be given awareness of the elevation of other vertices nearby. Such a mechanism would allow constraints to be placed on sharp variations and ensure that any transitions in elevation are smooth and non-volatile. Noise algorithms which are designed with this concept produce what is known as coherent noise. Illustration 2 on the previous page illustrates the difference between white noise and coherent noise. Coherent noise functions exhibit three constraints [2]. Any input value will always result in the same output value, small changes to the input value result in small changes in the output value, and large changes to the input value will result in more random changes in the output value. When generating heightmaps, the input to these coherent noise functions are the coordinates of each vertex and the output is each vertex’s elevation value. Consequently, these three constraints that are characteristic of coherent noise provide each vertex with sufficient awareness of the elevation of its neighbors while allowing more distant vertices to vary more randomly. Thus most procedural generation algorithms utilize the principles of coherent noise to ensure that the resulting terrain will be sufficiently smooth without any of the sharp spikes that are possible when utilizing white noise.

Accurately simulating naturally occurring terrain phenomena presents the core challenge of designing an effective noise algorithm. While how well a noise algorithm mimics natural terrain is an arguably subjective matter, there are principles that can be followed in order to increase output quality. In observing naturally occurring terrain, polygonal shapes with hard angles and straight edges rarely occur. However, patterns resembling fractals often occur naturally in the form of coastlines, rivers, and mountains, for example [11]. Illustration 3 on the following page provides a real-world example of

7 this remarkable similarity. Thus this self-similarity and chaotic appearance inherent to fractal patterns make them particularly useful when attempting to mimic natural terrain.

Many coherent noise algorithms are designed with this principle in mind, and can be applied recursively on themselves through the use of a principle called Fractional

Brownian Motion (fBm) in order to create fractal-like patterns [4]. Fractional Brownian

Motion introduces small random variations to the input coordinates of a noise algorithm and effectively generates multiple layers of noise. When applying fBm, multiple iterations are run recursively, with each iteration increasing in frequency and decreasing in amplitude. This serves to introduce additional noise to the output and fill in the finer details of the terrain, resulting in higher overall fidelity. Using this technique, noise algorithms can be adapted to more accurately represent the appearance of terrain as it is found in nature.

Illustration 3: Mandelbrot Fractal (Left) vs. Satellite Image of the Nile River (Right)

8 Chapter 3: Procedurally Generating a Planet

While the previously described method of using noise algorithms to generate heightmaps are a staple of procedural terrain generation, they are traditionally applied to flat planar meshes in order to create rectangular terrains of limited length and width.

While this is sufficient for a majority of 3D applications, generating an entire planet adds an entire layer of complexity to the problem. This is not to say that such techniques cannot be adapted to the procedural generation of a planet.

Spherical Terrains

Planets are of course spherical in shape, so the challenge of adapting a rectangular heightmap to a spherical object presents itself. In order to accomplish this, an appropriate mesh representing a sphere must first be selected to act as the base geometry to be deformed. In choosing such a mesh, the primary concern is how evenly distributed the vertices are since the density of the vertices in a given area determines the amount of geometric detail that can be applied there. If a mesh concentrates too many vertices in a particular area and less in others, the geometric detail of the mesh will not be uniform and some areas will exhibit less of the detail present in the heightmap [7]. There are several approaches to representing a sphere in 3D space, perhaps the most familiar of which mirrors the geographic coordinate system of latitude and longitude. In this system, the sphere’s vertices are placed at the intersections of the latitude and longitude grid. While simple and straightforward, this method does not lend itself well to the application of heightmaps because the vertices become more dense and concentrated near the poles.

9 Another approach is to use a regular polyhedral shape and refine it in order to approximate a perfect sphere [7]. Regular polyhedra are three dimensional geometric shapes composed of faces of regular polygons, such as equilateral triangles or squares.

Perhaps the most familiar regular polyhedron is the cube, which of course features six uniform squares as its faces. In order to approximate a sphere, each of the squares can be further subdivided into four new ones by adding new vertices at the midpoints of each edge and the center of the original square. This can be done recursively, resulting in exponentially finer geometric detail with each iteration. Once sufficient detail has been achieved, the position of each vertex can be adjusted such that it is one unit of distance away from the volumetric center of the cube. The result is an approximation of the unit sphere which can then be scaled and deformed using a heightmap.

Illustration 4: Icosahedral Approximation of a Sphere. [7]

Similar approaches utilize the recursive subdivision of other regular polyhedra, one such example being the regular icosahedron which is composed of twelve vertices and twenty equilateral triangles as faces. In this case, these equilateral triangles are subdivided in the same manner as the cubes in the previous approach, resulting in a slightly different geometric approximation of a perfect sphere. Due to their intrinsic uniformity, this method of recursively refining regular polyhedra ensures that the resulting mesh evenly distributes geometric detail across the entire sphere [7].

10 In the traditional application of heightmaps, each vertex’s elevation value represents its vertical deviation from a flat reference plane with these values assigned by a noise algorithm. A similar technique can be applied in principle to spherical terrains.

Since the reference mesh in a spherical terrain is a perfect sphere, the numerical value representing each vertex’s height is its distance from the sphere’s center, or its radius.

Thus instead of representing vertical deviation from a flat reference plane, the values contained within a heightmap can be used to represent radial deviation from the surface of the reference sphere. With this principle in mind, the heightmap can then be mapped to the mesh using a spherical coordinate system. These coordinates act as the input values for the noise algorithm used to assign height values to every vertex of the sphere.

The end result is a procedurally deformed sphere utilizing an analogous approach to generating rectangular terrains.

11 Chapter 4: Noise Algorithms Tested

Five algorithms that are commonly used for procedural terrain generation were tested along the dimensions of computational complexity, memory requirements, and dependence on hardware. These five algorithms are Value Noise, Cubic Noise, Perlin

Noise, Simplex Noise, and the Diamond Square Algorithm. This section shall provide a description of each algorithm and a brief overview of how they each work to produce noise for use in procedural terrain generation.

Illustration 5: Value Noise

Value Noise

Value Noise is perhaps the most straightforward of the noise algorithms tested.

Value Noise works by first assigning pseudorandom values to each point in the heightmap. Next, the final elevation value of each point is obtained by interpolating its value with those of the surrounding points. Doing so gives each point the awareness of its neighbors’ elevation values that its characteristic of coherent noise. This process can then be repeated recursively on the result using Fractional Brownian Motion, producing

12 fractal-like noise. Different variations of Value Noise can use varying interpolation functions to achieve this result. In this case, the particular variant of Value Noise tested utilizes quintic interpolation to smooth out variations in each point in the heightmap.

Illustration 6: Cubic Noise

Cubic Noise

The Cubic Noise algorithm works by first generating a map of pseudorandom white noise larger than the desired heightmap. This map is then scaled down to the desired resolution using cubic image scaling [13]. This process takes every pseudorandom value of the original white noise and combines it with nearby values through the cubic interpolation with the overall effect of smoothing out the variations in the final result. Through this mechanism, each position in the final heightmap is given awareness of the value of nearby positions, creating coherent noise. The Cubic Noise algorithm can also be used to produce fractal-like noise through recursive iterations using

Fractional Brownian Motion.

13 Perlin Noise

Perlin Noise is one of the oldest coherent noise algorithms that can be used to create heightmaps. Designed by Ken Perlin in 1983, Perlin noise works by first generating a grid of unit-length gradient vectors originating at each intersection that point in pseudorandom directions. The position of each noise value being calculated is placed within each cell, such that each coordinate is surrounded by four grid points, each with their own gradient vector. Next, four distance vectors are calculated representing the distance from the coordinates of the noise value being calculated and the corners of the surrounding cell. Finally, the dot products between each gradient vector and each corresponding distance vector are calculated and interpolated in order to produce the final noise value [8]. Since each noise value is dependent on the distance vectors and adjacent cells share gradient vectors, each point is given awareness of the value of its neighbors and coherent noise is achieved [10]. The Perlin Noise algorithm can also be applied recursively on the results using Fractional Brownian Motion, producing fractal-like noise.

Illustration 7: Perlin Noise

14 Simplex Noise

Simplex Noise is another coherent noise algorithm designed by Ken Perlin in

2001 that serves as an optimization of his earlier Perlin Noise algorithm [9]. Simplex

Noise simplifies Perlin Noise by utilizing a simplex grid in which each cell is a triangle instead of a square. This results in less total vectors needed to calculate each height value since each cell only has three corners. Furthermore, Simplex Noise utilizes a summation process instead of an interpolation to compute the final noise values. These optimizations provide several benefits over Perlin Noise [5]. Simplex Noise is less computationally complex than Perlin noise and thus enjoys better scalability. By using simplex grids, directional artifacts are also minimized. Like the other noise algorithms presented,

Simplex Noise can also be applied recursively using Fractional Brownian Motion to produce fractal-like noise.

Illustration 8: Simplex Noise

15 Diamond Square Algorithm

The Diamond Square Algorithm is another coherent noise algorithm used to generate heightmaps. The algorithm utilizes the principle of midpoint displacement in order to assign elevation values to each coordinate [17]. The algorithm begins with a square coordinate grid with the four corner coordinates initialized to pseudorandom values. It then calculates the average of the elevation of these four point plus or minus a pseudorandom offset. This value is then assigned to the elevation of the point in the direct center of the grid. This calculation is repeated for each diamond shape formed by the previously assigned values. At this point, the grid is then subdivided into four smaller squares and the whole process is repeated for each of them. This is done until every value in the grid has been assigned an elevation value.

Illustration 9: Diamond Square Noise

16 At each subdivision level, the magnitude of the pseudorandom offset decreases, ensuring that sharp variations do not occur since any changes between coordinates in close proximity are calculated by the smaller subdivision steps. Through this mechanism, the Diamond Square Algorithm achieves coherent noise. It is important to note that the

Diamond Square Algorithm is unique from the other algorithms in that it is inherently fractal [11]. Consequently, it is unnecessary to utilize a method like Fractional Brownian

Motion in order to achieve fractal-like noise. However, the algorithm has several limitations. In order for the original grid to subdivide completely, the original grid must have dimensions of 2n+1. In addition, the algorithm can only produce square heightmaps due its design.

17 Chapter 5: Technical Approach

In order to obtain a practical understanding of each noise algorithms’ performance ramifications for procedurally generating planets in VR, each algorithm was put through a benchmark running within an actual 3D graphics engine used to develop VR applications. The engine used in this thesis is Unity, a complete cross-platform development environment for developing 3D applications that is freely available for academic use. The Unity engine abstracts much of the rendering pipeline away from the developer, vastly simplifying the development of 3D applications. In addition, Unity comes with a fully featured scripting engine and API that supports C# as a primary scripting language. Thus the programming language used to develop both the benchmarking application and the rendering prototype is C#. Unity was chosen as the target engine due to its native support for VR integration, mature feature set, and thorough documentation. For the actual implementations of the noise algorithms themselves, a C# noise generation library called FastNoise was included in the project.

FastNoise supports four of the algorithms in question with parameterization and also supports fBm for the generation of fractal-like noise. Because FastNoise does not include the Diamond Square Algorithm, an implementation was custom coded for this project.

18 As for adding VR support to the rendering prototype, the SteamVR API was chosen as the software interface for implementing the application for use on the HTC

Vive virtual reality platform. SteamVR is a plugin provided for free by Valve

Corporation for use with Unity and provides an interface to the engine with which to render VR graphics and take input from supported VR hardware setups, one of which is the HTC Vive. The HTC Vive is a VR hardware platform that includes a stereoscopic head-mounted display and two motion controllers, both of which are tracked in 3D space with infrared pulses emitted from two base tracking stations. The HTC Vive platform is widely available at the consumer level, and thus is ideal for testing each noise algorithm’s output quality for use in a practical development situation.

19 Chapter 6: Noise Benchmarking

The NoiseBenchmark Program

Illustration 10: The NoiseBenchmark GUI

In order to measure each noise algorithms’ computational complexity, memory requirements, and dependence on hardware, a comprehensive test suite named

“NoiseBenchmark” with a graphical user interface was created in Unity that iteratively generates heightmaps using each algorithm. Whenever a heightmap is generated, the benchmarking program also tracks the execution time of the algorithm in milliseconds, the memory usage of the heightmap, and the overall size of the managed memory heap

20 allotted by the Unity engine. The benchmarking program can not only be used to run a the full test suite but also to generate individual heightmaps with variable parameters.

The program’s graphical user interface features multiple fields for manipulating these various parameters affecting the output of the noise algorithms. By isolating certain parameters and holding all others constant, the benchmarking program is able to analyze the performance of each algorithm along each of the desired dimensions. Table 1 below gives a brief description of each parameter and how they each affect the program’s output.

Parameter Description Noise Type Specifies which algorithm to use when generating heightmaps. Specifies the method of fractal iteration for supported algorithms. The Fractal Type primary mode for terrain generation is Fractional Brownian Motion. (fBm) Specifies the resolution of the heightmap. The program outputs a square Resolution heightmap with length and width equal to this value. Pseudorandom integer value that acts as the seed for noise algorithms Seed that require one. This can be specified manually, though running a test suite randomizes this automatically throughout execution. Specifies the cycles per unit of length for the output of the noise Frequency algorithms. Affects the fineness of the output heightmap. Higher values produce more variation in a smaller area. Specifies how many recursive iterations should be applied to the Octaves heightmap for algorithms that support fBm. Higher values produce more detail in the final results but require additional computation time. Multiplier that affects how much the frequency of the noise algorithm Lacunarity grows with each successive fractal iteration. Increasing this value will affect the fineness of each successive iteration. Multiplier that affects the decay rate of noise values with each successive fractal iteration. Higher values allows noise values assigned Gain in successive iterations to vary more, introducing a higher degree of volatility to the final results. How many iterations of each noise algorithm to run during an instance of the test suite. In order to collect the data for analysis, this value was Iterations set to 100, meaning that each algorithm was run 100 times with differing sets of parameter values.

Table 1: NoiseBenchmark Parameters

21 To generate a single heightmap, the user simply sets the desired values for each parameter and clicks the “generate” button. Once this is complete, the user can then click the “export” button and the program will output a .png image file to the directory it is located within. The program will then generate the heightmap and display the output in the rendering window. The rendering window also displays the generation time, memory usage, and heap size for the completed operation. The user can also run a specific test case by setting the parameters and clicking the “Run” button. The “Run All” button will run the complete test suite for all noise algorithms while setting the parameters automatically throughout its execution. These functions will output the results of each test case to a .csv text file, which can then be converted to a spreadsheet for analysis.

Testing Methodology

In order to systematically compare each noise algorithm along the desired performance dimensions, the benchmarking program follows a completely automated test suite that runs each algorithm at different sets of fixed parameter values. The test suite generates heightmaps for each algorithm at four levels of resolution and five levels of fractal octaves for the specified number of iterations. This process is executed for four resolutions, 256×256, 512×512, 1024×1024, and 2048×2048. After the specified number of heightmaps are generated at the current settings, the test suite outputs a .csv text file containing the data with a naming scheme that mirrors these settings. For example, a 50 iteration test run of 256×256 Simplex Noise at 3 octaves will output a file named

“Simplex256_3oct_x50.csv”. It is also important to note that because the frequency, lacunarity, and gain parameters are multiplier values that have minimal effect on

22 computational complexity, they are held constant throughout the test suite. Furthermore, in order to eliminate any computational advantages that may occur if the seed value was held constant for each run, the seed value is automatically randomized by the application before generating each height map.

To capture the values for generation time, memory usage, and heap size, the benchmarking application makes use of several features native to C# and the Unity engine. The C# System.Diagnostics namespace features a Stopwatch class, which allows breakpoints to be placed at certain points in the code in order to measure the elapsed time between them in milliseconds. These breakpoints were placed at the start of the execution of a noise algorithm and at the end once execution was completed. This allows the program to capture the generation time of one run of a noise algorithm. To capture memory diagnostics, the Unity API features the UnityEngine.Profiling namespace which includes the Profiler class. This class has several methods that can be used to track memory usage in code. The first method, GetRuntimeMemorySizeLong(), takes a Unity object as a parameter returns a long integer value that represents the current amount of memory being used by that object in bytes. The texture object representing the heightmap was passed to this method as the parameter in order to obtain the memory usage value. The second method is the GetMonoHeapSizeLong() method, which takes no parameters and returns the current size of the managed memory heap allotted by the engine. This method was used to obtain the current heap size required by the engine at each execution of the noise algorithms.

23 In order to obtain a sufficiently large dataset for analysis, a test suite consisting of one hundred iterations was performed. This means that one hundred iterations of each noise algorithm was performed for each combination of resolution and number of fractal octaves. However, because the Diamond Square Algorithm is inherently fractal and does not require iterations at differing levels of fractal octaves, the algorithm is simply tested at different levels of resolution. The test suite produced eighty-four .csv files in total which were then combined and converted into spreadsheets for analysis. For each combination of resolution and fractal octaves, the results of the one hundred iterations were then averaged and plotted to gain a visual representation of each algorithm’s performance curves. In addition, in order to explore each algorithm’s dependence on hardware, the one-hundred-iteration test suite was run on three different computers, each having a diverse set of hardware components. These three computers were classified into three types, a low-end machine, a mid-range machine, and a high-end machine. The separate datasets from these three test suites were also plotted and compared in order to examine how each algorithm performs on different hardware setups. This test design provides the resulting dataset with sufficiently diverse results from which to conduct the analysis of each noise algorithm.

24 Chapter 7: Benchmark Results

Computational Complexity

The primary metric used by the test suite to asses each algorithm’s computational complexity is generation time. First, the average generation time of each algorithm was plotted against the number of fractal octaves performed. In this test case, the resolution was held constant at 2048×2048 as well as the hardware setup the test was run on. Note that because the Diamond Square Algorithm is inherently fractal by design, fractal octaves are not applicable and thus the algorithm is omitted from this test. It is clear from the data that for each algorithm, generation time appears to scale roughly linearly with respect to the number of fractal octaves. Based on Figure 1 on the following page, conclusions about how well each algorithm scales with respect to the number of fractal octaves can be made based upon the slope of each curve, which represents how quickly generation time increases with each fractal iteration.

Cubic Noise displays the worst scalability having higher overall generation time than the other algorithms and the steepest performance curve. Perlin Noise comes in second with a shallower performance curve and slightly worse generation times than

Value and Simplex Noise. Value and Simplex Noise exhibit very similar performance curves, with Value Noise performing slightly better. Increasing the number of fractal octaves when generating heightmaps provides the benefit of a corresponding increase in the finer details of the output results. For large scale heightmaps such as those used when generating planetary terrains, this is a valuable benefit to have. Consequently, the data suggests that Simplex Noise and Value Noise are better suited for planetary terrains due to their ability to generate heightmaps with more fractal octaves in less time.

25 s e v a t c O

. s v

e m i T

n o i t a r e n e G

: 1

e r u g i F

26 Another metric through which the computational complexity of each algorithm can be analyzed is the actual resolution of the heightmap itself. In this test case, generation time was plotted against the increasing resolution of each heightmap, with the number of fractal iterations being held constant at four octaves, along with the hardware system the test was run on. The number of fractal octaves was held constant at four because for Value, Cubic, Perlin, and Simplex noise, four octaves produces comparable amounts of fine detail to the Diamond Square Algorithm at this level.

Illustration 11: Simplex, 4 Octaves (left) vs Diamond Square (Right)

Too low of an amount of fractal octaves does not generate a comparable level of fractal detail to the Diamond Square Algorithm, while too many octaves results in diminishing returns in fractal detail, resulting in unnecessary increases in generation time. Four fractal octaves provides a reasonable compromise between generation time and detail and allows the other four algorithms to be compared with the Diamond Square Algorithm.

Figure 2 on the following page displays each algorithms’ performance curves for this test.

27 n o i t u l o s e R

. s v

e m i T

n o i t a r e n e G

: 2

e r u g i F

28 The data shows that for each algorithm, generation time scales in a markedly nonlinear fashion with respect to the resolution of the target heightmap. Cubic Noise once again exhibits the worst performance, displaying the highest overall generation times at all resolutions and the steepest performance curve. Perlin Noise once again comes in second, with slightly worse overall generation times and a slightly steeper performance curve. Simplex Noise and Value Noise once again display very similar performance, though Value Noise scales slightly better than Simplex Noise with a marginally shallower performance curve. Interestingly, the Diamond Square Algorithm exhibits considerably faster generation times than all of the other algorithms, along with a considerably shallower performance curve. Thus it is clear that the Diamond Square

Algorithm has the best scalability in terms of the resolution of the heightmap being generated. Increasing the resolution of the target heightmap provides it with finer detail by allowing more overall elevation values to be stored. The density of these coordinates also increases, allowing a higher resolution heightmap to generate greater geometric detail when applied. This is a significant benefit when generating vast terrains such as those on a planetary scale. Consequently, the Diamond Square Algorithm is the best algorithm to quickly generate high resolution heightmaps with due to its scalability.

29 Memory Usage

The primary factor in determining how much memory a heightmap consumes within the Unity engine is its resolution. Whenever a heightmap is being generated, the engine instantiates a two-dimensional texture object at the specified resolution [16]. This texture file is composed of a total number of pixels equal to the resolution squared, each with their own color values. Unity automatically allocates a section of the managed memory heap to this texture object, which the benchmarking application measures along with the total size of the heap itself. A consequence of this is that in our test suite, heightmaps generated with every algorithm besides the Diamond Square Algorithm will use the same amount of memory to store the output texture file. Recall that the Diamond

Square Algorithm operates with the important caveat that it can only generate heightmaps of 2n + 1 resolution. Thus the resolution of heightmaps generated with the Diamond

Square Algorithm can only be increased in discrete steps, which themselves increase exponentially. Thus when comparing the memory usage of the Diamond Square

Algorithm against that of the other four algorithms at a 2n resolution, the closest possible resolution heightmap the Diamond Square Algorithm can generate will be this value plus one. To account for this limitation, the memory usage of the Diamond Square Algorithm was tested at resolutions of 2n + 1 while the others were tested at the corresponding 2n resolutions. Figure 3 on the following page compares the average memory usage on the high-end system of Simplex Noise at five octaves and the Diamond Square Algorithm along with the peak size of the Unity managed memory heap.

30 n o i t u l o s e R

. s v

e g a s U

y r o m e M

: 3

e r u g i F

31 The performance curves in this graph illustrate how a heightmap generated using the Diamond Square Algorithm will consume more memory on average than the other four algorithms due to the discrete resolution limitation. The graph also illustrates how the managed memory heap grows as the resolution increases. This raises the question of what percentage of the managed memory heap the heightmap consumes. The Unity engine will continue to draw memory from the system in order to grow the managed memory heap as necessary until no more physical memory is available. If the amount of memory used ever exceeds the maximum heap size, the application will crash. It is thus beneficial to minimize the percentage of the heap the heightmap consumes in order to allow the remaining portion to be allocated for other 3D objects or rendering functions.

Figure 4 on the following page illustrates the percentage of heap consumed on the high- end system by heightmaps generated with five octave Simplex Noise and the Diamond

Square Algorithm at different resolutions:

32 p a e H

f o

e g a t n e c r e P

s a

e g a s U

y r o m e M

p a m t h g i e H

: 4

e r u g i F

33 From this graph, it is evident that heightmaps generated using the Diamond

Square Algorithm will consume a larger percentage of the heap at similar resolutions when compared to the other four algorithms. By extension, the Diamond Square

Algorithm will reach the upper memory limit much faster than the other four algorithms due to the discrete resolution limitation. From a practical standpoint, less managed memory will be available for other 3D objects or rendering functions [16]. This is an important factor to consider if the 3D application being developed is to render a scene with the procedural planet alongside many other 3D objects or rendering functions. It thus follows that though the Diamond Square Algorithm has several performance benefits over the other algorithms due to its inherent fractal nature, developers must consider how much memory they wish to be allocated to the heightmap itself versus other assets being rendered, as well as if the increased generation speed is worth the memory sacrificed in this tradeoff.

34 Hardware Dependence

As previously stated, the complete test suite was run on three differing sets of hardware. The specifications for each test system can be found in the table below:

Test System Low-End Mid-Range High-End CPU Intel Core 2 Duo E8400 Intel Core i5-2500K AMD Ryzen 7 1700X Core Count 2 4 8 Logical Processors 2 4 16 CPU Frequency 3.0 GHz 4.6 GHz 3.9 GHz RAM 4 GB DDR3 16 GB DDR3 16 GB DDR4 RAM Frequency 1333 MHz 1600 MHz 3200 MHz GPU Nvidia GTX 260 Nvidia GTX 670 Nvidia GTX 1070 VRAM 2 GB 6 GB 8 GB Manufacture Year 2009 2011 2017

Table 2: Test System Specifications

In order to test dependence on hardware, the results from the generation time versus resolution test were plotted and analyzed for each individual algorithm and each separate hardware system. Figure 5 on the following page illustrates the results for Value Noise.

From this graph, it is evident that Value Noise exhibits considerable benefits in generation time for higher resolution heightmaps when run on newer and faster hardware.

The performance gap between the low-end system and mid-range system is considerable, illustrating how a faster CPU clock speed and more available memory directly benefit the generation process. Despite the mid-range system having a higher clock speed than the high-end system, the gap between the mid-range system and the high-end system is even larger, indicating that Value Noise benefits greatly from modern RAM running at higher frequencies. Figure 6 illustrates similar behavior when the same test is run with Cubic

Noise, though with wider gaps between performance curves overall.

35 n o s i r a p m o C

e r a w d r a H

e s i o N

e u l a V

: 5

e r u g i F

36 n o s i r a p m o C

e r a w d r a H

e s i o N

c i b u C

: 6

e r u g i F

37 When the same test is run using Perlin Noise, the performance gaps are slightly different. The gap between the low-end system and the mid-range system and the gap between the mid-range system and the high-end system are roughly similar, though both gaps increase as resolution increases. This indicates that Perlin noise benefits from both faster CPU clock speeds and newer memory with faster frequencies, though not as dramatically as Value Noise or Cubic Noise. Figure 7 on the following page illustrates these results.

Running the same test using Simplex Noise also produces slightly different performance gaps. Here the gap between the low end system and mid-range system is significant, indicating that CPU clock speed and amount of available RAM directly benefit Simplex Noise. The gap between the mid-range system and the high-end system is narrower but still considerable, indicating the Simplex Noise benefits directly from newer and faster RAM as well. Figure 8 displays the results of this test.

38 n o s i r a p m o C

e r a w d r a H

e s i o N

n i l r e P

: 7

e r u g i F

39 n o s i r a p m o C

e r a w d r a H

e s i o N

x e l p m i S

: 8

e r u g i F

40 Finally, the same test was run on all three systems using the Diamond Square

Algorithm. In this case the performance gap between the low-end system and both of the other systems is very significant, reaching a difference in generation time of more than a second at a 2048×2048 resolution. This indicates that the Diamond Square Algorithm greatly benefits from higher CPU clock speeds, the amount of available RAM, and RAM frequency. Interestingly, despite this, the performance gap between the mid-range system and the high-end system is minimal. The higher clock speed of the mid-range system is likely what brings it on par with the high-end system, even though it has much slower older generation RAM. Consequently it is clear that the Diamond Square algorithm is highly dependent on the clock rate of the CPU. Figure 9 on the following page illustrates these results.

41 n o s i r a p m o C

e r a w d r a H

e r a u q S

d n o m a i D

: 9

e r u g i F

42 During the hardware dependence tests, the greatest overall gap in generation times between the low-end system and the high-end system reached as high as one and a half seconds when generating heightmaps using Cubic Noise. Overall, the tests conducted reveal that CPU frequency, RAM size, and RAM frequency have the greatest effect on generation times for all algorithms. In addition, the performance gap between systems widens as the resolution of the generated hightmaps increases. It is also important to note that systems with more available RAM can generate higher resolution heightmaps. As a demonstration of this, a test run generating one hundred 8192x8192 resolution heightmaps was conducted on the low-end system. During this test, the benchmark application ran out of memory and crashed, likely due the system’s limited amount of available RAM and 32-bit operating system. Consequently, it is clear that the generation of heightmaps using these noise algorithms benefits greatly from newer and more powerful hardware. Table 3 below summarizes the results of the hardware dependence test.

Relative Dependence on Hardware Specification Algorithm CPU Frequency RAM Frequency RAM Size Value Moderate High Moderate Cubic High High Moderate Perlin Moderate Moderate Moderate Simplex Moderate High Moderate Diamond Square High Low High

Table 3: Hardware Dependence Summary

43 Overall Recommendations

Several overall conclusions can be drawn from the analyses conducted above.

When it comes to computational complexity, the data suggests that Simplex and Value noise exhibit the best scalability in terms of the number of fractal octaves. As stated previously, a heightmap generated with more fractal octaves allows for more fidelity in the finer details of the terrain, which are crucial in generating large terrains on a planetary scale. The data also suggests that the Diamond Square Algorithm outperformed all other algorithms in terms of scalability with respect to resolution. Thus for higher resolution heightmaps, which have more overall detail throughout, the Diamond Square Algorithm is the algorithm of choice. The memory usage test revealed, however, that this raw speed comes with a significant caveat. The Diamond Square algorithm can only generate heightmaps with resolutions of 2n + 1, which has a considerable effect on the amount of managed memory it uses. Thus the developer must decide whether or not the advantages provided by the algorithm’s quick generation times and inherent fractal quality outweigh its memory consumption at the target resolution. If this is not the case, either Value

Noise or Simplex Noise are the two next most viable choices, and they have the added benefit of allowing their resolutions to be scaled continuously. Perlin Noise produced acceptable results in terms scalability, though it was outperformed by Simplex Noise in all test cases. Given that Simplex Noise is an optimization of Perlin Noise, it will usually produce similar output results with less performance overhead. Cubic Noise was consistently the slowest algorithm in terms of raw generation time and scaled the worst with respect to resolution and number of fractal octaves, so it appears to be the least viable algorithm for planetary terrain generation according to this test.

44 Chapter 8: Rendering Procedural Planets in VR

While the previous chapters explored the mechanics of generating heightmaps using various noise generation algorithms, the process of actually adapting them for rendering procedurally generated planets in VR is a complex challenge in itself. There are many considerations to be taken into account regarding rendering such large objects in any 3D application, not to mention the additional performance requirements of rendering them in virtual reality. In the development of the VR rendering prototype, it was discovered that rendering such a vast scene with a high number of vertices and triangles caused significant performance issues. This was the primary challenge in achieving planetary scale.

Achieving Planetary Scale

As described previously, the procedural generation of a spherical terrain begins with a base shape that is then refined through recursive subdivision. While this recursive subdivision greatly increases the geometric detail available in the mesh, it also increases the number of vertices exponentially, as well as the number of total triangles rendered using these vertices [14]. It is critical to note that the resulting increase in geometric detail is distributed uniformly throughout the mesh. However, depending on the location of the planet itself and the location of the camera viewpoint within the scene, many of these vertices and triangles may be very far away or obscured by the planet’s horizon where increased geometric detail is unnecessary [15]. Consequently, the challenge encountered was that many of the application’s resources were being wasted by rendering additional detail where it is not needed. The number of triangles and vertices being

45 rendered in a 3D scene directly affects the application’s framerate, and most VR applications recommend high framerates in order to minimize motion sickness and tracking . It thus follows that minimizing the total triangle count while preserving geometric detail is critical in rendering procedural planets in VR.

The solution to this problem is to devise a system where geometric detail is dynamically increased where it is most needed. Areas that are not visible to the camera do not benefit at all from any increased geometric detail, and neither do relatively flat or uniform areas in the terrain. Thus the resources that would be used to render increased geometric detail in these two cases would be put to better use rendering what the camera can actually see and areas of the terrain that exhibit volatile variations in elevation. This dynamic adjustment of geometric detail would greatly reduce the overall triangle count of the scene being rendered at any given frame, increasing the application’s framerate and optimizing performance [6]. Such systems are known as Level-of-Detail systems or

LOD. While LOD algorithms are a vast research topic of their own, it is important to understand how they work on a fundamental level in the context of rendering procedural planets in VR.

Illustration 12: Varying Levels of Detail [14]

46 One example of a dynamic LOD system is the Adaptive Quadtree system. The system begins with a square mesh with the capability to be subdivided into four smaller square meshes. These four child meshes can be further recursively subdivided as well, for as many levels as necessary. A data structure known as a quadtree is used to keep track of each mesh and its children. Quadtrees are a type of tree data structure in which each node has four children. Thus each node in the quadtree perfectly corresponds with each square mesh in the system as well as its children. The system is able to traverse the quadtree in both directions, with upwards traversals deactivating the child meshes and activating the parent mesh. Downwards traversals accomplish the opposite. During a downwards traversal, the result is a higher degree of geometric detail since the parent mesh is being split into its four smaller children, each with their own vertices and triangles. The opposite is true for upwards traversals, which decrease the level of geometric detail by deactivating the smaller child meshes and reactivating the larger and simpler parent mesh [15].

Illustration 13: Quadtree Parent Node With Two Children

47 Utilizing this system, downwards traversals can be triggered to occur dynamically in areas that the camera is directly viewing or in areas with volatile changes in elevation, providing higher geometric detail in both cases. Likewise, areas outside of the camera’s viewpoint or areas with relatively flat and uniform terrain can dynamically trigger upwards traversals, decreasing geometric detail to free up resources for where they are most needed. It is this conservation of rendering resources that the Adaptive Quadtree

LOD system provides that is crucial in rendering procedurally generated planets at scale.

In the rendering prototype developed for this thesis, a cube is used as the base shape for generating the base sphere. Cubes are of course composed of six flat square faces.

Consequently these six faces can be implemented as quadtrees, allowing for the integration of an Adaptive Quadtree LOD system. The prototype takes advantage of this principle in order to optimize performance and maximize framerates.

Another problem encountered involves the loss of floating point value precision within the Unity engine at extreme distances. Whenever an object is instantiated in

Unity, it is given a transform component which contains the objects physical location and orientation in 3D space. This transform component is defined relative to the origin of the scene, otherwise known as world space. The transform component is composed of a set of three dimensional vector variables, which are themselves composed of three floating point values. Consequently, the farther away an object or the camera is from the origin in world space, the more these floating point values will grow and degrade in precision. In traditional 3D applications, scenes are usually small enough such that this loss of floating point precision is not an issue. In rendering planetary terrains, the planet itself can be tens of thousands of units in diameter and the camera viewpoint may need to be tens of

48 thousands of units away in order to view the planet in its entirety. At this scale, the loss of floating point precision is significant enough to cause certain rendering issues, such as jittering in lighting effects or distorted vertex positions, which in turn leads to distorted meshes. This is highly undesirable for accurately rendering procedurally generated planets.

The solution to this problem is to implement a floating origin system. In a floating origin system, the camera’s position is fixed near the origin. Instead of holding the position and scale of objects fixed in world space with the camera moving around them, a floating origin system instead translates the whole scene and the objects within around the fixed camera position. By keeping the camera near the origin at all times, the floating point coordinates of nearby objects and effects will remain sufficiently small enough to retain floating point precision and avoid any rendering artifacts. More advanced floating origin systems can even dynamically scale the entire scene to a smaller size in order to produce the illusion of very distant objects. Avoiding any rendering artifacts as a result of floating point precision loss is critical for any 3D application, especially in the rendering of vast procedural planets. Thus the rendering prototype developed for this thesis makes use of a floating origin system to avoid these issues.

The Rendering Prototype

The VR rendering prototype, named “PlanetGenVR”, was also developed using the Unity engine with C# as the primary scripting language. In order to integrate VR functionality for rendering on the HTC Vive, the SteamVR API was included in the program as well. In addition, a Unity plugin named “Planetary Terrain”, which provides

49 an Adaptive Quadtree LOD system as well as a floating origin system, was integrated into the prototype, maximizing performance. Combining these software packages, a functional prototype was created that is capable of rendering large procedural planets at a high enough framerate for use in VR. To actually generate the planets to be rendered, the prototype takes heightmap images exported directly from the NoiseBenchmark program as inputs.

Because PlanetGenVR is only a prototype, a few compromises were made in terms of mapping the heightmaps and textures to the procedural planets. Firstly, a simple mapping scheme was used in order to map the heightmap to the base sphere for mesh deformation. The mapping scheme in question simply uses the X and Y-coordinates of the heightmap as longitude and latitude values, respectively. This scheme has the side effects of compressing the heightmap at the poles and a visible seam where the heightmap ends since they are not natively exported as tileable. Secondly, a simple elevation-based texturing scheme was used to texture the planets in which the elevation value of the terrain determines its color at any given point. Despite these compromises, the prototype still effectively demonstrates the detail each noise algorithm is capable of throughout the rest of the planet, especially near the equator.

Illustration 14: Pole Compression and Edge Seams

50 Output Quality Samples

The following section provides visual samples for each noise algorithm’s output in VR. For these samples, each algorithm was run at an 8192×8192 resolution at five octaves, except for the diamond square algorithm. The seed value and all multiplier values were held constant to ensure a consistent comparison between each algorithm’s visual output. While how well an algorithm simulates natural terrain is a largely subjective matter, the samples still provide useful insight when taken in the context of the performance analysis conducted previously. Specifically, particular attention was paid to each samples’ geometric variation, fine detail, and presence of directional artifacts.

Directional artifacts are grid-like features that may occur depending on the design of the specific algorithm used for generation. They present themselves as unnatural straight edges or block-like structures in the terrain. In the following samples, possible directional artifacts are highlighted in red.

51 Illustration 15: Value Noise VR Sample

In Illustration 15 above, Value Noise produces terrain with a moderate degree of both geometric variation fine detail. These results are impressive when considering its relatively fast performance when compared to the other algorithms. However, subtle directional artifacts can be seen in certain areas. Some ridges exhibit straight edges and square shapes, which is something to consider depending on the degree of realism desired.

52 Illustration 16: Cubic Noise VR Sample

In Illustration 16 above, this sample of Cubic Noise displays relatively flat terrain with less geometric variation and fine detail, though the values seem to be distributed in a sufficiently random manner. However, directional artifacts are very apparent in this sample where small rectangular hills are visible. In addition, ridges seem to consistently flow horizontally, further indicating the presence of directional artifacts. Given Cubic

Noise’s poor performance during the benchmark tests, these results suggest that it is one of the least suited algorithms for procedural planet generation.

53 Illustration 17: Perlin Noise VR Sample

Illustration 17 displays Perlin Noise when applied to the rendering prototype.

Perlin Noise produces acceptable results, with moderate geometric variation and sufficient fine detail. Directional artifacts are minimal though still noticeable, likely due to the algorithm’s use of a rectangular vector grid to calculate elevation values. Though

Perlin noise was one of the slower noise algorithms, these results may be worth the extra execution time if visual quality is desired.

54 Illustration 18: Simplex Noise VR Sample

Illustration 18 displays Simplex Noise when rendered within the prototype. The elevation values generated by Simplex Noise are markedly volatile with high geometric variation and fine detail. However, this volatility can always be compensated for by adjusting the multiplier values before generation. In addition, likely because Simplex

Noise utilizes a simplex grid with triangular cells, no directional artifacts are immediately visible. Given Simplex Noise’s impressive performance during the benchmark tests, it may be one of the ideal choices for procedural planet generation.

55 Illustration 19: Diamond Square VR Sample

Illustration 19 shows how terrain generated by the Diamond Square algorithm looks when applied in VR. In this sample, geometric variation and fine detail are relatively low and the terrain as a whole is rather flat. While the terrain appears to have an acceptable degree of randomness, several directional artifacts are clearly visible.

Many ridges have completely straight edges and some rectangular formations are apparent. This is likely due to the algorithm’s heavy use of subdivided squares in its design. Consequently, even though the Diamond Square Algorithm was one of the fastest algorithms during the benchmark tests, it may be at the expense of overall visual quality.

56 Overall, planets were able to be rendered in VR using heightmaps generated with each of the five algorithms tested. In addition, each sample ran in excess of ninety frames per second within the rendering prototype, indicating that each algorithm meets a minimum level of viability for procedural planet generation in VR. This is likely due to the prototype’s use of an Adaptive Quadtree LOD system. However, each sample varies significantly in the final appearance of the resulting planetary terrain. Each sample exhibited unique degrees of geometric variation and fine detail, along with varying levels of directional artifacts. Table 4 below summarizes the results of the output quality comparison.

Output Quality Algorithm Geometric Variation Fine Detail Directional Artifacts Value Moderate Moderate Moderate Cubic Low Low High Perlin Moderate Moderate Low Simplex High High Low Diamond Square Low Low High

Table 4: Output Quality Comparison

57 Chapter 9: Conclusion

In summary, the research conducted throughout the development of this thesis provided great insight into the subtleties of using noise to generate heightmaps for the procedural generation of planetary terrains. The research also shed light on the unique challenge of adapting these techniques for use in a VR environment. By thoroughly delving into the mechanisms through which noise algorithms work, a comprehensive benchmark testing program was developed. The dataset generated by the

NoiseBenchmark program proved to be invaluable in allowing the noise algorithms to be compared with one another in a systematic and quantitative manner. This analysis provides an empirical understanding of how the computational complexity and memory requirements of each algorithm scale when generating larger and more complex heightmaps. The data highlights Simplex Noise, Value Noise, and the Diamond Square algorithm as the fastest and most scalable noise algorithms, making them well suited for use in procedural terrain generation for VR. The analysis also sheds light on how dependent each algorithm is on hardware. All of the noise generation algorithms rely heavily on the CPU and memory and directly benefit from higher CPU clock frequencies, memory frequencies, and overall amount of available memory. The PlanetGenVR prototype further explores the capabilities of the noise algorithms and tests them in a practical manner by comparing their actual output results. The prototype also explored the challenge of dynamically managing geometric complexity in order to optimize performance. The visual comparison provided by the rendering prototype highlights

Simplex Noise and Perlin Noise as the algorithms with the best visual results, and given that they both performed well during the benchmark tests, they are solid choices for

58 generating planetary terrains. Most importantly, the prototype successfully demonstrates that it is indeed feasible to render a fully procedural, large-scale, planetary terrain at an acceptable framerate in VR, which is the primary objective of this thesis as a whole.

Further Work

The research and analysis conducted in pursuit of this thesis also highlighted several critical subjects for further exploration. A key insight provided by the

NoiseBenchmark analysis is that resolution is the most limiting factor in using noise to generate heightmaps. The data reveals that both generation time and memory usage scale non-linearly with respect to the heightmap’s resolution. Resolution is the most important factor in how much geometric detail a heightmap can contain. However, the

NoiseBenchmark data also reveals how generating a high resolution heightmap can take whole seconds, which is not ideal for generation at runtime. Consequently, the development of noise algorithms that can generate heightmaps of higher resolutions more efficiently constitutes a key area of research for future exploration. In addition, an alternate data structure that can store more elevation values with less memory than a heightmap would prove to be invaluable in terms of scalability. Such improvements constitute the next step in procedural generation, with the ultimate goal being the reduction of generation time and memory usage to a low enough level suitable to be executed at runtime.

Furthermore, the challenges encountered in developing the PlanetGenVR prototype also highlight areas for further research and exploration. Level-of-Detail systems are instrumental in ensuring optimal performance, especially in VR.

59 Consequently, more effective and efficient methods of dynamically adjusting geometric detail are highly relevant to the procedural generation of planetary terrains. Another topic that warrants further exploration is the adaptation of rectangular heightmaps to spherical terrains. The PlanetGenVR prototype encountered issues of distorted geometry at certain locations due to the simple mapping technique used. These issues highlighted the inherent limitation of heightmaps when used for spherical terrain generation. Thus research into new specialized data structures for tracking the elevation values of spherical terrains is another key area for exploration. In line with this, the development of noise algorithms that natively produce spherical terrains would also greatly benefit the procedural generation of planets.

Finally, viewing each sample in VR made it apparent that while the output of every noise algorithm can be manipulated by adjusting their respective parameter values, these parameters affect the noise in rather abstract ways. Furthermore, adjusting these values tends to have an effect over the entirety of the generated heightmaps rather than in isolated areas. As a result, terrains created with these algorithms tend to have a uniform appearance despite the randomness used to generate them. Consequently, researching clearer and more precise ways to parameterize these existing noise algorithms is a key concern. Alternatively, new noise algorithms with better parameterization would also be a welcome improvement. Overall, the end goal is to explore new ways to give users more definitive control over the terrains they create.

60 References

[1] F. Bevilacqua, C. T. Pozzer, and M. C. Dornellas, “Charack: Tool for Real-Time Generation of Pseudo-Infinite Virtual Worlds for 3D Games,” 2009 VIII Brazilian Symposium on Games and Digital Entertainment, 2009.

[2] J. Bevins, “Libnoise Glossary,” Libnoise. [Online]. Available: http://libnoise.sourceforge.net/glossary/index.html#coherentnoise. [Accessed: 05- Sep-2018].

[3] D. M. D. Carli, F. Bevilacqua, C. T. Pozzer, and M. C. Dornellas, “A Survey of Procedural Content Generation Techniques Suitable to Game Development,” 2011 Brazilian Symposium on Games and Digital Entertainment, 2011.

[4] A. Cristea and F. Liarokapis, “Fractal Nature-Generating Realistic Terrains for Games,” 2015 7th International Conference on Games and Virtual Worlds for Serious Applications (VS-Games), 2015.

[5] S. Gustavson, “Simplex Noise Demystified,” 22-Mar-2005. [Online]. Available: http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf. [Accessed: 15- Sep-2018].

[6] P. Lindstrom, D. Koller, W. Ribarsky, L. F. Hodges, N. Faust, and G. A. Turner, “Real-time, Continuous Level of Detail Rendering of Height fields,” Proceedings of the 23rd Annual Conference on Computer Graphics and Interactive Techniques (SIGGRAPH ‘96), 1996.

[7] R. Kooima, J. Leigh, A. Johnson, D. Roberts, M. Subbarao, and T. Defanti, “Planetary-Scale Terrain Composition,” IEEE Transactions on Visualization and Computer Graphics, vol. 15, no. 5, pp. 719–733, 2009.

[8] K. Perlin, “An Image Synthesizer,” 12th Annual Conference on Computer Graphics and Interactive Techniques (SIGGRAPH '85), 1985.

[9] K. Perlin, “Improving Noise,” 29th Annual Conference on Computer Graphics and Interactive Techniques (SIGGRAPH '02), 2002.

[10] D. Maung, Y. Shi, and R. Crawfis, “Procedural Textures Using Tilings with Perlin Noise,” 2012 17th International Conference on Computer Games (CGAMES), 2012.

[11] T. J. Rose and A. G. Bakaoukas, “Algorithms and Approaches for Procedural Terrain Generation-A Brief Review of Current Techniques,” 2016 8th International Conference on Games and Virtual Worlds for Serious Applications (VS-GAMES), 2016.

61 [12] R. Smelik, J. de Kraker, S. Groenewegen, “A Survey of Procedural Methods for Terrain Modelling,” TNO Defence, Security, and Safety, 2009.

[13] J. Talle, “Job Talle,” Cubic Noise, 31-Oct-2017. [Online]. Available: https://jobtalle.com/cubic_noise.html. [Accessed: 27-Sep-2018].

[14] T. Ulrich, “Rendering Massive Terrains using Chunked Level of Detail Control,” 29th Annual Conference on Computer Graphics and Interactive Techniques (SIGGRAPH '02), 2002.

[15] T. Ulrich, “Continuous LOD Terrain Meshing Using Adaptive Quadtrees,” Continuous LOD Terrain Meshing Using Adaptive Quadtrees, 28-Feb-2000. [Online]. Available: https://www2.cs.duke.edu/courses/cps124/spring08/ notes/14_datastructures/lod_terrain.html. [Accessed: 25-Aug-2018].

[16] “Understanding Automatic Memory Management,” Unity – Manual. [Online]. Available: https://docs.unity3d.com/Manual/UnderstandingAutomaticMemory Management.html. [Accessed: 04-Oct-2018].

[17] H.-R. Wang, W.-L. Chen, X.-L. Liu, and B. Dong, “An Improving Algorithm for Generating Real Sense Terrain and Parameter Analysis Based on Fractal,” 2010 International Conference on Machine Learning and Cybernetics, 2010.

62 Appendix: Data Averages

High End System, 100 Iterations

63 64 Mid-Range System, 100 Iterations

65 66 Low-End System, 100 Iterations

67 68