#define_import_path forky::noise /* https://gist.github.com/munrocket/236ed5ba7e409b8bdf1ff6eca5dcdc39 # WGSL Noise Algorithms > Operator % has changed, probably current code need a fix ## Value noise ![](https://habrastorage.org/webt/pq/qj/aw/pqqjawx0lz3nupdrqzzz_lut3u8.jpeg) */ fn rand(n: f32) -> f32 { return fract(sin(n) * 43758.5453123); } fn noise(p: f32) -> f32 { let fl = floor(p); let fc = fract(p); return mix(rand(fl), rand(fl + 1.), fc); } /* ![](https://habrastorage.org/webt/vy/em/e9/vyeme9gogvhwetu6o1adzzylevg.jpeg) */ fn rand2(n: vec2) -> f32 { return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); } fn noise2(n: vec2) -> f32 { let d = vec2(0., 1.); let b = floor(n); let f = smoothStep(vec2(0.), vec2(1.), fract(n)); return mix(mix(rand2(b), rand2(b + d.yx), f.x), mix(rand2(b + d.xy), rand2(b + d.yy), f.x), f.y); } /* ![](https://habrastorage.org/webt/qu/jd/oe/qujdoegt1sts87aiunz_s3_tqbu.jpeg) */ fn mod289(x: vec4) -> vec4 { return x - floor(x * (1. / 289.)) * 289.; } fn perm4(x: vec4) -> vec4 { return mod289(((x * 34.) + 1.) * x); } fn noise3(p: vec3) -> f32 { let a = floor(p); var d: vec3 = p - a; d = d * d * (3. - 2. * d); let b = a.xxyy + vec4(0., 1., 0., 1.); let k1 = perm4(b.xyxy); let k2 = perm4(k1.xyxy + b.zzww); let c = k2 + a.zzzz; let k3 = perm4(c); let k4 = perm4(c + 1.); let o1 = fract(k3 * (1. / 41.)); let o2 = fract(k4 * (1. / 41.)); let o3 = o2 * d.z + o1 * (1. - d.z); let o4 = o3.yw * d.x + o3.xz * (1. - d.x); return o4.y * d.y + o4.x * (1. - d.y); } /* ## Perlin noise ![](https://habrastorage.org/webt/v9/a5/lm/v9a5lmu7mbk_dwvxptvx0krhrhm.jpeg) */ // MIT License. © Stefan Gustavson, Munrocket // fn permute4(x: vec4) -> vec4 { return ((x * 34. + 1.) * x) % vec4(289.); } fn fade2(t: vec2) -> vec2 { return t * t * t * (t * (t * 6. - 15.) + 10.); } fn perlinNoise2(P: vec2) -> f32 { var Pi: vec4 = floor(P.xyxy) + vec4(0., 0., 1., 1.); let Pf = fract(P.xyxy) - vec4(0., 0., 1., 1.); Pi = Pi % vec4(289.); // To avoid truncation effects in permutation let ix = Pi.xzxz; let iy = Pi.yyww; let fx = Pf.xzxz; let fy = Pf.yyww; let i = permute4(permute4(ix) + iy); var gx: vec4 = 2. * fract(i * 0.0243902439) - 1.; // 1/41 = 0.024... let gy = abs(gx) - 0.5; let tx = floor(gx + 0.5); gx = gx - tx; var g00: vec2 = vec2(gx.x, gy.x); var g10: vec2 = vec2(gx.y, gy.y); var g01: vec2 = vec2(gx.z, gy.z); var g11: vec2 = vec2(gx.w, gy.w); let norm = 1.79284291400159 - 0.85373472095314 * vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)); g00 = g00 * norm.x; g01 = g01 * norm.y; g10 = g10 * norm.z; g11 = g11 * norm.w; let n00 = dot(g00, vec2(fx.x, fy.x)); let n10 = dot(g10, vec2(fx.y, fy.y)); let n01 = dot(g01, vec2(fx.z, fy.z)); let n11 = dot(g11, vec2(fx.w, fy.w)); let fade_xy = fade2(Pf.xy); let n_x = mix(vec2(n00, n01), vec2(n10, n11), vec2(fade_xy.x)); let n_xy = mix(n_x.x, n_x.y, fade_xy.y); return 2.3 * n_xy; } /* ![](https://habrastorage.org/webt/r0/db/mi/r0dbmiy7ezkpzs8hricyknptdi4.jpeg) */ // MIT License. © Stefan Gustavson, Munrocket // fn permute4(x: vec4) -> vec4 { return ((x * 34. + 1.) * x) % vec4(289.); } fn taylorInvSqrt4(r: vec4) -> vec4 { return 1.79284291400159 - 0.85373472095314 * r; } fn fade3(t: vec3) -> vec3 { return t * t * t * (t * (t * 6. - 15.) + 10.); } fn perlinNoise3(P: vec3) -> f32 { var Pi0 : vec3 = floor(P); // Integer part for indexing var Pi1 : vec3 = Pi0 + vec3(1.); // Integer part + 1 Pi0 = Pi0 % vec3(289.); Pi1 = Pi1 % vec3(289.); let Pf0 = fract(P); // Fractional part for interpolation let Pf1 = Pf0 - vec3(1.); // Fractional part - 1. let ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); let iy = vec4(Pi0.yy, Pi1.yy); let iz0 = Pi0.zzzz; let iz1 = Pi1.zzzz; let ixy = permute4(permute4(ix) + iy); let ixy0 = permute4(ixy + iz0); let ixy1 = permute4(ixy + iz1); var gx0: vec4 = ixy0 / 7.; var gy0: vec4 = fract(floor(gx0) / 7.) - 0.5; gx0 = fract(gx0); var gz0: vec4 = vec4(0.5) - abs(gx0) - abs(gy0); var sz0: vec4 = step(gz0, vec4(0.)); gx0 = gx0 + sz0 * (step(vec4(0.), gx0) - 0.5); gy0 = gy0 + sz0 * (step(vec4(0.), gy0) - 0.5); var gx1: vec4 = ixy1 / 7.; var gy1: vec4 = fract(floor(gx1) / 7.) - 0.5; gx1 = fract(gx1); var gz1: vec4 = vec4(0.5) - abs(gx1) - abs(gy1); var sz1: vec4 = step(gz1, vec4(0.)); gx1 = gx1 - sz1 * (step(vec4(0.), gx1) - 0.5); gy1 = gy1 - sz1 * (step(vec4(0.), gy1) - 0.5); var g000: vec3 = vec3(gx0.x, gy0.x, gz0.x); var g100: vec3 = vec3(gx0.y, gy0.y, gz0.y); var g010: vec3 = vec3(gx0.z, gy0.z, gz0.z); var g110: vec3 = vec3(gx0.w, gy0.w, gz0.w); var g001: vec3 = vec3(gx1.x, gy1.x, gz1.x); var g101: vec3 = vec3(gx1.y, gy1.y, gz1.y); var g011: vec3 = vec3(gx1.z, gy1.z, gz1.z); var g111: vec3 = vec3(gx1.w, gy1.w, gz1.w); let norm0 = taylorInvSqrt4( vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); g000 = g000 * norm0.x; g010 = g010 * norm0.y; g100 = g100 * norm0.z; g110 = g110 * norm0.w; let norm1 = taylorInvSqrt4( vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); g001 = g001 * norm1.x; g011 = g011 * norm1.y; g101 = g101 * norm1.z; g111 = g111 * norm1.w; let n000 = dot(g000, Pf0); let n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); let n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); let n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); let n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); let n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); let n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); let n111 = dot(g111, Pf1); var fade_xyz: vec3 = fade3(Pf0); let temp = vec4(f32(fade_xyz.z)); // simplify after chrome bug fix let n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), temp); let n_yz = mix(n_z.xy, n_z.zw, vec2(f32(fade_xyz.y))); // simplify after chrome bug fix let n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); return 2.2 * n_xyz; } /* ## Simplex noise ![](https://habrastorage.org/webt/cv/c5/xt/cvc5xtkaeelocohjjt44wcah-im.jpeg) */ // MIT License. © Ian McEwan, Stefan Gustavson, Munrocket, Johan Helsing // fn mod289(x: vec2) -> vec2 { return x - floor(x * (1. / 289.)) * 289.; } fn mod289_3(x: vec3) -> vec3 { return x - floor(x * (1. / 289.)) * 289.; } fn permute3(x: vec3) -> vec3 { return mod289_3(((x * 34.) + 1.) * x); } // MIT License. © Ian McEwan, Stefan Gustavson, Munrocket fn simplexNoise2(v: vec2) -> f32 { let C = vec4( 0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439 // 1.0 / 41.0 ); // First corner var i = floor(v + dot(v, C.yy)); let x0 = v - i + dot(i, C.xx); // Other corners var i1 = select(vec2(0., 1.), vec2(1., 0.), x0.x > x0.y); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; var x12 = x0.xyxy + C.xxzz; x12.x = x12.x - i1.x; x12.y = x12.y - i1.y; // Permutations i = mod289(i); // Avoid truncation effects in permutation var p = permute3(permute3(i.y + vec3(0., i1.y, 1.)) + i.x + vec3(0., i1.x, 1.)); var m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), vec3(0.)); m *= m; m *= m; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) let x = 2. * fract(p * C.www) - 1.; let h = abs(x) - 0.5; let ox = floor(x + 0.5); let a0 = x - ox; // Normalize gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h); // Compute final noise value at P let g = vec3(a0.x * x0.x + h.x * x0.y, a0.yz * x12.xz + h.yz * x12.yw); return 130. * dot(m, g); } /* ## FBM */ // MIT License. © Inigo Quilez, Munrocket // noise2() is any noise here: Value, Perlin, Simplex, Worley // var m2: mat2x2 = mat2x2(vec2(0.8, 0.6), vec2(-0.6, 0.8)); fn fbm(p: vec2) -> f32 { var f: f32 = 0.; f = f + 0.5000 * noise2(p); p = m2 * p * 2.02; f = f + 0.2500 * noise2(p); p = m2 * p * 2.03; f = f + 0.1250 * noise2(p); p = m2 * p * 2.01; f = f + 0.0625 * noise2(p); return f / 0.9375; } /* ## VoroNoise */ // // by Inigo Quilez // fn hash23(p: vec2) -> vec3 { let q = vec3(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)), dot(p, vec2(419.2, 371.9))); return fract(sin(q) * 43758.5453); } fn voroNoise2(x: vec2, u: f32, v: f32) -> f32 { let p = floor(x); let f = fract(x); let k = 1. + 63. * pow(1. - v, 4.); var va: f32 = 0.; var wt: f32 = 0.; for(var j: i32 = -2; j <= 2; j = j + 1) { for(var i: i32 = -2; i <= 2; i = i + 1) { let g = vec2(f32(i), f32(j)); let o = hash23(p + g) * vec3(u, u, 1.); let r = g - f + o.xy; let d = dot(r, r); let ww = pow(1. - smoothStep(0., 1.414, sqrt(d)), k); va = va + o.z * ww; wt = wt + ww; } } return va / wt; } /* ### Main references - Stefan Gustavson (http://github.com/ashima/webgl-noise) - Inigo Quilez (https://iquilezles.org/www/index.htm) - Patricio Gonzalez Vivo (https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83) ### 2do - [x] translate main noises - [x] add images if possible - [ ] revisit, becasue % operator has changed - [ ] Worley noise, integer based value noise */