// Simplex Noise 3D with fBm and ridged fBm variants. import { makeRng } from './rng.js'; export class SimplexNoise { constructor(seed = 0) { this.G = [[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]]; const rng = makeRng(seed); const p = new Uint8Array(256); for (let i = 0; i < 256; i++) p[i] = i; for (let i = 255; i > 0; i--) { const j = Math.floor(rng()*(i+1)); [p[i],p[j]]=[p[j],p[i]]; } this.perm = new Uint8Array(512); this.pm12 = new Uint8Array(512); for (let i = 0; i < 512; i++) { this.perm[i] = p[i&255]; this.pm12[i] = this.perm[i]%12; } } noise3D(x,y,z) { const F=1/3,H=1/6,s=(x+y+z)*F; const i=Math.floor(x+s),j=Math.floor(y+s),k=Math.floor(z+s); const t=(i+j+k)*H,x0=x-i+t,y0=y-j+t,z0=z-k+t; let i1,j1,k1,i2,j2,k2; if(x0>=y0){if(y0>=z0){i1=1;j1=0;k1=0;i2=1;j2=1;k2=0;}else if(x0>=z0){i1=1;j1=0;k1=0;i2=1;j2=0;k2=1;}else{i1=0;j1=0;k1=1;i2=1;j2=0;k2=1;}} else{if(y00){a*=a;const v=g[M[ii+P[jj+P[kk]]]];n0=a*a*(v[0]*x0+v[1]*y0+v[2]*z0);} let b=0.6-x1*x1-y1*y1-z1*z1;if(b>0){b*=b;const v=g[M[ii+i1+P[jj+j1+P[kk+k1]]]];n1=b*b*(v[0]*x1+v[1]*y1+v[2]*z1);} let c=0.6-x2*x2-y2*y2-z2*z2;if(c>0){c*=c;const v=g[M[ii+i2+P[jj+j2+P[kk+k2]]]];n2=c*c*(v[0]*x2+v[1]*y2+v[2]*z2);} let d=0.6-x3*x3-y3*y3-z3*z3;if(d>0){d*=d;const v=g[M[ii+1+P[jj+1+P[kk+1]]]];n3=d*d*(v[0]*x3+v[1]*y3+v[2]*z3);} return 32*(n0+n1+n2+n3); } fbm(x,y,z,octaves=5,persistence=2/3) { let sum=0,max=0,amp=1; for(let o=0;o