ProceduralTerrainGeneration

12
Project Report “Procedural Terrain Generation” COMP 3009 COMP 3009 Project Report Procedural Terrain Generation December, 2015 Page 1 of 12

Transcript of ProceduralTerrainGeneration

Page 1: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

COMP 3009 Project Report

Procedural Terrain Generation

December, 2015 Page 1 of 12

Page 2: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

Table of Contents

1. Introduction (0.5 page) 2. Project (3­4 pages including images) 2.1 Objective of project 2.2 Project Detailed Description (0.5) 2.2.1 What special features were incorporated into the Project (0.5) 2.2.2 Special Elements (1­2 pages)

2.3 Originality (0.25 ­ 0.5 page) 2.4 What was not accomplished (0.25 ­ 0.5) 2.5 What was hard (0.25 0.5)

3. Project Work (0.25 page not including table) 4. Grade (0.25 page) 5. Conclusions (0.5­1 page)

List of Figures Figure 1. An example terrain from the game Minecraft. Figure 2. Perlin Noise. Figure 3. Using an image to display our world with multiple chunks. Figure 4. Misaligned chunks. Top­Down view. Figure 5. A properly aligned map. Top­Down view. Figure 6. Sample kitten in 3D with lighting. Image 1. Terrain chain (front page). Image 2. Terrain shore.

List of Tables Table 1: Project Schedule ­ this table presents the estimated work time vs. the actual time that it

took to complete the tasks. Course: COMP 3009 Date: 17/12/2015 Student Name & Number: Jason Kemp ­ 100804785 Vladimir Menshikov ­ 100840927

December, 2015 Page 2 of 12

Page 3: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

1. Introduction (0.5 page) The project is about procedural terrain generation. We have picked it because we are

interested in how procedural terrain generation works as it is very common in games. We think that the best way to learn about something is to try and create it by ourselves. We have created height maps from using perlin noise. It was done by creating perlin noise and assigning it to textures. This can be generated completely randomly or with a unique key, that will generate the same terrain every time. You can fly freely around the world with a small illusion of being on a personal airplane due to a spinning rotor in front. The terrain is also beautiful, with white snowy mountains (white) and forested middle areas (green). There are lakes at the lowest altitudes. The differentiation is not purely according to elevation but the surroundings as well. Tall grassy plateaus are rare but can happen. There is an arbitrary light spot shining from far away onto the land. The lakes are not just blue like the color change of the terrain but have wavy movement and transparency to show the terrain below water. There is a “Bird’s eye view” option to see all the currently loaded chunks from higher up for a better overall view. The terrain is generated with chunks, loading only the ones closer to the user. While traveling faraway chunks “unload” and new chunks become visible. Due to the unique nature of perlin noise, when moving back to an already explored area the same terrain will be present instead of new random terrain. When looking at the terrain from a birds eye view, it looks like a potential map for a game, which is our goal.

Figure 1. An example terrain from the game Minecraft.

December, 2015 Page 3 of 12

Page 4: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

2. Project (3­6 pages including images)

2.1 Objective of project

The projected is about generating terrain using a seed and perlin noise. The perlin noise is generating height maps which are assigned to textures and displayed.

2.2 Project Detailed Description (0.5)

We have implemented multiple features in the project. Height maps from textures. Texture generation. Lighting. A hierarchical object with movement, a spinning airplane rotor. Water waves. Procedural generation with a seed. Free movement in a 3D world with a seemingly endless terrain. Smooth terrain elevation transitioning, snowy peaks to forests to lakes.

2.2.1 What special features were incorporated into the Project (0.5)

Height Map & Texture Generation ­ This is a core concept for out project. We use the height value of a texture that we generate in order to display “terrain”. The terrain effect is given by chaining random height values to create mountains and plateaus. Using a technique similar to that of blur of bloom, the texture is sample at neighboring locations and the relative height is used to assign a color. This means random patterns along the mountain side where the “forest” becomes “rock” or “snow”. The world is split into 25 chunks, these chunks change depending on your location.

Perlin Noise ­ Using perlin noise in order to generate textures based on a given seed (or random) is necessary to have a more natural looking scene, compared to a flat plane with minor artificial hills. It is much more efficient to generate terrain randomly than having to assign the value of every area manually. The perlin noise is calculated at 6 resolutions and averaged together to ensure smooth transitions.

Lighting ­ Ambient and Diffuse Lighting gives a more realistic view on the world, the tall mountains shine brighter while their back sides are left in the dark. We decided not to use specular lighting as the mountains did not seem like they should be shiny.

Rotor Object ­ Gives the feeling of flying around in an aircraft instead of a god­like movement. Having dynamically moving objects on a scene makes it more “interesting” compared to a plain static scene.

Water Waves ­ What are lakes without some “Natural” waves. It also makes the scene more dynamic and realistic. The wave function is the product of 4 different wave functions to appear more random. The transparency allows you to see the underlying terrain.

December, 2015 Page 4 of 12

Page 5: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

3D Movement ­ Moving around in a 3D world is a core concept in many old and new games and applications. Without free 3D movement it feels like something is wrong with the program, or the developer.

Smooth Terrain ­ The terrain transitioning was smoothed out by using the averages of nearby height values in a grid. This leads to more realistic terrain without random forests in a lower mountain area or snow in a bumpy forest area. Controls

­ wasd for movement and turning, up/down/left/right for pitch and roll. ­ b birds eye view ­ f wireframe ­ n turns off waves ­ h turns off heightmap (can see perlin texture) press l to raise perlin texture above water.

(press b now to see the entire map).press l again to place back at proper height, press h again to turn on height map

­ p to turn off rotor (plane);

Image 2. Terrain shore.

December, 2015 Page 5 of 12

Page 6: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

2.2.2 Special Elements (1­2 pages) The main element of the project is the generation of terrain. While using a texture as a

height map is relatively easy, creating large maps of procedurally generated terrain is not that simple. Firstly, in order to display a map, or a terrain, it needs to be generated. We focused on generating a random height value and assigning it to a 2D texture as color. The plane itself is 2D but the changes in elevation due to the height (color) value gives it a 3D look. This was done by accessing the Y value of a vertex inside the vertex shader and changing it from being flat, to the value of the texture’s color.

Figure 2. Perlin Noise. example from seed 39

This created a nice basic 3D terrain. But the problem is in making it bigger. Of course the texture can be stretched out far and increase the number of vertices to make it look finer but it becomes very slow to load and render. What happens when the player manages to move far enough for there to be a need for a continuation of the terrain in a direction. Making a texture infinitely big is not an option. What we have done is create many smaller textures that are fast to process and arranged them in a 2D array based on global X and Z coordinated. The smaller chunks are easier to handle. When moving around the world further chunks in that direction are loaded and the chunks at the back are no longer needed so they are “unloaded”, that is not being rendered or updated anymore. This allows us to keep a small dynamic area loaded with relatively smooth transitioning in the world. Initially we used an image for our testing. We used it to set up a base framework for out project before we moved to generating and displaying our own

December, 2015 Page 6 of 12

Page 7: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

textures.

Figure 3. Using an image to display our world with multiple chunks.

Once we transitioned to that we had a big problem, that is correctly displaying the textures in our global grid. Often the terrain did not match up and the chunks were very cut up.

Figure 4. Misaligned chunks. Top­Down view.

December, 2015 Page 7 of 12

Page 8: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

We solved it by finding a pattern common to all the chunks and applying the required transformations to fix the alignments.

Figure 5. A properly aligned map. Top­Down view.

Another issue was on lighting. How to calculate the normals for a texture whose height

values are adjusted. This was done in the shader, but the shader does not know about the location of other vertices, and we need 2 more vertices to calculate the normals.We calculated normals by accessing the texture’s nearby vertices. The shader does not know about the neighboring vertices but the texture does. We had to access Y values with an offset X and Z values. The offset was calculated based on the size of the mesh that the texture was bound to. For a size of 100x100 mesh, the vertex offset was 1/100. By getting 2 more values we subtracted them with the current vertex to get 2 vectors and crossed them to get the normal.

December, 2015 Page 8 of 12

Page 9: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

2.3 Originality (0.25 ­ 0.5 page)

