Come on! Feel the noise! Part 2

This is my article for beginners who wants to understand 'noise()' and want to know how to use it. In part 1, I explained the character of noise() and made some still images. In this part 2, we will challenge to make some animation with noise().



Note.
I only explain the 'noise()' function in Processing and p5.js.
The example codes in this article are written in Processing. And I linked to the OpenProcessing for codes of p5.js. And I will share these codes under creative commons CC0 (except example works). Please feel free to use these codes.

Let me show you how can I enjoy creative coding with 'noise()' in Processing and p5.js and let's enjoy with me to do creative coding using 'noise()'! 😀

 

The dimension of time.

The 1D, 2D, and 3D noise, 'D' means dimension, but you do not necessarily associate with the line, the plane surface, and the solid shape.
For example.

      fill(noise(i * j * 0.01) * 360.0, 80.0, 90.0, 100.0);
This 1D noise creates plane surface looks.
An image that was created with 1D noise.

In this example, The 2D noise creates one-dimensional lines.

      float y = noise(i, j) * 100 + j * h;
Some lines that was drew with 2D noise.
You can see that 'i' means line length and 'j' means line number.

Let's see this line number, top to bottom, as the past to the future.

This is the animation with 'noise()'!
Now, you can see that 'j' means time. The second dimension = time.

This dimension of time is the key to the animation with 'noise()'.

 

Let make a 2D noise animation.

Let's make this still image to the animation.

A still image that was drew with 1D noise.
We used a 1D noise like this.
noise(i * j * 0.01)
To make this animate, we add a time dimension to make the 1D noise to the 2D noise.
Instant done!
noise(i * j * 0.01, t) // 't' means time
You can define 't' as frameCount number.
  float t = frameCount;
The animation in Processing/p5.js is a kind of flipbook. So the animation smoothness depends on frames per second (fps). We can specify the fps with 'frameRate()';
Now, we specify '10' fps. Do not forget to comment out the 'noLoop()'.
  // noLoop();
  frameRate(10);

Here is the code. I made the matrix size larger to be able to see the moving well.


/**
 * Come on! Feel the noise! Part 2
 * Animation : With the same parameter absolute value.
 * 
 * @author @deconbatch
 * @version 0.1
 * @license CC0 1.0 https://creativecommons.org/publicdomain/zero/1.0/deed.ja
 * Processing 3.5.3
 * 2020.11.07
 */

void setup() {
  size(640, 480);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  //  noLoop();
  frameRate(10);
  
  background(0.0, 0.0, 90.0, 100.0);
  stroke(0.0, 0.0, 0.0, 100.0);
  strokeWeight(1.0);
}

void draw() {
  int div = 20;
  float w = width * 0.5 / div;
  float h = height * 0.5 / div;

  float t = frameCount;
  
  translate(width * 0.5, height * 0.5);
  for (int i = -div; i < div; i++) {
    for (int j = -div; j < div; j++) {
      float x = i * w;
      float y = j * h;
      fill(noise(i * j * 0.01, t) * 360.0, 80.0, 90.0, 100.0);
      rect(x, y, w, h);
    }
  }
}

Link to the p5.js code on OpenProcessing.

Let's run!

Oops! It's too rough! 😖

Then? Yes! We should make the change rate of a parameter smaller.
It's rough along time. So let's make the change rate of 't' the time dimension smaller.

  float t = frameCount * 0.05;

Yes! Nice smoothness!

Putting some flavor, it becomes tasty!


 







Let make an animation with 3D noise.

Next, let's try to animate the still image that we made it with 2D noise in part 1.

An image that was drew with 2D noise.
In the same way, we can add the time dimension to the 2D noise and make it to the 3D noise.
    let s = noise(x * 0.005, y * 0.005, t);
Here is the moving example. I changed the rectangles to the circle.


/**
 * Come on! Feel the noise! Part 2
 * Animation : THIS IS THE 2D NOISE!
 * 
 * @author @deconbatch
 * @version 0.1
 * @license CC0 1.0 https://creativecommons.org/publicdomain/zero/1.0/deed.ja
 * Processing 3.5.3
 * 2020.11.07
 */

void setup() {
  size(640, 480);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  //  noLoop();
  frameRate(10);

  background(0.0, 0.0, 90.0, 100.0);
  fill(220.0, 90.0, 60.0, 100.0);
  stroke(40.0, 60.0, 90.0, 100.0);
  strokeWeight(5.0);
}

