Lab: Noisy Globe

How to 3D

Chapter 11: Noise

Lab: Noisy Globe

In this chapter, you've been learning how to disrupt perfect surfaces with organic randomness. Normally we'd have a lecture on the reading and then a lab. Since our labs have been converted to work time for our games, and since noise begs to be experimented with, we're going to have an early lab. We're going to generate terrain for a fake planet and then project it on a real sphere in the Science on a Sphere lab.

Requirements

Your challenge is to build a globe terrain generator. Follow these steps:

Clone an existing renderer into a new renderer named noisy-globe.
Delete all files but index.html and main.ts.
In index.html, remove the canvas element and add in an img element with ID image.
In main.ts, remove all globals and all functions but initialize, and clear the body of initialize.
In lib/noise.ts, paste in this 3D noise generator.
In initialize, call the provided noiseGlobe function to get a Field2 full of 3D noise values projected onto a 2D raster.
Create a flat Uint8ClampedArray that has the same resolution as the field but has four bytes for each pixel.
Iterate through the array and field simultaneously, mapping each noise value to a color. Divide up the noise levels into various bands. Lowest noise values map to water, low to sandy coast, medium to grassland, high to mountains, and highest to snowcaps. For each level, choose two colors, one for the small end and one for the big end. Lerp between these two colors by using the noise value as a proportion within the value range. For example, if the noise value is 0.6 and grasslands span [0.55, 0.7], then we'd lerp \(\frac{0.05}{0.15} = \frac{1}{3}\) of the way between the two colors.
Use the array to set the image's pixel data with this code:
TypeScript
const image = document.getElementById('image') as HTMLImageElement;
const imageData = new ImageData(pixels, width, height);
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
canvas.getContext('2d')!.putImageData(imageData, 0, 0);
image.src = canvas.toDataURL();
const image = document.getElementById('image') as HTMLImageElement;
const imageData = new ImageData(pixels, width, height);
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
canvas.getContext('2d')!.putImageData(imageData, 0, 0);
image.src = canvas.toDataURL();
Replace the identifiers pixels, width, and height as necessary to match the identifiers you have chosen.
Tweak the colors, radius, and number of octaves until you get a pleasing terrain with some interesting detail.
Right-click on the image, save it your computer, and submit it in the #lab channel on Discord.
Tell your instructor, and he'll project your terrain onto the Sphere.

Submission

To receive credit for your lab work, follow these steps:

Non-host, download the noisy-globe folder before the host closes the session.
Share your terrain image in a post in the #lab channel in Discord. Tag your group members with @.
Push your code to your individual GitHub repository that your instructor made for you.
← WaterLab: Game Step →