Arvutiteaduse instituut
  1. Kursused
  2. 2016/17 sügis
  3. Arvutigraafika (MTAT.03.015)
EN
Logi sisse

Arvutigraafika 2016/17 sügis

  • Main
  • Lectures
  • Practices
  • Projects
  • Exam
  • Results
  • Links

Complex Procedural Terrains

Jan Aare van Gent, Kerstin Äkke

Poster for the project

Repository

  • https://bitbucket.org/jangent/procedural-terrain-generation/

Introduction

The purpose of this project is to procedurally generate a terrain that has overhangs and caves not just changes in height.

Initial planning

We hope to make the project in UE4, but if we find it too difficult or the performance lacking, there is a chance we will switch to regular OpenGL/GLSL. It's too bad UE4 doesn't seem to support custom vertex and geometry shaders. We might be able to get similar functionality by using UE4's flagship material nodes (pixel shaders) for all shading purposes or we could use 3rd party plugins.

The project will be a demo project demonstrating how to generate complex procedural terrain on the fly. The terrain will be generated around the player/camera. If possible, we will add the ability for the camera to move freely around, while at the same time, generating new terrain.

The project will be divided into two parts:

  1. Block/polygon generation around the camera/player
  2. Density function implementation

Result

We use Unreal Engine 4, but switched from blueprints to c++ scripting. Block generation is independent from camera location. Decided to use RuntimeMeshComponent plugin instead of ProceduralMeshComponent.

Algorithm summary

Most of the algorithm used is also described in the first chapter of GPUGems3. It had to be modified due to lack of access to shaders in Unreal Engine.

  1. Load lookup tables
  2. Create noise volumes
  3. Calculate bottom left front corners of all blocks.
  4. Run marching cubes algorithm for an unbuilt block

Marching cubes

We use the Marching Cubes algorithm for mesh generation on each block. The density field (or the scalar field) will be generated via a density function.

  1. Based on voxel location calculate density values for unchecked corners
  2. Store these values in density volume
  3. Calculate case number
  4. Based on voxel location and case number calculate triangle vertices that haven't already been added to the vertices list
  5. Store these new vertices to an array and map their index
  6. Calculate and store normal of each new vertex
  7. Calculate and store color of each new vertex
  8. Add indices of triangle vertices to triangles array in correct order
  9. Create new mesh section using previously created arrays

Note: may result in some floating rocks.

Intermediate results 1

Program generates terrain for small area. Process is rather slow, no normals are set.


density = -pos[2] + 100 + sin(pos.X*100) * 20 + sin(pos.Y * 100)*20 + 40*(sin(pos.X*pos.X+pos.Y*pos.Y))

Intermediate results 2

Area is quite large, but not endless. Blocks further away from center have less voxels, that causes some problems around edges. Water on the floor of the scene.


example of generated terrain

example of generated terrain with water

Final result

Terrain is made up from 24x24x2 blocks. Each block contains 30x30x30 voxels with edge length of 20. The density function uses 4 noise volumes. Normals are calculated for each vertex via a gradient. Framerate has improved compared to intermediate results.


example of generated terrain

Materials

  • https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch01.html
  • http://www.geisswerks.com/about_terrain.html
  • https://en.wikipedia.org/wiki/Marching_cubes
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Tartu Ülikooli arvutiteaduse instituudi kursuste läbiviimist toetavad järgmised programmid:
iktp regionaalarengu fondi logo euroopa sotsiaalfondi logo tiigri�likooli logo it akadeemia logo