void draw() {
  int divX = 16;
  int divY = 12;
  float w = width  / divX;
  float h = height / divY;

  float t = frameCount * 0.05;

  translate(w * 0.5, h * 0.5);
  for (int i = 0; i < divX; i++) {
    float x = i * w;
    for (int j = 0; j < divY; j++) {
      float y = j * h;
      float s = noise(x * 0.005, y * 0.005, t);
      ellipse(x, y, s * w, s * h);
    }
  }
}


Link to the p5.js code on OpenProcessing.

You may have got a hang of it. Then we'll try to make some animation with a new idea.

At first, we make something like this with 1D noise.

The curve thaw was made with many circles.

Placing circles side by side.

A line that was made with many circles.

Changing angle with noise one by one. The parameter of 1D noise is the number of circles. Then, it becomes a smooth curve.

A smooth curve that was made with 1D noise.

Next, we draw many lines.

Many lines with 1D noise.

If we used 1D noise, all the lines are the same curve. So, we add the number of lines to the 2nd parameter of noise.
With this 2D noise, the lines will be like this.

Many lines with 2D noise.

Finally, we add the time dimension. The creepy animation complete!
How creeeeeeeepy! 😱


/**
 * Come on! Feel the noise! Part 2
 * Animation : Creepy one...
 * 
 * @author @deconbatch
 * @version 0.1
 * @license CC0 1.0 https://creativecommons.org/publicdomain/zero/1.0/deed.ja
 * Processing 3.5.3
 * 2020.11.07
 */

void setup() {
  size(640, 480);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  frameRate(24);

  fill(220.0, 90.0, 60.0, 100.0);
  stroke(40.0, 60.0, 90.0, 100.0);
  strokeWeight(5.0);
}

void draw() {
  int lines = 5;
  int steps = 16;
  float w = min(width, height) * 0.5 / steps;
  float t = frameCount * 0.01;

  background(0.0, 0.0, 90.0, 100.0);
  translate(width * 0.5, height * 0.5);
  for (int l = 0; l < lines; l++) {
    rotate(TWO_PI / lines);
    pushMatrix();
    for (int s = 0; s < steps; s++) {
      float theta = map(noise(l, s * 0.1, t), 0.0, 1.0, -0.5, 0.5) * PI;
      translate(0.0, w);
      rotate(theta);
      ellipse(0.0, 0.0, w, w);
    }
    popMatrix();
  }
}

Link to the p5.js code on OpenProcessing.

Here is the 3D noise. 'l' means lines, 's' means circles, and 't' means the time.
I multiply 's' by 0.1 to make the curve smooth. I left 'l' rough on purpose to get very different noise values with each line.

float theta = map(noise(l, s * 0.1, t), 0.0, 1.0, -0.5, 0.5) * PI;
I said "You do not necessarily associate with the line, the plane surface, and the solid shape" before. This animation is a good example of it I think.

It is fun to see how this animation changes its look by trying to change the change rate of a parameter.
You may see where of the code I changed? 🤔

 

Transcend the dimension!

Now we can make an animation by adding the time dimension parameter to the 'noise()' that is used to make a still image.

...but, wait!
What can I do if I used 3D noise to make a still image?

The 'noise()' function of Processing/p5.js has less than three parameters.

noise() \ Language (API) \ Processing 3+
noise() | reference | p5.js

We can't add the time dimension as the 4th dimension. What can we do?
I don't know, so let's think while making something!

At first, we'll make a still image with 3D noise like this.
It's just like layers of 2D noise still image we made in part 1. The number of layers is the 3rd parameter of the 'noise()'.

Let's lay over the red, green, and blue layers.

The red layer that was drew with 2D noise.
The green layer that was drew with 2D noise.
The blue layer that was drew with 2D noise.
Three layers that was drew with 2D noise.

 

Here is the code. I wrote this code for animation, but it does not move yet that because I did not apply the time dimension to the 'noise()'.


/**
 * Come on! Feel the noise! Part 2
 * Animation : The layers with 2D noise.
 * 
 * @author @deconbatch
 * @version 0.1
 * @license CC0 1.0 https://creativecommons.org/publicdomain/zero/1.0/deed.ja
 * Processing 3.5.3
 * 2020.11.07
 */

void setup() {
  size(640, 480);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  frameRate(24);

  noStroke();
}

