在 Processing 中使用噪声函数

Using the noise function in Processing

我正在尝试在 Processing 中为由单个矩形组成的飞布制作动画。我用嵌套循环制作布料。现在我想使用噪声函数来操纵各个点的高度。不幸的是,我不能正确地做到这一点——显然我不明白这个功能。我绕道而行,在 PGraphics 上绘制噪声云,然后读取亮度值 - 并使用它来控制每个矩形的 z 位置。这按照我希望的方式工作!

只有 - 我怎样才能达到同样的效果而不绕道 PGraphics? 这是我想要的代码(绕行):

PGraphics pg;
float increment = 0.002;
float xoff;
float yoff;
float zoff = 0.0;
float zincrement = 0.1;

float size;
float pixel = 200;

void setup() {
  size(1920, 1080, P3D);
  frameRate(30);
  size = width/pixel;
  rectMode(CENTER);
  pg = createGraphics(width, width);
}

void draw() {

  //PGraphics
  pg.beginDraw();
  pg.loadPixels();
  xoff = 0.0;
  for (int x = 0; x < width; x++) {
    xoff += increment;
    yoff = 0.0;
    for (int y = 0; y < width; y++) {
      yoff += increment;
      float bright = noise(xoff, yoff, zoff)*255;
      pg.pixels[x+y*width] = color(bright, bright, bright);
    }
  }
  pg.updatePixels();
  pg.endDraw();
  zoff += zincrement;

  //SCENE
  background(0);
  stroke(255,0,0);
  line(width/2, 0, width/2, height);
  translate(0, 0, mouseX);
  pushMatrix();
  rotateX(radians(45));
  translate(pixel*size/2, -pixel*size, -pixel*size);
  rotateZ(radians(mouseX));
  translate(-pixel*size/2, -pixel*size/2, -pixel*size/4);
  pushMatrix();
  
  for (int y = 0; y < pixel; y++) {
    for (int x = 0; x < pixel; x++) {

      color c = pg.get(int(size*x), int(size*y));
      float zpoint = map(brightness(c), 0, 255, -500, 500);
      pushMatrix();
      noiseDetail(3, 0.5f);
      translate(x*size, y*size, zpoint);
      rotate(radians(45));
      noStroke();
      fill(255);
      rect(0, 0, size, size);
      popMatrix();
    }
  }
  popMatrix();
  popMatrix();
}

这就是我想用更简单的方式编写它的方式:

float size;
float pixel = 200;


float xoff;
float yoff;
float zoff;
float increment = 0.01;


void setup() {
  size(1920, 1080, P3D);
  frameRate(30);
  size = width/pixel;
  rectMode(CENTER);


}

void draw() {

  
  background(0);
  stroke(255,0,0);
  line(width/2, 0, width/2, height);
  translate(0,0,mouseX);
  pushMatrix();
  rotateX(radians(45));
  translate(pixel*size/2,-pixel*size,-pixel*size);
  rotateZ(radians(mouseX));
  translate(-pixel*size/2,-pixel*size/2,-pixel*size/4);
  pushMatrix(); 
  for (int y = 0; y < pixel; y++) {
    for (int x = 0; x < pixel; x++) {
      pushMatrix();
      noiseDetail(1, 0.25f);
      float n = noise(x*size + xoff, y*size + yoff, zoff)*255;
      translate(x*size, y*size,  n);
      rotate(radians(45));
      noStroke();
      fill(255);
      rect(0, 0,   size,  size);
      popMatrix();
    }
  }
  popMatrix();
  popMatrix();
  
  yoff += 0.11;
  xoff += 0.02;
  zoff += 0.03;
}

我认为这条线是问题所在 - 因为目前它无法创建像这样的真实布料。

float n = noise(x*size + xoff, y*size + yoff, zoff)*255;

你是对的,问题出在这一行

float n = noise(x*size + xoff, y*size + yoff, zoff)*255;

x 和 y 输入参数从一次迭代到另一次迭代的变化太大(等于大小)。如果你读过有关 Perlin 噪声的文章,你就会知道如果迈出一大步,它看起来就像是随机噪声。我建议将此行编辑为类似以下内容:

float n = noise(xx + xoff, yy + yoff, zoff)*255;

其中 xx 和 yy 是您在 for 循环中缓慢递增的其他变量

我的解决方案:

void draw() {

  
  background(0);
  stroke(255,0,0);
  line(width/2, 0, width/2, height);
  translate(0,0,mouseX);
  pushMatrix();
  rotateX(radians(45));
  translate(pixel*size/2,-pixel*size,-pixel*size);
  rotateZ(radians(mouseX));
  translate(-pixel*size/2,-pixel*size/2,-pixel*size/4);
  pushMatrix();
  
  float xx = 0;
  float yy = 0;
  for (int y = 0; y < pixel; y++) {
    xx = 0;
    for (int x = 0; x < pixel; x++) {
      pushMatrix();
      noiseDetail(1, 0.25f);
      float n = noise(xx + xoff, yy + yoff)*255;
      
      translate(x*size, y*size,  n);
      rotate(radians(45));
      noStroke();
      fill(255);
      rect(0, 0,   size,  size);
      popMatrix();
      xx += 0.1;      
    }
    yy += 0.1;
  }
  popMatrix();
  popMatrix();
  
  yoff += 0.11;
  xoff += 0.02;
  zoff += 0.03;
}

改变 xx 和 yy 的增量可以使标志看起来像在 1 个方向上流动...