2D Perlin Noise Sampling
Here is a simple p5.js sketch that samples Perlin noise in 2D space to generate the z-coordinate of each point in a 50 by 50 grid of points. It's pretty neat to sit and watch the world go by sometimes, isn't it?
I'll probably endeavor to make the world a bit more interesting as time goes by.
The source code for the sketch is quite straightforward. I added comments too, cause that's something good programmers do.
function setup() {
let canvas_element = document.getElementById('noise-canvas');
createCanvas(0.5 * windowWidth, 0.5 * windowHeight, WEBGL, canvas_element);
normalMaterial();
noiseSeed(1);
}
// Convenience function for converting a grid-point to a noise sample.
//
// px, py -> the grid coordinate at which to sample the noise
// nsx, nsy -> the scale factors to adjust the "smoothness" of the noise in
// x and y, respectively.
// amp -> a scale factor to adjust the output of the noise function from
// [0, 1] to [0, amp].
function scaledNoiseSample(px, py, nsx, nsy, amp) {
return amp * noise(px * nsx, py * nsy);
}
function draw() {
// Grid limits
let max_x = 50;
let max_y = 50;
// Grid scale factors
let gsx = 20;
let gsy = 20;
// Noise scale factors
let octave_1_amp = 500;
let nsx = 0.03;
let nsy = 0.03;
// Clear the background
background(0);
// Adjust the view in 3-d space
rotateX(0.9);
scale(0.6);
translate((-1 / 2) * (max_x * gsx), (-1 / 2) * (max_y * gsy));
// Setup a wire-frame style render
stroke(255);
strokeWeight(0.3);
noFill();
// Loop over rows in the grid
for (let y = 0; y < max_y; y++) {
// A triangle strip is fairly efficient for this rendering.
// TRIANGLEs or QUADs would require redundantly specifying vertices.
// Further improvements to efficiency could be made (in this code,
// each row of vertices is specified twice).
beginShape(TRIANGLE_STRIP);
// Use the frame count to automatically scroll along the positive x-axis.
let x0 = frameCount;
// Calculate the z-coordinate of one of the vertices.
let gz1 = scaledNoiseSample(x0, y, nsx, nsy, octave_1_amp);
vertex(gsx * 0, gsy * y, gz1);
for (let x = 0; x < max_x; x++) {
// Specify the diagonally adjacent vertices to the right and below the
// previous pair (or the first vertex in the initial case).
let x_prime = x + frameCount;
let gz2 = scaledNoiseSample(x_prime, (y + 1), nsx, nsy, octave_1_amp);
vertex(gsx * x, gsy * (y + 1), gz2);
let gz3 = scaledNoiseSample((x_prime + 1), y, nsx, nsy, octave_1_amp);
vertex(gsx * (x + 1), gsy * y, gz3);
}
// Specify the last vertex on the lower row of vertices
// for this row of triangles.
let xf = max_x + frameCount;
let gz4 = scaledNoiseSample(xf, (y + 1), nsx, nsy, octave_1_amp);
vertex(gsx * max_x, gsy * (y + 1), gz4);
// Finish the triangle strip for this row.
endShape();
}
// End of frame.
}