【问题标题】:Issue with seamless 1-D SImplex noise无缝一维 SIMplex 噪声问题
【发布时间】:2022-01-02 01:46:44
【问题描述】:

通常,在生成无缝 Simplex 噪声时,策略是转到 4 维(过去使用 2-D Simplex 时这种策略对我来说效果很好),但是我正在尝试使用 1 生成无缝 GIF 循环-D 单纯形噪声(只对指定折线图中 Y 值的噪声感兴趣)。

我很好奇我是否误解了如何在一维中使事情变得无缝,或者我是否可能在逻辑上有错误。基本上,我正在生成一个二维数组,其中第一个维度是 Z 轴,第二个维度是该 Z 的点(xy 值)列表。我遍历每个 z 并简单地依次绘制每个顶点.

我注意到,当我达到最大 Z 值时,会出现明显的跳跃,表明我做错了什么(不是无缝的)。

我正在使用fast-simplex-noise 库(我更喜欢它而不是P5 的内置noise 函数)并将其指定为:

function setup() {
  let freq = 0.005;
  let octaves = 14;
  _noise = new FastSimplexNoise({ frequency: freq, octaves: octaves });

  // specify the points:
  points = [];
  
  step = 0;
  maxSteps = 150;
  let r = 1.0;
  
  for (let z = 0; z < maxSteps; z++) {
    let t = (1.0 * z) / maxSteps;
    
    points[z] = [];

    for (let x = o + 10; x < width - o - 10; x++) {
      let _n = _noise.get4DNoise(x, z, r*cos(TWO_PI*t), r*sin(TWO_PI*t));
      let _y = height/2 + 250*_n;
      points[i].push({ x: x, y: _y });
    }
  }
}

draw 函数中,我只需遍历points 列表中的每个顶点,并跟踪当前z 每次绘制迭代的值。

【问题讨论】:

    标签: processing p5.js simplex simplex-noise


    【解决方案1】:

    听起来您期望从z = maxSteps - 1 跳转到z = 0 时噪声值的变化很小。但是,当您将z 指定为get4DNoise 的第二个参数时,情况并非如此,因为对于z 的这两个值,第三维和第四维将非常接近(感谢使用正弦和余弦),第二个将相差maxSteps - 1。这就引出了一个问题:你为什么要使用 4D 噪声?您正在尝试随机改变y,以便它可以平滑地更改zx 中的更改,并循环返回。为了实现这一点,您只需在围绕圆柱体移动的 3d 空间中沿直线对噪声值进行采样。

    这是您的噪声算法的可视化,以及一个非常相似的仅使用 3d 噪声的算法。注意左边的圆柱体有接缝,而右边的圆柱体没有接缝:

    const maxSteps = 100;
    const scaleFactor = 20;
    
    let texture1;
    let texture2;
    
    let _noise;
    let cam;
    
    function setup() {
      let size = Math.min(windowWidth, windowHeight);
      createCanvas(size, size, WEBGL);
      noStroke();
      cam = createCamera();
      cam.setPosition(0, 0, 500);
      cam.lookAt(0, 0, 0);
    
      _noise = new FastSimplexNoise({
        frequency: 0.005,
        octaves: 14
      });
    
      texture1 = makeTexture(true);
      texture2 = makeTexture(false);
    }
    
    function doubleClicked() {
      console.log(cam);
    }
    
    function makeTexture(use4d) {
      let points = [];
      // Using an r of 1.0 covers a very small and unchanging region of noise space
      let r = use4d ? 1.0 : maxSteps / 2;
    
      for (let z = 0; z < maxSteps; z++) {
        let t = z / maxSteps;
    
        points[z] = [];
    
        for (let x = 0; x < maxSteps; x++) {
          let _n =
            use4d ?
            _noise.get4DNoise(x, z, r * cos(TWO_PI * t), r * sin(TWO_PI * t)) :
            _noise.get3DNoise(x, r * cos(TWO_PI * t), r * sin(TWO_PI * t));
          let _y = 250 * _n;
          points[z].push({
            x: x,
            y: _y
          });
        }
      }
    
      let g = createGraphics(maxSteps, maxSteps);
    
      for (let z = 0; z < maxSteps; z++) {
        for (let x = 0; x < maxSteps; x++) {
          // x == points[z][x].x
          // Using z as x and x as y because of the texture coordinate layout for cylinders
          g.set(
            z, x,
            // Shifting y values upward because they tend to be small resulting in a dark texture
            map(points[z][x].y, 0, 250, 100, 300)
          );
        }
      }
    
      // required after set()?
      g.updatePixels();
    
      return g;
    }
    
    function draw() {
      background(255);
      orbitControl(2, 1, 0.1);
    
      push();
      translate(-150, 0, 0);
      texture(texture1);
      cylinder(100, 200);
      pop();
    
      push();
      translate(150, 0, 0);
      texture(texture2);
      cylinder(100, 200);
      pop();
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/fast-simplex-noise@1.0.0/fast-simplex-noise.js"></script>

    【讨论】:

    • 这很有意义(并且效果很好)。不知道为什么我不认为如果我要降低一个尺寸,我的圆柱体也应该降低一个尺寸。谢谢!
    猜你喜欢
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 2012-09-10
    • 2012-11-15
    • 1970-01-01
    • 2015-04-18
    • 2013-10-11
    相关资源
    最近更新 更多