samedi 17 décembre 2022

Issues with perlin noise having discontinuous edges

I created a simple perlin noise generator using p5.js, which is based on this link . For the most part, I got 80% of the algorithm working. The only issue is that there is defined discontinuities aligned with each gradient vector. the code for this project is shown below.

// 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;

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

an image of the issue I'm having is shown below.

discontinuous edge example

I suspect that my issue has to do with the value between each gradient vector not properly using the adjacent gradient vectors, but I've tested and debugged this extensively and I cant find the issue. I've also tried several different ease_curve functions, but none of them seem to change anything. Any help would be greatly appreciated.




Aucun commentaire:

Enregistrer un commentaire