2D Perlin noise function

I will keep this brief, im trying to implement my own perlin noise function.
It does not work, why does it not work? How can i make it work?
I also want to add the fact that i have been programming in proccessing for 4 weeks only. So new-ish.
(doesn’t work in the sense that it doesn’t make the image i want, it runs)

I want to create this (or similar):
perlin

UPDATE: i have now solved all the issues and now it works.

New functioning perlin noise code

PVector gradients1[];
float c1,c2,c3,c4;
int x,y;
float x2 = 0;
float y2 = 0;
float increment = 0.005;
int j = 0;
int i = 0;
int[] p = { 151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,151,
160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 };


PVector[] gradients = {
  new PVector(0, 1), 
  new PVector(1, 1), 
  new PVector(1,0),
  new PVector(1,-1),
  new PVector(0,-1),
  new PVector(-1,-1),
  new PVector(-1,0),
  new PVector(-1,1),
};


void setup() {
  size(800,800);
  frameRate(60);
  loadPixels();
  float xoff = 0.0; 
  for (int x = 0; x < width; x++) {
    xoff += increment;  
    float yoff = 0.0;  
    for (int y = 0; y < height; y++) {
      yoff+= increment;
      float f = perlinNoise(xoff,yoff);
      pixels[x+y*width] = color(f*255);
      }
  yoff += increment;
  } 
  updatePixels(); 
}

  //squaresize is 800/8
float perlinNoise(float x, float y) {

  
  int ix = floor(x);
  int iy = floor(y);
  
  x -= floor(x);
  y -= floor(y);
  
  ix &= 255;
  iy &= 255;
  
 int w1 = p[ix + p[iy]];
 int w2 = p[ix + 1 + p[iy]];
 int w3 = p[ix + p[iy + 1]];
 int w4 = p[ix + 1 + p[iy + 1]];
 
  c1 = dotP(w1 & 7, x, y);
  c2 = dotP(w2 & 7, x - 1, y);
  c3 = dotP(w3 & 7, x, y - 1 );
  c4 = dotP(w4 & 7, x - 1, y - 1);
  
  float fx = fade(x);
  float fy = fade(y);  
  
 float d1 = interpolate(c1,c2,fx);
 float d2 = interpolate(c3,c4,fx);
 
 float e = interpolate(d1,d2,fy);
 
 return e;
 //return (e + sqrt(2.0) / 2.0) / sqrt(2);
}

void keyPressed() {
save("myimage.png");
}

 float interpolate(float p0, float p1, float t) {
 return (1.0 - t) * p0 + t * p1;
} 

 float dotP(int i, float x, float y) {
 return
 gradients[i].x * x + gradients[i].y * y;
}

float fade(float t) { 
return t * t * t * (t * (t * 6 - 15) + 10);
}

1 Like

Hi! Welcome to the forum and to Processing :slight_smile:

I’m not sure why it doesn’t work, but I see some issues with the code.

  • x2 and y2 increase forever. I think they should be reset to 0 each time draw() gets called.
  • perlinNoise() returns numbers between 0 and 1, which would be too dark to see anything. Instead of using color(f) try color(128+127*f).
  • perlinNoise() always returns 0.5. Something wrong in the algorithm?

ps. you can use the existing lerp() function (linear interpolate) instead of creating your own interpolate().

1 Like
  1. There is no draw open in this project.
  2. That gives me the same result as multiplying the function with 255.
  3. if anybody is interested, i still cannot make it work but here is where the code is at now.
PVector w1, w2, w3, w4, v1,v2,v3,v4;
float c1,c2,c3,c4;
int x,y;
float x2 = 0;
float y2 = 0;
float increment = 0.01;
int j = 0;
int i = 0;
int[] perm = { 151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 };

PVector[] gradients = {
  new PVector(0, 1), 
  new PVector(1, 1), 
  new PVector(1,0),
  new PVector(1,-1),
  new PVector(0,-1),
  new PVector(-1,-1),
  new PVector(-1,0),
  new PVector(-1,1),
};



void setup() {
  size(800,800);
  frameRate(30);
  loadPixels();
  float xoff = 0.0; 
  for (int x = 0; x < width; x++) {
    xoff += increment;  
    float yoff = 0.0;  
    for (int y = 0; y < height; y++) {
      yoff += increment;
      float f = perlinNoise(xoff,yoff);
      pixels[x+y*width] = color(255*f);
      }
  yoff += increment;
}
  updatePixels(); 
}
  //squaresize is 800/8
float perlinNoise(float x, float y) {

  
  int ix = floor(x) & 255;
  int iy = floor(y) & 255;
  
  x = x - floor(ix);
  y = y - floor(iy);
  
  float fx = fade(x);
  float fy = fade(y);
  
  ix &= 255;
  iy &= 255;
  
  
 int w1 = perm[ix + perm[iy]];
 int w2 = perm[ix + 1 + perm[iy]];
 int w3 = perm[ix + perm[iy + 1]];
 int w4 = perm[ix + 1 + perm[iy + 1]];
 
  c1 = dotP(w1 & 7, x, y);
  c2 = dotP(w2 & 7, x - 1, y);
  c3 = dotP(w3 & 7, x, y - 1 );
  c4 = dotP(w4 & 7, x - 1, y - 1);
 
 
 float d1 = interpolate(fx,c1,c2);
 float d2 = interpolate(fx,c3,c4);
 
 float e = interpolate(fy,d1,d2);
 
 return (e + sqrt(2.0) / 2.0) / sqrt(2);
}

void keyPressed() {
save("myimage.png");
}

 float interpolate(float p0, float p1, float t) {
    return (1.0 - t)*p0 + t*p1;
} 

 float dotP(int i, float x, float y) {
 return
 gradients[i].x * x + gradients[i].y * y;
}

float fade(float t) { 
return t * t * t * (t * (t * 6 - 15) + 10);
}
1 Like

You are right about the multiplying by 255. I mixed noise (range 0.0 to 1.0) with simplexNoise (range -1.0 to 1.0).

I think you got wrong the argument order in interpolate(). If you fix that it works :slight_smile:

1 Like