Javascript柏林噪声实现。工件与价值界

Javascript柏林噪声实现。工件与价值界,javascript,procedural-generation,perlin-noise,Javascript,Procedural Generation,Perlin Noise,我试图理解柏林河的噪音,但我有两个主要问题: 我从我编写的函数中得到的值似乎永远不会达到接近极限(0,1)的值。另一个问题是,我吐出来的图像与柏林噪声生成的图像一点也不相似。 代码分为多个部分。所有代码按顺序显示 种子PNRG用于数组排列p,并添加Math.lerp和ctx.drawPixel const SEED = [0x12345678, 0x9ABCDEF0, 0x12345678, 0x9ABCDEF0]; const fade = function (t) { return

我试图理解柏林河的噪音,但我有两个主要问题: 我从我编写的函数中得到的值似乎永远不会达到接近极限(0,1)的值。另一个问题是,我吐出来的图像与柏林噪声生成的图像一点也不相似。 代码分为多个部分。所有代码按顺序显示

种子PNRG用于数组排列
p
,并添加
Math.lerp
ctx.drawPixel

const SEED = [0x12345678, 0x9ABCDEF0, 0x12345678, 0x9ABCDEF0];
const fade = function (t) {
    return t * t * t * (t * (t * 6 - 15) + 10);
};
Math.lerp = function (a, b, f) {
    return a + fade(f) * (b - a);
};
Math.seededPNRG = function (a, b, c, d) {
    return function() {
        a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0;
        let t = (a + b) | 0;
        a = b ^ b >>> 9;
        b = c + (c << 3) | 0;
        c = (c << 21 | c >>> 11);
        d = d + 1 | 0;
        t = t + d | 0;
        c = c + t | 0;
        return (t >>> 0) / 4294967296;
    }
};
CanvasRenderingContext2D.prototype.drawPixel = function (x,y) {
    this.fillRect(x,y,1,1);
};
const SEED=[0x12345678,0x9ABCDEF0,0x12345678,0x9ABCDEF0];
常数衰减=函数(t){
返回t*t*t*(t*(t*6-15)+10);
};
Math.lerp=函数(a、b、f){
返回a+fade(f)*(b-a);
};
Math.seedpnrg=函数(a、b、c、d){
返回函数(){
a>>>=0;b>>>=0;c>>>=0;d>>>=0;
设t=(a+b)| 0;
a=b^b>>>9;
b=c+(c>11);
d=d+1 | 0;
t=t+d | 0;
c=c+t | 0;
返回(t>>>0)/4294967296;
}
};
CanvasRenderingContext2D.prototype.drawPixel=函数(x,y){
this.fillRect(x,y,1,1);
};
生成数组的置换(Knuth shuffle)

const random=Math.seedpnrg(…SEED);
常数p=[];
{
对于(设i=0;i n+1;
AAA= P[P[P](席)+ ] +子];
ABA=P[P[P] [Xi] +Inc(Yi)]席];
AAB= P[P[P[席] +Yi] +Inc(Zi)];
ABB=P[P[P[席] +Inc(Yi)] +Inc(Zi)];
baa=p[p[p[inc(xi)]+yi]+zi];
bba=p[p[p[inc(xi)]+inc(yi)]+zi];
bab=p[p[p[inc(xi)]+yi]+inc(zi)];
bbb=p[p[p[inc(xi)]+inc(yi)]+inc(zi)];
}
常量梯度=函数(散列,x,y,z){
设h=hash&15;
设u=h<8×y:y;
让v;
if(h<4)
v=y;
else if(h==12 | | h==14)
v=x;
否则v=z;
返回(h&1==0?u:-u)+(h&2==0?v:-v);
};
设x1,x2,y1,y2;
x1=Math.lerp(
等级(aaa、xf、yf、zf),
等级(baa、xf-1、yf、zf),
U
);
x2=Math.lerp(
毕业生(aba、xf、yf-1、zf),
毕业生(工商管理学士、xf-1、yf-1、采埃孚),
U
);
y1=数学lerp(x1,x2,v);
x1=Math.lerp(
等级(aab、xf、yf、zf-1),
梯度(bab、xf-1、yf、zf-1),
U
);
x2=Math.lerp(
等级(abb、xf、yf-1、zf-1),
等级(bbb、xf-1、yf-1、zf-1),
U
);
y2=数学lerp(x1,x2,v);
返回(数学lerp(y1,y2,w)+1)/2;
};
画图

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

const height = canvas.height;
const width = canvas.width;

for (let i=100; i<width-200; i++) {
    for (let j=100; j<height-200; j++) {
        let k = perlin(i/100, j/100,.5);
        ctx.fillStyle = "#"+Math.floor(k * 256).toString(16).repeat(3);
        ctx.drawPixel(i, j);
    }
}
const canvas=document.getElementById('canvas');
const ctx=canvas.getContext('2d');
const height=canvas.height;
const width=canvas.width;
for(设i=100;i
const perlin = function (x, y, z) {
    x = x % 512;
    y = y % 512;
    z = z % 512;
    let xi = x & 255, yi = y & 255, zi = z & 255;
    let xf = x - Math.floor(x), yf = y - Math.floor(y), zf = z - Math.floor(z);
    let u = fade(xf), v = fade(yf), w = fade(zf);
    let aaa, aba, aab, abb, baa, bba, bab, bbb;
    {
        let inc = n => n+1;
        aaa = p[p[p[    xi ]+    yi ]+    zi ];
        aba = p[p[p[    xi ]+inc(yi)]+    zi ];
        aab = p[p[p[    xi ]+    yi ]+inc(zi)];
        abb = p[p[p[    xi ]+inc(yi)]+inc(zi)];
        baa = p[p[p[inc(xi)]+    yi ]+    zi ];
        bba = p[p[p[inc(xi)]+inc(yi)]+    zi ];
        bab = p[p[p[inc(xi)]+    yi ]+inc(zi)];
        bbb = p[p[p[inc(xi)]+inc(yi)]+inc(zi)];
    }
    const grad = function (hash, x, y, z) {
        let h = hash & 15;
        let u = h < 8 ? x : y;
        let v;
        if (h < 4)
            v = y;
        else if (h === 12 || h === 14)
            v = x;
        else v = z;
        return (h & 1 === 0 ? u : -u)+(h & 2 === 0 ? v : -v);
    };
    let x1, x2, y1, y2;
    x1 = Math.lerp(
        grad(aaa, xf, yf, zf),
        grad(baa, xf-1, yf, zf),
        u
    );
    x2 = Math.lerp(
        grad(aba, xf, yf-1, zf),
        grad(bba, xf-1, yf-1, zf),
        u
    );
    y1 = Math.lerp(x1, x2, v);
    x1 = Math.lerp(
        grad(aab, xf, yf, zf-1),
        grad(bab, xf-1, yf, zf-1),
        u
    );
    x2 = Math.lerp(
        grad(abb, xf, yf-1, zf-1),
        grad(bbb, xf-1, yf-1, zf-1),
        u
    );
    y2 = Math.lerp(x1,x2,v);
    return (Math.lerp(y1, y2, w) + 1) / 2;
};
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const height = canvas.height;
const width = canvas.width;

for (let i=100; i<width-200; i++) {
    for (let j=100; j<height-200; j++) {
        let k = perlin(i/100, j/100,.5);
        ctx.fillStyle = "#"+Math.floor(k * 256).toString(16).repeat(3);
        ctx.drawPixel(i, j);
    }
}