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.

Main content

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).
Nature of Code Image
Figure I.10: 1D Noise
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.
Nature of Code Image
Figure I.11: 2D Noise
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.
Nature of Code Image
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?

  • winston default style avatar for user sloens
    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.
    (37 votes)
    Default Khan Academy avatar avatar for user
    • old spice man green style avatar for user Bob Lyon
      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 = mx + 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;
      };
      (84 votes)
  • leafers ultimate style avatar for user George Georgiev
    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;
    };
    (6 votes)
    Default Khan Academy avatar avatar for user
  • mr pink red style avatar for user Bob Everton
    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.
    (8 votes)
    Default Khan Academy avatar avatar for user
  • piceratops ultimate style avatar for user LordBlaze64 [Read Bio]
    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;
    };
    (6 votes)
    Default Khan Academy avatar avatar for user
  • piceratops tree style avatar for user Cade Brown
    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?
    (7 votes)
    Default Khan Academy avatar avatar for user
    • piceratops ultimate style avatar for user NolanB
      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.
      (3 votes)
  • orange juice squid orange style avatar for user Omeleto
    Is there a way to fill the clouds (ellipse) with noisy cloud using point function. Please!! I need your help!.
    (3 votes)
    Default Khan Academy avatar avatar for user
    • spunky sam blue style avatar for user Dalendrion
      Maybe you can only draw the point if it falls inside a circle.
      I adjusted the code from this page:
      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.
      (11 votes)
  • duskpin ultimate style avatar for user πTom_Pallister π
    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?
    (6 votes)
    Default Khan Academy avatar avatar for user
  • duskpin ultimate style avatar for user Jeanne Coleongco
    Hi there! In the Animated noise Challenge, why does putting 'var xOff = 0.0;' outside the draw function cause the frames to change completely each time 'draw' runs instead of move around slowly? And is it for the same reason that 'var yOff = 0.0;' outside the draw function does the same thing but also sort of squishes the cloud image so it's not so smooth anymore? Thank you very much!
    (6 votes)
    Default Khan Academy avatar avatar for user
  • leaf green style avatar for user Masood Ashrafi
    For project mountain range, if anyone knows where to begin that would help a lot because I am unsure as to whether I use noise or set a random variable first.
    (5 votes)
    Default Khan Academy avatar avatar for user
  • hopper cool style avatar for user 🍕MBONKA🍕
    Is there a way to color noise? I want it to have color besides just shades of gray.
    (4 votes)
    Default Khan Academy avatar avatar for user