If you're seeing this message, it means we're having trouble loading external resources on our website.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

Lesson 3: Noise

# Two dimensional noise

This idea of noise values living in a one-dimensional space is important because it leads us right into a discussion of two-dimensional space. Let’s think about this for a moment. With one-dimensional noise, we have a sequence of values in which any given value is similar to its neighbor. Because the value is in one dimension, it only has two neighbors: a value that comes before it (to the left on the graph) and one that comes after it (to the right).
Two-dimensional noise works exactly the same way conceptually. The difference of course is that we aren’t looking at values along a linear path, but values that are sitting on a grid. Think of a piece of graph paper with numbers written into each cell. A given value will be similar to all of its neighbors: above, below, to the right, to the left, and along any diagonal.
If you were to visualize this graph paper with each value mapped to the brightness of a color, you would get something that looks like clouds. White sits next to light gray, which sits next to gray, which sits next to dark gray, which sits next to black, which sits next to dark gray, etc.
This is why noise was originally invented. You tweak the parameters a bit or play with color to make the resulting image look more like marble or wood or any other organic texture.
Let’s take a quick look at how to implement two-dimensional noise in ProcessingJS. If you wanted to color every pixel of a window randomly, you would need a nested loop, one that accessed each pixel and picked a random brightness.
To color each pixel according to the `noise()` function, we’ll do exactly the same thing, only instead of calling `random()` we’ll call `noise()`.
``var bright = map(noise(x,y), 0, 1, 0, 255);``
This is a nice start conceptually—it gives you a noise value for every (`x`,`y`) location in our two-dimensional space. The problem is that this won’t have the cloudy quality we want. Jumping from pixel 200 to pixel 201 is too large of a jump through noise. Remember, when we worked with one-dimensional noise, we incremented our time variable by 0.01 each frame, not by 1! A pretty good solution to this problem is to just use different variables for the noise arguments. For example, we could increment a variable called `xoff` each time we move horizontally, and a `yoff` variable each time we move vertically through the nested loops.
We’ve examined several traditional uses of Perlin noise in this tutorial. With one-dimensional noise, we used smooth values to assign the location of an object to give the appearance of wandering. With two-dimensional noise, we created a cloudy pattern with smoothed values on a plane of pixels. It’s important to remember, however, that Perlin noise values are just that—values. They aren’t inherently tied to pixel locations or color. Any example in these tutorials that has a variable could be controlled via Perlin noise. When we model a wind force, its strength could be controlled by Perlin noise. Same goes for the angles between the branches in a fractal tree pattern, or the speed and direction of objects moving along a grid in a flow field simulation, like in the program below.
We began the last tutorial by talking about how randomness can be a crutch. In many ways, it’s the most obvious answer to the kinds of questions we ask continuously—how should this object move? What color should it be? This obvious answer, however, can also be a lazy one.
As we finish off this tutorial, it’s also worth noting that we could just as easily fall into the trap of using Perlin noise as a crutch. How should this object move? Perlin noise! What color should it be? Perlin noise! How fast should it grow? Perlin noise!
The point of all of this is not to say that you should or shouldn’t use randomness. Or that you should or shouldn’t use Perlin noise. The point is that the rules of your system are defined by you, and the larger your toolbox, the more choices you’ll have as you implement those rules. The goal of these tutorials is to help you fill your toolbox.  If all you know is one type of randomness, then all of your designs will include only one type of randomness.  Perlin noise is another tool for randomness you can use in your programs.  After a little practice with Perlin noise we will move on to another type of tool- vectors!
This "Natural Simulations" course is a derivative of "The Nature of Code" by Daniel Shiffman, used under a Creative Commons Attribution-NonCommercial 3.0 Unported License.

## Want to join the conversation?

• Could someone please really explain exactly what map is doing? I have looked at others answers to that question and looked it up online, but I still can't get it.
• Using the Fahrenheit scale, we know that water freezes at 32°F and boils at 212°F. Using the Celsius scale, we know that water freezes at 0°C and boils at 100°C. So, what is the Celsius equivalence of 86°F?
``    var c = map(86, 32, 212, 0, 100);    println(c);``