void draw() {
  int divX = 40;
  int divY = 30;
  int divZ = 3;
  float w = width  / divX;
  float h = height / divY;
  float t = frameCount * 0.02;

  background(0.0, 0.0, 90.0, 100.0);
  translate(w * 0.5, h * 0.5);
  for (int z = 0; z < divZ; z++) {
    fill(z * 360.0 / divZ, 60.0, 80.0, 100.0);
    for (int i = 0; i < divX; i++) {
      float x = i * w;
      for (int j = 0; j < divY; j++) {
        float y = j * h;
        float s = noise(x * 0.005, y * 0.005, z + t);
        if (s < 0.5) {
          ellipse(x, y, s * w * 2.0, s * h * 2.0);
        }
      }
    }
  }
}


Link to the p5.js code on OpenProcessing.

 

The 'noise()' has three parameters. So we can not add any.

        float s = noise(x * 0.005, y * 0.005, z);
So, how we can add the element of time?
Let me try to add to the first parameter.
noise(x * 0.005 + t, y * 0.005, z);

Ummm. It's changing along the time, but it just looks scrolling.
'x + t' means increasing 'x' but not time passing.

The second parameter (y) will be the same result. So, we can move it up and down, left and right, and obliquely.

We can make the creepy animation synchronized something.

 

I got sidetracked. 😅
How about this for dimension lack problem?

noise(x, y, z + t)

Oh! It looks good!
It's scrolling on the z-axis, so the plane surface looks changing with 2D noise. You can imagine that you are pulling a plane surface in three-dimensional noise space.

It works for the two-dimensional plane surface, but not for the three-dimensional solid shape. You'll see the three-dimensional solid shape is just scrolling.
I think we should use noise(x, y, z) to draw an image and we want to use 't' independently as time.
Maybe this?

noise(noise(x, y, z), t)

Ummmmmmm! It does not look like scrolling, but it is awkward moving.
'noise(x, y, z)' returns fix value and do not change along the time, so this cause this wooden movement?

Then, how about this?

noise(noise(x, y, t), z)
We should go more further? Adding 't' even more to the outside noise!
noise(noise(x, y, t), z, t)

...Now, I can't make out what it's all about.

To tell the truth, I have no good idea about this.
It's enough with 'noise(x, y, z + t)' for this example. I think a suitable answer will differ depending on one's purpose.

We used nested 'noise()' this time. And using some other function may be worth considering.

noise(func(x, y, z), t)

If you had a good idea, please let me know.

 

The noise() tips.







A substitution for an array of random values.

One of the 'noise()' feature is

'noise()' returns the same value for the same parameter absolute value.

And if you specify the change rate of a parameter big, 'noise()' returns almost random values.
So, you can use 'noise()' as an array of random values when you treat a 'noise()' parameter as an array's index.
It will spend too much CPU time though.

 

Want the same set of noise values.

'noise()' returns different results for each execution. So you'll get a different set of noise values for each execution of your code.
It will be fun to see the different image drawing for each execution. But when you are tuning the parameters to polish your works, the same set of noise values will suit your purpose.

You can use 'noiseSeed()' in this situation.

noiseSeed() \ Language (API) \ Processing 3+
noiseSeed() | reference | p5.js

You can get the same set of noise values every execution if you specified like this.
noiseSeed(0);

And when you change the parameter of 'noiseSeed()', you can change the set of noise values.

 

Want more dynamic changing values.

You'll see the set of return values of 'noise()' sometimes changes widely and sometimes changes narrow.

A line that was drew with 'noise()'
A line that was drew with 'noise()'

If you want to get widely changing values like from 0.0 to 1.0, you can normalize with the min/max value of 'noise()'.
Though, you should treat the problem that it tends to cause rough changing.

 

Want to get cyclic noise values.

Sometimes you will want to get cyclic noise values.
Not like this.

Not noise values like this.

But this.

The cyclic noise values like this.

One of the answers is using parameters of tracks of a circle in 2D noise. (Sorry, it is written in Japanese.)

 

Mind the repeated results.

'noise()' has the character that it returns repeated results in the case of long-range values of the parameters.

It's a pattern that was drawn with 2D noise.

noise(x, y);

It looks normal.

But when I double the area?

You can see the repeated pattern.
You don't have to worry about this in many cases. But you had better mind when you make a big scale image.

 

Fun time! Let's make some animations with 'noise()'.

Let's make an animation with your code that makes a still image in Come on! Feel the noise! part 1.

If you had no idea, how about making an animation that draws a moving point with 1D noise? Or how about to draw a circle that changes it's size with 1D noise, and increase that circle and changes these size with 2D noise? It will be fun when you clear with 'background()' before every drawing, and it will be fun also when you do not clear at all.

And these tweet of mine are various example works with 'noise()'. Please use it as reference.


 Thank you for reading! Enjoy your creative coding with 'noise()'! 😀👍