We think our concept was unique relative to the class because procedural generation is not a simple task and we have experienced it deeply. The idea itself is popular in all games but trying to create it from nothing and without any experience is not something people would try. But creating 3D illustrations from images is unique.

Figure 6. Sample kitten in 3D with lighting.

2.4 External Resources (0.25 ­ 0.5 page)

The following page had a great tool for generating perlin noise. However it had to be modified to allow the result to be used as a texture. Also the output is rotated 90 degrees so when multiple chunks are rendered beside each other the result does not line up. This led to many hours of testing to finally realize the problem. http://www.sorgonet.com/linux/noise_textures/

December, 2015 Page 9 of 12

Page 10: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

2.5 What was not accomplished (0.25 ­ 0.5)

We have accomplished what we have initially planned and kept adding more content as we programmed. Resulting in features like water waves and smooth terrain. Unfortunately a skybox was not implemented as another feature because it conflicted with the terrain textures and a solution was not found.

2.6 What was hard (0.25 0.5)

Texture conflicts prevented us from implementing a skybox. We tried many different ways of binding and indexing textures but none worked to a presentable extent. We did not plan for it initially but it could be a nice addition. Making sure the transitions between chunks were smooth and proper was also difficult. With bigger chunk sizes the load time increases significantly to the point where a freeze is felt.

December, 2015 Page 10 of 12

Page 11: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

3. Project Work (0.25 page not including table)

We followed the agile methodology as we already had experience working with it. We broken down the big project into smaller modules and implemented them 1 by 1. Every time a feature was complete we felt something major was done and we are one step closer to completion, in comparison to not knowing if it will work or not in the end (difficult debugging). We kept designing and adding new features as we saw fit because the core design and approach allowed us to do that.

We did not expect the project to take a long time as the theory part is not that complicated. With a proper design it could be done efficiently. But we had many problems with debugging the code when even the simplest inheritance did not work, terrain did not align and objects did not display. The lack of experience initially really slowed us down. But after many hours of debugging we overcame almost everything.

Task time Estimates Actual Time Reasons

Overall effort 40~ 100~ Spent many evenings tackling compilation errors and display bugs.

Researching and Design of Project

1h 2h Kept thinking of cool new things we could add as we progressed.

Design of code 4h 8h The design was fairy simple but

limitations of C/C++ made us redesign some areas.

Implementation

20h 40h Difficulty in making a proper initial framework. had to restart multiple time. Lack of experience in both OpenGL and C/C++ lead to many errors.

Integration and testing

5h 30h Too many bugs that do not make sense. Value adjustments to make the terrain and object look better. Many small things. Finding problem with perlin alignment took days of testing.

Incorporation of special features

8h 16h The special feature was not as hard to develop as making it work in conjunction with other features (overlapping textures, shaders...).

Other 4h 6h Writing the report. A lot of final touches.

Table 1: Project Schedule ­ this table presents the estimated work time vs. the actual time that it took to complete the tasks. The noted times are per person. Around half of the work was done together.

December, 2015 Page 11 of 12

Page 12: ProceduralTerrainGeneration

Project Report “Procedural Terrain Generation” COMP 3009

4. Grade (0.25 page) 0­50 – Fail 50 – 60 Fail to Poor (gray zone) 60 – 70 Poor to almost Good 70 – 80 Almost good ­ Good 80 – 90 Good to Very Good 90 – 100 Very good to Excellent

90. We started with a smaller feasible goal and incorporated more features as we went along. Those features make the overall project better little by little, up to the point of having a ready product to show everyone. But there are a couple minor negatives. Not perfect chunk connections. The rotor is missing diffused light. Overall the goal was met and the desired functionality and effect is there. Almost perfect.

5. Conclusions (0.5­1 page)

We have learned a lot from applying our knowledge from class to programming something major. After fighting compilation errors and bugs for days we understand the flow of OpenGL much better as well as the limitations of C/C++ compared to other languages (Java). Overall OpenGL is straight forward once you understand how to implement what is needed. The project taught us the insides of how terrain generation works and the little things that get in the way such as loading times for chunks, managing chunks, alignment, finesse of mesh (more triangles in a smaller area give a smoother terrain). And of course lighting makes a scene much better looking.

December, 2015 Page 12 of 12