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);
}

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. 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);
}

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: