Back

P5 Perlin Noise

This tutorial page is about perlin noise in P5.js, perlin noise is an algorithm based on real life equations of sound that produces semi-random values between 0 and 1. By applying these random values in a graphical application we can create very interesting and unique patterns, in fact the perlin noise algorithm was originally developed by Ken Perlin in order to produce graphics for the movie Tron in 2003. We will be making a perlin noise "flow" program which uses the returned value of perlin noise to set the direction of a set of lines as they move continually through 2d space.

we will start by simply setting up a basic P5.js project.
						
<!DOCTYPE html>

<html>
	<head>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.sound.js"></script>
	</head>

	<body>
		<div id="canvasHolder"></div>
	</body>
</html>
					
var canvas;

function setup(){
	canvas = createCanvas();
	canvas.parent('canvasHolder');
}

function draw(){
	
}
					
I always suggest setting up your external librarys first, before you get to the 'point of no return'. This is the point where you would have to erase huge chunks of your code in order to deal with an issue with your library that you wouldn't realise untill late in the development cycle.

The next thing you need to know about perlin noise is that it takes three dimentions of input. In order to produce a random value it takes in three seperate numbers and runs calculations in order to ensure your results are not completely random, we will be subbing in our x, y coordinates as our "dimetions" of input. In P5 the third dimention will automatically default to 0 if we pass in two values, but if you want to you can also pass in something like time as your third dimention of input for different results. Here is the function that returns our perlin noise value:
						
var value = noise(x, y, z);
var 2d_value = noise(x, y);

					
Also, note that this algorithm also takes a 'seed' value, which is automatically generated by p5. If you want to set the seed manually you can call the function noiseSeed(); and pass in any number. Using the same seed twice will result in exactly the same results each time. This can be a good thing or a bad thing depending on what you are doing so keep this in mind.

Now that we have an idea of how perlin noise works there are a few steps before we put it in action. First we need to create a class to hold our line origins, and look at some basic trigonometry with radians.

var xZoom = 0.02;
var yZoom = 0.02;

class lineOrigin {
	constructor(x, y){
		this.x = x;
		this.y = y;
		this.direction;
		this.speed = 10; // pixels traveled per frame
	}

	update(){
		this.direction = noise(this.x * xZoom, this.y * yZoom) * (2*Math.PI); // 2PI radians is same as 360 degrees
		var distanceX = Math.cos(this.direction) * this.speed;
		var distanceY = Math.sin(this.direction) * this.speed;

		var newX = this.x + distanceX;
		var newY = this.y + distanceY;

		stroke(255, 255, 255);
		line(this.x, this.y, newX, newY);

		this.x = newX;
		this.y = newY;
	}
}
						
					
Alright, so now that we have our line origin class all we need to do is create instances on the canvas and update them until a patern emerges!
						
var lineOrigins = [];
for (var x = 0; x < 500; x+=15){
	for (var y = 0; y < 500; y+=15){
		lineOrigins.push(new lineOrigin(x, y));
	}
}

var timeDrawing = 0;
function draw(){
	timeDrawing++;
	if (timeDrawing <= 300){
		for (var i = 0; i < lineOrigins.length; i++){
			lineOrigins[i].update();
		}
	}
}

					
Now you should be getting results! But they may be kinda.. boring.. Why is that? Well there is actually a function that I haven't mentioned yet:

function setup(){
	canvas = createCanvas(500, 500);
	canvas.parent('canvasHolder');

	noiseDetail(10, 0.02);
}
					
This noiseDetail finction is one of he most important parts of perlin noise. Remember how I mentioned that perlin noise is based on real noise equations, well the first input is the octaves, or loudness of the sound generated. The second input is the dropoff value, or how quickly the noise dissipates. Using these you can get extremely varied and interesting results. So have fun with this and find some new uses for perlin noise!