function noise2d(x, y) {
const _x = Math.floor(x);
const _y = Math.floor(y);
x = x - _x;
y = y - _y;
const _x0 = _x % nUnique;
const _y0 = _y % nUnique;
const _x1 = (_x + 1) % nUnique;
const _y1 = (_y + 1) % nUnique;
const g00 = cells2d[_x0 + perm[_y0]]
const g10 = cells2d[_x1 + perm[_y0]]
const g01 = cells2d[_x0 + perm[_y1]]
const g11 = cells2d[_x1 + perm[_y1]]
const d00 = [x, y];
const d10 = [x-1, y];
const d01 = [x , y-1];
const d11 = [x-1, y-1];
const in00 = dot(g00, d00);
const in10 = dot(g10, d10);
const in01 = dot(g01, d01);
const in11 = dot(g11, d11);
const l1 = lerp(in00, in10, fade(x));
const l2 = lerp(in01, in11, fade(x));
return lerp(l1, l2, fade(y)) + 0.5;
}