Noise Blending Implementation

colornoiseSome people have asked for an implementation of the noise blending technique in my previous post. Here’s the Processing code for the core idea. Keep in mind that this is just about making a smoothly changing noise field; what you do with that noise is up to you!

The best way to implement this (and the way I did it!) is to use my AU library. Then you can save 2D arrays of floats in AUField objects, which are easy to make and manipulate. But that library hasn’t been released yet (I just added another function this morning!), so this listing is just pure out-of-the-box Processing.

noiseLoopThe only weirdness is the variable ListOfNoiseArrays, which is of type float[][][]. If you haven’t seen this kind of thing before, don’t worry: it’s just a 3D array. Think of it as a stack of slices. The first index tells you which slice to use, and the second and third indices tell you the row and column of the pixel you want on that slice.

Conveniently, the value of ListOfNoiseArrays.length returns the length of the first index. That is, it’s the number of slices that the array holds. So this gives us an easy way to find out how many noise fields we’re blending through without needing to keep a separate global variable. This image shows the output as an animated gif; if it’s not animating, click it to see it in motion.

// A little sketch to demonstrate the multiple noise field interpolation technique.
// No guarantee or warranty of any kind. You may use and distribute this freely.
// Andrew Glassner, August 28, 2014

float[][][] ListOfNoiseArrays; // global to hold list of noise fields

void setup() {
  size(500, 500);
  int numFields = 4; // how many fields you want to use. Must be > 0
  ListOfNoiseArrays = new float[numFields][height][width]; // create the array
  for (int n=0; n<ListOfNoiseArrays.length; n++) { // for each field n,
    for (int y=0; y<height; y++) { // look at all the pixels
      for (int x=0; x<width; x++) {
        float noiseX = (x*.02) + (n*width); // .02 was chosen by eye; it's
        float noiseY = (y*.02) + (n*height); // not too simple or busy
        ListOfNoiseArrays[n][y][x] = noise(noiseY, noiseX); // save this value
      }
    }
  }
}

void draw() {
  int cycleLength = 25; // number of frames to get from one field to another
  // Find n, the index of the first field in the set of 4 we're going to blend
  int n = (int)((frameCount*1./cycleLength) % ListOfNoiseArrays.length);
  // Find alfa, a value from 0 to 1 telling us where we are in this blend
  float alfa = ((frameCount - (n*cycleLength))/(1.*cycleLength)) % 1.0;
  // Now build up the noise field for every pixel. I'll draw it, but typically
  // we'd save this in an array and use it to generate our graphics.
  loadPixels();
  for (int y=0; y<height; y++) {
    for (int x=0; x<width; x++) {
      // Find the four values of n that are the fields we're going to interpolate
      int n0 = n;
      int n1 = (n0+1)%ListOfNoiseArrays.length;
      int n2 = (n1+1)%ListOfNoiseArrays.length;
      int n3 = (n2+1)%ListOfNoiseArrays.length;
      // Evaulate a Catmull-Rom curve through the values for this pixel
      float v = curvePoint(ListOfNoiseArrays[n0][y][x], ListOfNoiseArrays[n1][y][x],
                           ListOfNoiseArrays[n2][y][x], ListOfNoiseArrays[n3][y][x], alfa);
      pixels[(y*width)+x] = color(255 * v); // save noise value as a shade of gray
    }
  }
  updatePixels();
}

1 thought on “Noise Blending Implementation

  1. Pingback: Noise Blending with the AU Library | Imaginary Institute Blog

Leave a Reply

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