Perlin

HTML

<canvas id='c' width=600 height=600></canvas>

CSS

canvas{
    border:1px solid #faa;
    background:#000;
}

JavaScript

randVecs = [];
for(i=0; i<22;  i++){
    randVecs[i] = [];
    for(j=0; j<22;  j++){
        val = Math.random()*2*Math.PI;
        randVecs[i][j] = [Math.cos(val), Math.sin(val)];
    }
}

function randVec(x, y){
    var a = 2*3.1415927*Math.cos(x*y+x+y);
    return [Math.cos(a), Math.sin(a)];
    return randVecs[x][y];
}

function dot(a, b){
    return a[0]*b[0]+a[1]*b[1];
}

function lin(a, b, p){
    p = 3*p*p-2*p*p*p;
    return (b-a)*p+a;
}

function perlin(x, y){
    x0 = Math.floor(x);
    y0 = Math.floor(y);
    x1 = x0+1;
    y1 = y0+1;
    
    s = dot(randVec(x0, y0), [x-x0, y-y0]);
    t = dot(randVec(x1, y0), [x-x1, y-y0]);
    u = dot(randVec(x0, y1), [x-x0, y-y1]);
    v = dot(randVec(x1, y1), [x-x1, y-y1]);
    
    a = lin(s, t, x-x0);
    b = lin(u, v, x-x0);
    c = lin(a, b, y-y0);
    // c ranges from +/- 1/sqrt(2)
    c = c*1.4142135623730951*0.5+0.5;
    //c = 3*c*c-2*c*c*c;
    //c = 1-(Math.abs(c-0.5))*2;
    c = Math.pow(Math.abs(Math.cos(c*3.1415927)), 1/2); //blender 'hard clouds'
    //c = (c*10)-Math.floor(c*10);
    return c;
    
}

ctx=document.getElementById('c').getContext('2d');

perlin(1.2, 5.5);

maxP = 0;
minP = 100;

for(x=0; x<600; x++){
    for(y=0; y<600; y++){
        p = perlin(x/30, y/30);
        if(p<minP) minP = p;
        if(p>maxP) maxP = p;
        ctx.fillStyle = "rgba(255, 255, 255, "+p+")";
        ctx.fillRect(x, y, 1, 1);
    }
}

console.log(minP, maxP);