What is the Fahrenheit equivalence of -40°C?
``    var f = map(-40, 0, 100, 32, 212);    println(f);``

Exactly, for you Algebra-1 fans, `y = map(x, x1, x2, y1, y2)` allows you to specify a linear equation passing through the points `(x1, y1)` and `(x2, y2)` and then allows you to compute any `y` where `y` = m`x` + b, where m and b are uniquely derived from the two points. Only, you don't have to do any algebra.
``var map = function(x, x1, x2, y1, y2) {    var m = (y2 - y1) / (x2 - x1);    var b = y1 - m*x1;    return m*x + b;};``
• Why does my program work when the for loop rules are " < 100 " , but when I change that to " <400 " it stops animating?
``var zoff = 0.0;draw = function() {    var xoff = 0.0;for (var x = 0; x < 100; x++) {    var yoff = 0.0;    for (var y = 0; y < 100; y++) {        var bright = map(noise(xoff, yoff, zoff), 0, 1, 0, 255);        stroke(bright, bright, bright);        point(x, y);        yoff += 0.01;    }    xoff += 0.01;}zoff += 0.01;};``
• Because this code is way too slow. Point is quite slow and you're calling it way too many times.
One way to solve this problem is to change pixels directly, which is a lot faster. I've done a program a while ago quite similar to this one that uses direct pixel manipulation to work.
• I'm trying to understand the noise concept. I get the part about get texture out of the noise function, but I don't see from the examples how the color of the object is defined.
• What am I doing wrong for the challenge: Animated Noise?
It says this: "We want to smoothly animate the noise - so that the noise is moving around over time, not changing completely each time."
This is my code:
``var xOff = 0.0;var zOff = 0.0;draw = function() {    for (var x = 0; x < 100; x++) {        var yOff = 0.0;        for (var y = 0; y < 100; y++) {            var bright = map(noise(xOff, yOff, zOff), 0, 1, 0, 255);            stroke(bright, bright, bright);            point(x, y);            yOff += 0.01;        }    xOff += 0.01;    }        zOff += 0.1;};``
• If you move `var xOff = 0.0;` inside your draw function, it'll have the `xOff` value reset with each frame, smoothing out the animation.
• Khan Academy said that: We want to smoothly animate the noise - so that the noise is moving around over time, not changing completely each time. Here is my code:
``draw = function() {    for (var x = 0; x < 100; x++) {    var yOff = 0.0;    for (var y = 0; y < 100; y++) {        var bright = map(noise(xOff, yOff, zOff), 0, 1, 0, 255);        stroke(bright, bright, bright);        point(x, y);        yOff += 0.01;    }    xOff += 0.01;}  zOff += 0.01;  };``

Does anyone know what is wrong with the code?
• Try defining your xOff variable inside your draw function, right above your first for loop. If that doesn't fix it, try indenting everything from "var yOff = 0.0;" to the curly bracket right above the "xOff += 0.01;". That should fix the problem.
• Is there a way to fill the clouds (ellipse) with noisy cloud using point function. Please!! I need your help!.
• Maybe you can only draw the point if it falls inside a circle.
``var cloudX = 50;var cloudY = 50;var cloudRadius = 50;var xoff = 0.0;for (var x = 0; x < 100; x++) {    var yoff = 0.0;    for (var y = 0; y < 100; y++) {        if (sq(cloudRadius) > sq(cloudX - x) + sq(cloudY - y)) {            var bright = map(noise(xoff, yoff), 0, 1, 0, 255);            stroke(bright, bright, bright);            point(x, y);        }        yoff += 0.01;    }    xoff += 0.01;}``

Of course, you may want to adjust the if statement to support any ellipse.
• I'm thinking about using noise for terrain generation, and just realized that you can make 2 dimensional noise into a heightmap and use 3 dimensional noise subtractively for caves, ravines, etc. Would that work?
• Yes! A lot of people have alredy done that at Khan. Whenever you see a program that generates terrain, look at the code and you'll likely find noise in there :)