You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perlin噪声生成器存在边缘不连续问题求助

2D Perlin噪声生成器的不连续边缘问题

我参考Perlin噪声的实现原理,用p5.js实现了一个简易的Perlin噪声生成器,算法完成度约80%,但生成的图像存在与梯度向量对齐的明显不连续边缘问题。

问题效果如下:
不连续边缘示例

项目代码如下:

JavaScript 代码

// noprotect
var screen_width = 400;
var screen_height = 400;

var res = 2;
var gvecs = {};


function setup() {
  createCanvas(screen_width, screen_height);
  initialize_gvecs();
  draw_perlin_noise();
}

function draw() {
  console.log(gvecs);
  noLoop();
}

function initialize_gvecs() {
  for (var y = 0; y <= res; y++) {
    for (var x = 0; x <= res; x++) {
      let theta = Math.random() * 2 * Math.PI;
      gvecs[[x, y]] = {
        x: Math.cos(theta),
        y: Math.sin(theta)
      };
    }
  }
}

function draw_perlin_noise() {

  loadPixels();

  for (var y = 0; y < screen_height; y++) {
    for (var x = 0; x < screen_width; x++) {
      var world_coordx = map(x, 0, screen_width, 0, res);
      var world_coordy = map(y, 0, screen_height, 0, res);

      var top_L_x = Math.floor(world_coordx);
      var top_L_y = Math.floor(world_coordy);

      var top_R_x = top_L_x + 1;
      var top_R_y = top_L_y;

      var bottom_L_x = top_L_x;
      var bottom_L_y = top_L_y + 1;

      var bottom_R_x = top_L_x + 1;
      var bottom_R_y = top_L_y + 1;

      var top_L_g = gvecs[[top_L_x, top_L_y]];
      var top_R_g = gvecs[[top_R_x, top_R_y]];
      var bottom_L_g = gvecs[[bottom_L_x, bottom_L_y]];
      var bottom_R_g = gvecs[[bottom_R_x, bottom_R_y]];

      var btw_top_L = {
        x: world_coordx - top_L_x,
        y: world_coordy - top_L_y
      };
      var btw_top_R = {
        x: world_coordx - top_R_x,
        y: world_coordy - top_R_y
      };
      var btw_bottom_L = {
        x: world_coordx - bottom_L_x,
        y: world_coordy - bottom_L_y
      };
      var btw_bottom_R = {
        x: world_coordx - bottom_R_x,
        y: world_coordy - bottom_R_y
      };

      var v = top_L_g.x * btw_top_L.x + top_L_g.y * btw_top_L.y;
      var u = top_R_g.x * btw_top_R.x + top_R_g.y * btw_top_R.y;
      var s = bottom_L_g.x * btw_bottom_L.x + bottom_L_g.y * btw_bottom_L.y;
      var t = bottom_R_g.x * btw_bottom_R.x + bottom_R_g.y * btw_bottom_R.y;

      var Sx = ease_curve(world_coordx - top_L_x);
      var a = s + Sx * (t - s);
      var b = u + Sx * (v - u);

      var Sy = ease_curve(world_coordy - top_L_y);
      var final_val = a + Sy * (b - a);

      pixels[(x + y * screen_width) * 4] = map(final_val, -1, 1, 0, 255);
      pixels[(x + y * screen_width) * 4 + 1] = map(final_val, -1, 1, 0, 255);
      pixels[(x + y * screen_width) * 4 + 2] = map(final_val, -1, 1, 0, 255);
      pixels[(x + y * screen_width) * 4 + 3] = 255;

    }

  }
  updatePixels();

}

function ease_curve(x) {
  return 6 * x ** 5 - 15 * x ** 4 + 10 * x ** 3;

}

HTML 代码

<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>

我怀疑问题出在梯度向量间的值未正确利用相邻梯度向量,但反复调试仍未找到原因,更换多种缓动曲线函数也无改善,恳请各位提供帮助。


内容的提问来源于stack exchange,提问作者Micah Wagner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 12:50:29