Beginner’s Guide to Creative Coding using p5js: Noise

p5js-noise1
Ken Perlin, Perlin Noise

The previous blog in this series gave introduction to creative coding and p5js basic structure. Going further, in this blog, we are going to learn about one of the most used functions in p5js - noise. It is the soul of p5js. You might say what is so interesting about this ‘noise’ function? To understand this, let’s take a ride back to history.

Perlin noise is a type of noise generated by an algorithm developed by Ken Perlin in 1983. He devised this new type of noise texture when he was told to come up with a realistic texture for the movie ‘TRON’. Noise is basically random() function in p5js but more harmonic. So, when you are looking for random numbers but want those numbers to deviate less or in a more ‘harmonic’ way, you use noise. To understand the difference between random() and noise() functions in p5js, let’s go through this demo.

function setup() {
  createCanvas(640, 480);
}

function draw() {
  background(220);
  randomSize();
  noiseSize();
  noLoop();
}

function randomSize(){
  for(let i = -3; i <= 3; i++){
    ellipse(width/2 + 50*i, height/2 - 50, random(30));
  }
}

function noiseSize(){
  let nx = 0;
  for(let i = -3; i <= 3; i++){
    ellipse(width/2 + 50*i, height/2 + 50, noise(nx)*30);
  }
  
  nx += 1;

When you execute this code, you should be able to see two lines of 7 circles with different radius. The first line of circles receives their radii from random() function and second one from noise() function. As you can see, the first line of circles has greater deviation in radius as compared to the second one. The random() function returns the value between 0 and 1 when no argument is passed. When a single argument is passed, it returns a number between 0 and argument. You can also pass two numbers as arguments to receive a number between that range.

random() 		// outputs a number between 0 and 1
random(4) 		// outputs a number between 0 and 4
random(5, 10) 		// outputs a number between 5 and 10`

On the other hand, the noise() function takes a particular number as an argument and returns a number between 0 and 1. If you wish to receive a number between 0 and any other number (say x), you need to multiply the output of the noise() function to that number (x).

noise(4)		//outputs a number between 0 and 1
noise(4)*4		//outputs a number between 0 and 4
map(noise(7), 0, 1, -30, 30)		//outputs a number between -30 and 30

The function map() takes a value and converts it to a new range after taking into consideration the original range. So, in the above line, if the output of noise(7) is 0, the map() will produce an output of -30.

Enough theory, let’s do some creative visualisation.

let nx = 0, ny = 0, centerX, centerY, squareSize = 20, gap;

function setup() {
  createCanvas(800, 800);
  
  centerX = width/2;
  centerY = height/2;
  gap = 1.5 * squareSize;
  
  noStroke();
  fill(20, 200, 0);
}

function draw() {
  background(2);
  
  nx = ny;
  
  for(let x = -8; x <= 8; x++){
    for(let y = -8; y <= 8; y++){
      let t = map(noise(nx), 0, 1, -squareSize/2, squareSize/2); 
      ellipse(centerX + x * gap, centerY + y * gap, squareSize + t);
      nx += 0.2;
    }
  }
  
  ny += 0.03;
}

Here, we are generating a few arrays of ellipses and applying noise() to their radius to give smooth transitions. Try to replace the noise() function with the random() and ellipses with rectangles and then see how the output changes. Go along, play with colors and ellipse sizes. Let’s do one more visualisation before ending the blog. Try this code in p5js editor.

function setup() {
  createCanvas(400, 400);
  noFill();
  stroke(2);
}

function draw() {
  background(220, 40);
  
  beginShape();
  for(let i = 0; i <= width; i++){
    vertex(i, height/2);
  }
  endShape();
}

Can you guess what it does? Here, two functions beginShape() and endShape() are used to create a custom shape by providing coordinates of each vertex of that shape. The structure is such that you begin with beginShape() and then add all the vertices of that particular shape. And at last, you call endShape() to finally conjure up your shape. As you can see, we created a line at the vertical center of the canvas using these functions. Now, let’s add our magic ingredient - noise ✨

let nx = 0;

function setup() {
  createCanvas(400, 400);
  
  noFill();
  stroke(2);
}

function draw() {
  background(220, 40);
  
  beginShape();
  for(let i = 0; i <= width; i++){
    let m = map(noise(nx, i*0.01), 0, 1, -80, 80);
    vertex(i, height/2 + m);
    nx += 0.00005;
  }
  endShape();
}

Can you figure out what causes these nice mountain ridges and fade effect? Try playing with values for nx and noise and see how it changes the sketch. That’s it for this blog. Hope you make your versions of different sketches by using noise().


Leave a Reply

Your email address will not be published. Required fields are marked *