Skip to content

Instantly share code, notes, and snippets.

@aaronsnoswell
Created February 21, 2012 04:58
Show Gist options
  • Save aaronsnoswell/1873849 to your computer and use it in GitHub Desktop.
Save aaronsnoswell/1873849 to your computer and use it in GitHub Desktop.
Canvas Perlin Noise Generator
// l33t codes go here
var canvas = document.querySelector("#canvas"),
ctx = canvas.getContext("2d");
var randcache = [];
function noise(x, y) {
/*
var n = (x) + (y*57);
n = (n<<13) ^ n;
return (1.0-((n*(n*n*15731+789221)+1376312589) & 0x7fffffff) / 1073741824.0);
*/
if(typeof(randcache[x])=="undefined")
randcache[x] = [];
if(typeof(randcache[x][y])=="undefined")
randcache[x][y] = Math.random();
return randcache[x][y];
}
function smooth_noise(x, y) {
var corners = (noise(x-1, y-1)+noise(x+1, y-1)+noise(x-1, y+1)+noise(x+1, y+1)) / 16,
sides = (noise(x-1, y)+noise(x+1, y)+noise(x, y-1)+noise(x, y+1)) / 8,
center = noise(x, y) / 4;
return corners + sides + center;
}
function interpolated_noise(x, y, interpolator) {
var integer_X = Math.round(x),
fractional_X = x - integer_X,
integer_Y = Math.round(y),
fractional_Y = y - integer_Y;
var v1 = smooth_noise(integer_X, integer_Y),
v2 = smooth_noise(integer_X + 1, integer_Y),
v3 = smooth_noise(integer_X, integer_Y + 1),
v4 = smooth_noise(integer_X + 1, integer_Y + 1);
var i1 = interpolator(v1, v2, fractional_X),
i2 = interpolator(v3, v4, fractional_X);
return interpolator(i1, i2, fractional_Y);
}
function perlin_2d(x, y) {
var total = 0;
var p = 0.25,
octaves = 2;
function lerp(a, b, x) {
return a*(1-x) + b*x;
}
function coserp(a, b, x) {
var ft = x * 3.1415927,
f = (1 - cos(ft)) * 0.5;
return a*(1-f) + b*f;
}
for(var i=0; i<(octaves-1); i++) {
var frequency = Math.pow(2,i),
amplitude = Math.pow(p,i);
total = total + interpolated_noise(x*frequency, y*frequency, lerp) * amplitude;
}
return total
}
var im = ctx.createImageData(128, 128);
for(var x=0; x<im.width; x++) {
for(var y=0; y<im.height; y++) {
var pos = x + y*im.width,
val = perlin_2d(x, y);
im.data[pos*4] = val*255;
im.data[pos*4 + 1] = val*255;
im.data[pos*4 + 2] = val*255;
im.data[pos*4 + 3] = 1*255;
}
}
ctx.putImageData(im, 0, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment