logoWASM TerrainGeneration

@sirajchokshi / Repository

Table of Contents

  1. About
  2. Usage
  3. Architecture
  4. Bugs/Compatibility

About

This terrain generator uses Perlin noise and was built with WebAssembly, C, and JavaScript. My motivation to build this stems from my interest in producing complex behavior from simple systems. While noise generation is not entirely simple, to the perceiver, giving a noisy map even a little bit of context (e.g. letting the values represent depth or height) forms an entirely new perspective. Assigning meaning to numerical values can elevate a noise function to a model resembling the natural world.

Usage

Movement

Move by ten sudo-pixels (i.e. one coordinate value) using the directional navigation buttons. Alternatively, go to a specific position by entering two non-negative integers and clicking the button. The left plus (+) and minus (-) buttons zoom, in and out respectively, relative to the top left pixel of the map.

The keyboard can also be used to navigate the terrain with the following controls.

Seed

The initial seed is randomized when the document loads, but you can manually enter new seeds or load up previously encountered ones for the same generation.

While any string can be entered as a seed, repeat values may be found as strings, that are not already positive integers, are hashed into an integer value and the safe integer limit can be passed when using extraneous or lengthy strings. When this occurs the seed falls back to the absolute value of the integer wrap-around.

Overriding the integer limit check can be done by simply entering an integer larger than 253. At this point significant stretching and artifacting is noticeable.

Limitations

You cannot navigate towards or go to negative values using the UI (all there is to see is artifact clutter). Additionally artifacts begin appearing as X and Y approach infinity.

Architecture

Algorithm

Using a simplified 2D Perlin noise algorithm implemented in C to calculate depth information for each point value. For speed and simplicity, the program works optimally when X, Y ∈ {a | 0 ≤ a ≤ 15000, a ∈ Z} where X and Y are integers representing horizontal and vertical position values respectively. The C algorithm has been compiled into WebAssembly (WASM) to run as a binary executable in the web browser. The compiled WASM module is able to provide unmatched speed when compared to JavaScript.

Chunking

Each coordinate position in the interface represents a 10 by 10 fat pixel chunk which are kept in state to limit the calculations necessary for rendering movements smaller than the viewport. Chunking also reduces the risk of memory leaks in the WebAssembly module resulting in a dead tab.

Rendering

The last, and arguably most important, part of a terrain generator is rendering. Graphics are what contextualize a 2D array of integers into a visual that can be perceived as an aerial view of a landscape. A constant WATER_LEVEL is used to find what is present at each height of the terrain and assign both a color, for material, and an accenting shade for height or depth. Lastly, some shades are randomly altered to add more texture to the map.

This process is repeated for every fat pixel on the display and uses JavaScript to draw each chunk onto an HTML5 canvas. The final fat pixel density is determined by the RESOLUTION constant currently set to 100 for the amount of colored squares of each axis. Increasing this constant to a high number (e.g. 400) would increase perceived resemblance to an organic map, but with additional noise values to estimate and an O2 iteration of the map on render time this process becomes exponentially complex in both time and space. A better solution to achieve a more organic shapes would be to estimate interpolated curves between the points.

Bugs/Compatibility

Did something go wrong? Make sure you have a compatible browser. This program works with all web browsers supporting WebAssembly and HTML5 Canvas. I have compiled a list of popular browser versions in the table below. If your browser should be compatible and you are still facing errors open an issue on Github or feel free to shoot an email to sirajsc2@illinois.edu.

Browser Minimum Version
Firefox 58
Chrome* 61
Safari Not Compatible
Edge 16
Opera 47

* On Chrome versions between 70 and 74 enable threads for better performance.

  1. WebAssembly. (2020, April 22). Retrieved May 1, 2020, from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/WebAssembly
  2. WebAssembly.instantiateStreaming(). (2020, May 7). Retrieved May 7, 2020, from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming
  3. WebGL API. (2020, March 31). Retrieved May 1, 2020, from https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API