// Noise Lab — Exported Texture
// Generated: 2026-09-02T08:39:03.258Z
// Filename: noise-texture
// Seed: 81771 | Scale: 36 | Octaves: 1 | Persistence: 0.2 | Falloff: 0.95
// Contrast: 1.85 | Brightness: 0.85 | Noise: turbulence | Mode: gradient
// Stretch: 0.5x1.4 | Rotation: 171° | Tileable: false
// Grain: 0.57 | Vignette: 0.75 | Blur: 0
// Invert: false | Posterize: off | Threshold: off
// Blend: colorize 0.6 | Displacement: 12 | SamplingScale: 1
// Aspect: 3:1 | ExportSize: 1024
// Gradient stops: 7 stops
// — Standalone vanilla JS — no dependencies. Creates a canvas and draws the texture.}
(function() {
// Seeded RNG — mulberry32
function mulberry32(a) {
return function() {
let t = (a += 0x6d2b79f5);
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
// Perlin 2D
class Perlin2D {
constructor(seed) {
this.p = new Uint8Array(512);
const rand = mulberry32(seed);
const perm = Array.from({length:256}, (_,i)=>i);
for (let i=255;i>0;i--) {
const j = Math.floor(rand()*(i+1));
const tmp = perm[i]; perm[i]=perm[j]; perm[j]=tmp;
}
for (let i=0;i<512;i++) this.p[i]=perm[i & 255];
}
fade(t){ return t*t*t*(t*(t*6-15)+10); }
lerp(a,b,t){ return a + t*(b-a); }
grad(hash,x,y){
const h = hash & 3;
const u = h < 2 ? x : y;
const v = h < 2 ? y : x;
return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
}
noise(x,y){
const X = Math.floor(x) & 255;
const Y = Math.floor(y) & 255;
x -= Math.floor(x); y -= Math.floor(y);
const u = this.fade(x), v = this.fade(y);
const A = this.p[X]+Y, AA=this.p[A], AB=this.p[A+1];
const B = this.p[X+1]+Y, BA=this.p[B], BB=this.p[B+1];
return this.lerp(
this.lerp(this.grad(this.p[AA],x,y), this.grad(this.p[BA],x-1,y), u),
this.lerp(this.grad(this.p[AB],x,y-1), this.grad(this.p[BB],x-1,y-1), u),
v
);
}
}
function cellularNoise(x,y,seed){
const xi=Math.floor(x), yi=Math.floor(y);
let minDist=10;
for(let j=-1;j<=1;j++){
for(let i=-1;i<=1;i++){
const cx=xi+i, cy=yi+j;
const r=mulberry32(seed + cx*374761393 + cy*668265263 + 999);
const px=cx+r(), py=cy+r();
const dx=px-x, dy=py-y;
const d=Math.sqrt(dx*dx+dy*dy);
if(disValidHex(s.color));
if(filtered.length===0) return {r:128,g:128,b:128};
if(filtered.length===1) return hexToRgb(filtered[0].color);
const stops=[...filtered].sort((a,b)=>a.pos-b.pos);
if(t<=stops[0].pos) return hexToRgb(stops[0].color,false);
if(t>=stops[stops.length-1].pos) return hexToRgb(stops[stops.length-1].color,true);
for(let i=0;i=stops[i].pos && t<=stops[i+1].pos){
const denom=stops[i+1].pos-stops[i].pos;
const local=denom===0?0:(t-stops[i].pos)/denom;
return lerpColor(stops[i].color, stops[i+1].color, local);
}
}
return hexToRgb(stops[0].color,false);
}
const perlin = new Perlin2D(PARAMS.seed);
const grainRand = mulberry32(PARAMS.seed + 9999);
function fbm(x,y){
const lacunarity = 1 + PARAMS.falloff * 2;
let amp=1, freq=1, sum=0, max=0;
for(let i=0;i1) v=1;
return v;
}
function render(canvas, w, h, offX, offY){
offX = offX||0; offY=offY||0;
const ctx=canvas.getContext("2d");
if(!ctx) return;
canvas.width=w; canvas.height=h;
const imgData=ctx.createImageData(w,h);
const data=imgData.data;
const cx=w/2, cy=h/2;
const rad=PARAMS.rotation*Math.PI/180;
const cosR=Math.cos(rad), sinR=Math.sin(rad);
const maxDist=Math.sqrt(cx*cx+cy*cy);
const baseScale=PARAMS.scale;
// For image mode: provide your own ImageData as 'imageData' variable below if needed.
// Example: const imageData = ctx.getImageData(...) from your uploaded image.
// If null, image mode falls back to gradient.
let imageData = null; // <-- replace with your ImageData for image blend modes
let imgW=0, imgH=0, imgPixels=null;
if(imageData){ imgW=imageData.width; imgH=imageData.height; imgPixels=imageData.data; }
for(let y=0;y0){
const g=(grainRand()-0.5)*PARAMS.grain*0.5;
v+=g; v=Math.max(0,Math.min(1,v));
}
if(PARAMS.vignette>0){
const dx=x-cx, dy=y-cy;
const dist=Math.sqrt(dx*dx+dy*dy)/maxDist;
const vig=1 - dist*PARAMS.vignette*0.9;
v*=vig; v=Math.max(0,Math.min(1,v));
}
let r,g,b;
if(PARAMS.mode==="bw"){
let vv=v;
if(PARAMS.invert) vv=1-vv;
if(PARAMS.thresholdOn){ vv=vv>PARAMS.threshold?1:0; }
else if(PARAMS.usePosterize){
const levels=Math.max(2,Math.min(16,Math.round(PARAMS.posterize)));
vv=Math.round(vv*(levels-1))/(levels-1);
}
const c=Math.round(vv*255); r=g=b=c;
} else if(PARAMS.mode==="gradient"){
const col=getGradientColor(v); r=col.r; g=col.g; b=col.b;
} else {
// image mode
if(imgPixels && imgW && imgH){
let u=(sampleX*0.5+0.5)%1, vv2=(sampleY*0.5+0.5)%1;
if(u<0) u+=1; if(vv2<0) vv2+=1;
if(PARAMS.blendMode==="displacement"){
const disp=(v-0.5)*(PARAMS.displacement/50)*0.5;
u=(u+disp)%1; vv2=(vv2+disp)%1;
if(u<0) u+=1; if(vv2<0) vv2+=1;
}
const ix=Math.floor(u*(imgW-1)), iy=Math.floor(vv2*(imgH-1));
const idx=(iy*imgW+ix)*4;
const ir=imgPixels[idx], ig=imgPixels[idx+1], ib=imgPixels[idx+2];
if(PARAMS.blendMode==="colorize" || PARAMS.blendMode==="blend"){
const col=getGradientColor(v);
r=Math.round(ir*(1-PARAMS.blendAmount)+col.r*PARAMS.blendAmount);
g=Math.round(ig*(1-PARAMS.blendAmount)+col.g*PARAMS.blendAmount);
b=Math.round(ib*(1-PARAMS.blendAmount)+col.b*PARAMS.blendAmount);
} else {
r=ir; g=ig; b=ib;
if(PARAMS.blendAmount<1){
const col=getGradientColor(v);
r=Math.round(r*PARAMS.blendAmount + col.r*(1-PARAMS.blendAmount)*0.3 + r*(1-PARAMS.blendAmount)*0.7);
g=Math.round(g*PARAMS.blendAmount + col.g*(1-PARAMS.blendAmount)*0.3 + g*(1-PARAMS.blendAmount)*0.7);
b=Math.round(b*PARAMS.blendAmount + col.b*(1-PARAMS.blendAmount)*0.3 + b*(1-PARAMS.blendAmount)*0.7);
}
}
} else {
const col=getGradientColor(v); r=col.r; g=col.g; b=col.b;
}
}
const idx=(y*w+x)*4;
data[idx]=r; data[idx+1]=g; data[idx+2]=b; data[idx+3]=255;
}
}
ctx.putImageData(imgData,0,0);
if(PARAMS.blur>0) canvas.style.filter="blur("+(PARAMS.blur*0.5)+"px)";
}
// ---- Create canvas and draw ----
let w = PARAMS.exportSize, h = PARAMS.exportSize;
if(PARAMS.aspect==="16:9"){ w=PARAMS.exportSize; h=Math.round(PARAMS.exportSize*9/16); }
else if(PARAMS.aspect==="9:16"){ w=Math.round(PARAMS.exportSize*9/16); h=PARAMS.exportSize; }
else if(PARAMS.aspect==="3:1"){ w=PARAMS.exportSize; h=Math.round(PARAMS.exportSize/3); }
const canvas = document.createElement("canvas");
canvas.width=w; canvas.height=h;
canvas.style.width=w+"px"; canvas.style.height=h+"px";
canvas.style.display="block";
canvas.style.maxWidth="100%";
// Append to body or to a container with id="noise-container" if it exists
const container = document.getElementById("noise-container") || document.body;
container.appendChild(canvas);
render(canvas, w, h, 0, 0);
// Expose for reuse / animation
window.noiseLabRender = render;
window.noiseLabCanvas = canvas;
window.noiseLabParams = PARAMS;
})();