Generative 3D Terrain With Perlin Noise

Generative 3D Terrain With Perlin Noise

Another Shiffman coding challenge. This time I’m generating 3D terrain that’s randomized using Perlin Noise to create a natural variation in the landscape. Code below the jump.

More #codingrainbow. Generative terrain with Perlin Noise

A video posted by Gabe Weintraub (@gabeweintraub) on


Generative 3D Terrain


	int cols, rows;
	int scl = 20; //scale
	int w = 2000;
	int h = 1600;

	float[][] terrain;
	float flying = 0.0;

	int backgroundValue = 0;
	int redValue = 255;
	int blueValue = 0;
	int greenValue = 0;

	void setup() {
	  size(1000, 1000, P3D);

	  cols = w/scl;
	  rows = h/scl;
	  terrain = new float[cols][rows];


	}

	void draw() {
		flying -= 0.1;
		background(0);
		lights();
		stroke(255);
		//noStroke();
		fill(redValue, greenValue, blueValue);
		//start at red and go to yellow
		 if( greenValue<255 && redValue==255 && blueValue==0){
		   greenValue++;
		  }
		  //go from yellow to pure green
		  if(greenValue == 255 && redValue>0){
		    //redToGreen = false;
		   redValue--;
		  }
		  //go from green to cyan/bluish-green
		  if(redValue==0 && greenValue==255 && blueValue<255){
		    blueValue++;
		  }
		  //go from bluish-green to blue
		  if(blueValue==255 && greenValue>0){
		   greenValue--;
		  }
		 // go from blue to violet
		  if(redValue < 255 && greenValue==0 && blueValue==255){
		    redValue++;
		  }
		  //go from violet to red
		if(redValue == 255 && blueValue>0){
		  blueValue--;
		}


	  float yoff = flying;
	  for (int y = 0; y < rows; ++y) {
	  	float xoff = 0.5;
	  	for (int x = 0; x < cols; ++x) {
	  		terrain[x][y] = map(noise(xoff, yoff), 0, 1, -100, 150);
	  		xoff += 0.15;
	  	}
	  	yoff += 0.15;
	  }
	  //noFill();
	  translate(width/2, height/2+50);
	  rotateX(PI/3);
	  //frameCount(1);
	  translate(-w/2, -h/2);
	  for (int y = 0; y < rows-1; ++y) {
	  	beginShape(TRIANGLE_STRIP);
	  	for (int x = 0; x < cols; ++x) {
	  		vertex(x*scl, y*scl, terrain[x][y]);
	  		vertex(x*scl, (y+1)*scl, terrain[x][y+1]);
	      //rect(x*scl, y*scl, scl, scl);
	    }
	    endShape();
	  }
	}