diff --git a/assets/workers/resolve-lygia.esm.js b/assets/workers/resolve-lygia.esm.js index 5537afc..25eab16 100644 --- a/assets/workers/resolve-lygia.esm.js +++ b/assets/workers/resolve-lygia.esm.js @@ -1,4 +1,7 @@ function getFile(url) { + if(url == "https://lygia.xyz/generative/fbm.glsl"){ + url = "/fbm.glsl" + } let httpRequest = new XMLHttpRequest(); httpRequest.open("GET", url, false); httpRequest.send(); @@ -8,6 +11,8 @@ function getFile(url) { return ""; } +const lygiaURL = "https://lygia.xyz" + function resolveLygia(lines) { if ( !Array.isArray(lines) ) { lines = lines.split(/\r?\n/); @@ -18,14 +23,13 @@ function resolveLygia(lines) { const line_trim = line.trim(); if (line_trim.startsWith('#include \"lygia') ) { let include_url = line_trim.substring(15); - include_url = "https://lygia.xyz" + include_url.replace(/\"|\;|\s/g,''); + include_url = lygiaURL + include_url.replace(/\"|\;|\s/g,''); src += getFile(include_url) + '\n'; } else { src += line + '\n'; } }); - return src; } @@ -39,7 +43,7 @@ async function resolveLygiaAsync(lines) { const line_trim = line.trim(); if (line_trim.startsWith('#include "lygia')) { let include_url = line_trim.substring(15); - include_url = "https://lygia.xyz" + include_url.replace(/\"|\;|\s/g, ""); + include_url = lygiaURL + include_url.replace(/\"|\;|\s/g, ""); return fetch(include_url).then((res) => res.text()); } else diff --git a/public/fbm.glsl b/public/fbm.glsl new file mode 100644 index 0000000..bde62dd --- /dev/null +++ b/public/fbm.glsl @@ -0,0 +1,620 @@ +/* +contributors: [Stefan Gustavson, Ian McEwan] +description: modulus of 289 +use: mod289( x) +*/ +#ifndef FNC_MOD289 +#define FNC_MOD289 +float mod289(const in float x) { return x - floor(x * (1. / 289.)) * 289.; } +vec2 mod289(const in vec2 x) { return x - floor(x * (1. / 289.)) * 289.; } +vec3 mod289(const in vec3 x) { return x - floor(x * (1. / 289.)) * 289.; } +vec4 mod289(const in vec4 x) { return x - floor(x * (1. / 289.)) * 289.; } +#endif + + +/* +contributors: [Stefan Gustavson, Ian McEwan] +description: permute +use: permute( x) +examples: + - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag +*/ +#ifndef FNC_PERMUTE +#define FNC_PERMUTE +float permute(const in float v) { return mod289(((v * 34.0) + 1.0) * v); } +vec2 permute(const in vec2 v) { return mod289(((v * 34.0) + 1.0) * v); } +vec3 permute(const in vec3 v) { return mod289(((v * 34.0) + 1.0) * v); } +vec4 permute(const in vec4 v) { return mod289(((v * 34.0) + 1.0) * v); } +#endif + +/* +contributors: [Stefan Gustavson, Ian McEwan] +description: Fast, accurate inverse square root. +use: taylorInvSqrt( x) +*/ +#ifndef FNC_TAYLORINVSQRT +#define FNC_TAYLORINVSQRT +float taylorInvSqrt(in float r) { return 1.79284291400159 - 0.85373472095314 * r; } +vec2 taylorInvSqrt(in vec2 r) { return 1.79284291400159 - 0.85373472095314 * r; } +vec3 taylorInvSqrt(in vec3 r) { return 1.79284291400159 - 0.85373472095314 * r; } +vec4 taylorInvSqrt(in vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } +#endif +/* +contributors: [Stefan Gustavson, Ian McEwan] +description: grad4, used for snoise(vec4 v) +use: grad4( j, ip) +*/ +#ifndef FNC_GRAD4 +#define FNC_GRAD4 +vec4 grad4(float j, vec4 ip) { + const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); + vec4 p,s; + p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; + p.w = 1.5 - dot(abs(p.xyz), ones.xyz); + s = vec4(lessThan(p, vec4(0.0))); + p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; + return p; +} +#endif + +/* +contributors: [Stefan Gustavson, Ian McEwan] +description: Simplex Noise https://github.com/stegu/webgl-noise +use: snoise( pos) +license: | + Copyright 2021-2023 by Stefan Gustavson and Ian McEwan. + Published under the terms of the MIT license: + https://opensource.org/license/mit/ +examples: + - /shaders/generative_snoise.frag +*/ +#ifndef FNC_SNOISE +#define FNC_SNOISE +float snoise(in vec2 v) { + const vec4 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 + vec2 i = floor(v + dot(v, C.yy) ); + vec2 x0 = v - i + dot(i, C.xx); + // Other corners + vec2 i1; + //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 + //i1.y = 1.0 - i1.x; + i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); + // x0 = x0 - 0.0 + 0.0 * C.xx ; + // x1 = x0 - i1 + 1.0 * C.xx ; + // x2 = x0 - 1.0 + 2.0 * C.xx ; + vec4 x12 = x0.xyxy + C.xxzz; + x12.xy -= i1; + // Permutations + i = mod289(i); // Avoid truncation effects in permutation + vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + + i.x + vec3(0.0, i1.x, 1.0 )); + vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); + m = m*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) + vec3 x = 2.0 * fract(p * C.www) - 1.0; + vec3 h = abs(x) - 0.5; + vec3 ox = floor(x + 0.5); + vec3 a0 = x - ox; + // Normalise 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 + vec3 g; + g.x = a0.x * x0.x + h.x * x0.y; + g.yz = a0.yz * x12.xz + h.yz * x12.yw; + return 130.0 * dot(m, g); +} +float snoise(in vec3 v) { + const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; + const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + // First corner + vec3 i = floor(v + dot(v, C.yyy) ); + vec3 x0 = v - i + dot(i, C.xxx) ; + // Other corners + vec3 g = step(x0.yzx, x0.xyz); + vec3 l = 1.0 - g; + vec3 i1 = min( g.xyz, l.zxy ); + vec3 i2 = max( g.xyz, l.zxy ); + // x0 = x0 - 0.0 + 0.0 * C.xxx; + // x1 = x0 - i1 + 1.0 * C.xxx; + // x2 = x0 - i2 + 2.0 * C.xxx; + // x3 = x0 - 1.0 + 3.0 * C.xxx; + vec3 x1 = x0 - i1 + C.xxx; + vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y + vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y + // Permutations + i = mod289(i); + vec4 p = permute( permute( permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + float n_ = 0.142857142857; // 1.0/7.0 + vec3 ns = n_ * D.wyz - D.xzx; + vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) + vec4 x_ = floor(j * ns.z); + vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) + vec4 x = x_ *ns.x + ns.yyyy; + vec4 y = y_ *ns.x + ns.yyyy; + vec4 h = 1.0 - abs(x) - abs(y); + vec4 b0 = vec4( x.xy, y.xy ); + vec4 b1 = vec4( x.zw, y.zw ); + //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + vec4 s0 = floor(b0)*2.0 + 1.0; + vec4 s1 = floor(b1)*2.0 + 1.0; + vec4 sh = -step(h, vec4(0.0)); + vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; + vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; + vec3 p0 = vec3(a0.xy,h.x); + vec3 p1 = vec3(a0.zw,h.y); + vec3 p2 = vec3(a1.xy,h.z); + vec3 p3 = vec3(a1.zw,h.w); + //Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + // Mix final noise value + vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); + m = m * m; + return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), + dot(p2,x2), dot(p3,x3) ) ); +} +float snoise(in vec4 v) { + const vec4 C = vec4( 0.138196601125011, // (5 - sqrt(5))/20 G4 + 0.276393202250021, // 2 * G4 + 0.414589803375032, // 3 * G4 + -0.447213595499958); // -1 + 4 * G4 + // First corner + vec4 i = floor(v + dot(v, vec4(.309016994374947451)) ); // (sqrt(5) - 1)/4 + vec4 x0 = v - i + dot(i, C.xxxx); + // Other corners + // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + vec4 i0; + vec3 isX = step( x0.yzw, x0.xxx ); + vec3 isYZ = step( x0.zww, x0.yyz ); + // i0.x = dot( isX, vec3( 1.0 ) ); + i0.x = isX.x + isX.y + isX.z; + i0.yzw = 1.0 - isX; + // i0.y += dot( isYZ.xy, vec2( 1.0 ) ); + i0.y += isYZ.x + isYZ.y; + i0.zw += 1.0 - isYZ.xy; + i0.z += isYZ.z; + i0.w += 1.0 - isYZ.z; + // i0 now contains the unique values 0,1,2,3 in each channel + vec4 i3 = clamp( i0, 0.0, 1.0 ); + vec4 i2 = clamp( i0-1.0, 0.0, 1.0 ); + vec4 i1 = clamp( i0-2.0, 0.0, 1.0 ); + // x0 = x0 - 0.0 + 0.0 * C.xxxx + // x1 = x0 - i1 + 1.0 * C.xxxx + // x2 = x0 - i2 + 2.0 * C.xxxx + // x3 = x0 - i3 + 3.0 * C.xxxx + // x4 = x0 - 1.0 + 4.0 * C.xxxx + vec4 x1 = x0 - i1 + C.xxxx; + vec4 x2 = x0 - i2 + C.yyyy; + vec4 x3 = x0 - i3 + C.zzzz; + vec4 x4 = x0 + C.wwww; + // Permutations + i = mod289(i); + float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x); + vec4 j1 = permute( permute( permute( permute ( + i.w + vec4(i1.w, i2.w, i3.w, 1.0 )) + + i.z + vec4(i1.z, i2.z, i3.z, 1.0 )) + + i.y + vec4(i1.y, i2.y, i3.y, 1.0 )) + + i.x + vec4(i1.x, i2.x, i3.x, 1.0 )); + // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope + // 7*7*6 = 294, which is close to the ring size 17*17 = 289. + vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ; + vec4 p0 = grad4(j0, ip); + vec4 p1 = grad4(j1.x, ip); + vec4 p2 = grad4(j1.y, ip); + vec4 p3 = grad4(j1.z, ip); + vec4 p4 = grad4(j1.w, ip); + // Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= taylorInvSqrt(dot(p4,p4)); + // Mix contributions from the five corners + vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0); + vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0); + m0 = m0 * m0; + m1 = m1 * m1; + return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ))) + + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ; +} +vec2 snoise2( vec2 x ){ + float s = snoise(vec2( x )); + float s1 = snoise(vec2( x.y - 19.1, x.x + 47.2 )); + return vec2( s , s1 ); +} +vec3 snoise3( vec3 x ){ + float s = snoise(vec3( x )); + float s1 = snoise(vec3( x.y - 19.1 , x.z + 33.4 , x.x + 47.2 )); + float s2 = snoise(vec3( x.z + 74.2 , x.x - 124.5 , x.y + 99.4 )); + return vec3( s , s1 , s2 ); +} +vec3 snoise3( vec4 x ){ + float s = snoise(vec4( x )); + float s1 = snoise(vec4( x.y - 19.1 , x.z + 33.4 , x.x + 47.2, x.w )); + float s2 = snoise(vec4( x.z + 74.2 , x.x - 124.5 , x.y + 99.4, x.w )); + return vec3( s , s1 , s2 ); +} +#endif + +/* +contributors: ["Patricio Gonzalez Vivo", "David Hoskins", "Inigo Quilez"] +description: Pass a value and get some random normalize value between 0 and 1 +use: float random[2|3]( value) +options: + - RANDOM_HIGHER_RANGE: for working with a range over 0 and 1 + - RANDOM_SINLESS: Use sin-less random, which tolerates bigger values before producing pattern. From https://www.shadertoy.com/view/4djSRW + - RANDOM_SCALE: by default this scale if for number with a big range. For producing good random between 0 and 1 use bigger range +examples: + - /shaders/generative_random.frag +license: + - MIT License (MIT) Copyright 2014, David Hoskins +*/ +#ifndef RANDOM_SCALE +#ifdef RANDOM_HIGHER_RANGE +#define RANDOM_SCALE vec4(.1031, .1030, .0973, .1099) +#else +#define RANDOM_SCALE vec4(443.897, 441.423, .0973, .1099) +#endif +#endif +#ifndef FNC_RANDOM +#define FNC_RANDOM +float random(in float x) { +#ifdef RANDOM_SINLESS + x = fract(x * RANDOM_SCALE.x); + x *= x + 33.33; + x *= x + x; + return fract(x); +#else + return fract(sin(x) * 43758.5453); +#endif +} +float random(in vec2 st) { +#ifdef RANDOM_SINLESS + vec3 p3 = fract(vec3(st.xyx) * RANDOM_SCALE.xyz); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +#else + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +#endif +} +float random(in vec3 pos) { +#ifdef RANDOM_SINLESS + pos = fract(pos * RANDOM_SCALE.xyz); + pos += dot(pos, pos.zyx + 31.32); + return fract((pos.x + pos.y) * pos.z); +#else + return fract(sin(dot(pos.xyz, vec3(70.9898, 78.233, 32.4355))) * 43758.5453123); +#endif +} +float random(in vec4 pos) { +#ifdef RANDOM_SINLESS + pos = fract(pos * RANDOM_SCALE); + pos += dot(pos, pos.wzxy + 33.33); + return fract((pos.x + pos.y) * (pos.z + pos.w)); +#else + float dot_product = dot(pos, vec4(12.9898,78.233,45.164,94.673)); + return fract(sin(dot_product) * 43758.5453); +#endif +} +vec2 random2(float p) { + vec3 p3 = fract(vec3(p) * RANDOM_SCALE.xyz); + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.xx + p3.yz) * p3.zy); +} +vec2 random2(vec2 p) { + vec3 p3 = fract(p.xyx * RANDOM_SCALE.xyz); + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.xx + p3.yz) * p3.zy); +} +vec2 random2(vec3 p3) { + p3 = fract(p3 * RANDOM_SCALE.xyz); + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.xx + p3.yz) * p3.zy); +} +vec3 random3(float p) { + vec3 p3 = fract(vec3(p) * RANDOM_SCALE.xyz); + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.xxy + p3.yzz) * p3.zyx); +} +vec3 random3(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * RANDOM_SCALE.xyz); + p3 += dot(p3, p3.yxz + 19.19); + return fract((p3.xxy + p3.yzz) * p3.zyx); +} +vec3 random3(vec3 p) { + p = fract(p * RANDOM_SCALE.xyz); + p += dot(p, p.yxz + 19.19); + return fract((p.xxy + p.yzz) * p.zyx); +} +vec4 random4(float p) { + vec4 p4 = fract(p * RANDOM_SCALE); + p4 += dot(p4, p4.wzxy + 19.19); + return fract((p4.xxyz + p4.yzzw) * p4.zywx); +} +vec4 random4(vec2 p) { + vec4 p4 = fract(p.xyxy * RANDOM_SCALE); + p4 += dot(p4, p4.wzxy + 19.19); + return fract((p4.xxyz + p4.yzzw) * p4.zywx); +} +vec4 random4(vec3 p) { + vec4 p4 = fract(p.xyzx * RANDOM_SCALE); + p4 += dot(p4, p4.wzxy + 19.19); + return fract((p4.xxyz + p4.yzzw) * p4.zywx); +} +vec4 random4(vec4 p4) { + p4 = fract(p4 * RANDOM_SCALE); + p4 += dot(p4, p4.wzxy + 19.19); + return fract((p4.xxyz + p4.yzzw) * p4.zywx); +} +#endif +/* +contributors: Patricio Gonzalez Vivo +description: Signed Random +use: srandomX( x) +license: + - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0 + - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license +*/ +#ifndef FNC_SRANDOM +#define FNC_SRANDOM +float srandom(in float x) { + return -1. + 2. * fract(sin(x) * 43758.5453); +} +float srandom(in vec2 st) { + return -1. + 2. * fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); +} +float srandom(in vec3 pos) { + return -1. + 2. * fract(sin(dot(pos.xyz, vec3(70.9898, 78.233, 32.4355))) * 43758.5453123); +} +float srandom(in vec4 pos) { + float dot_product = dot(pos, vec4(12.9898,78.233,45.164,94.673)); + return -1. + 2. * fract(sin(dot_product) * 43758.5453); +} +vec2 srandom2(in vec2 st) { + const vec2 k = vec2(.3183099, .3678794); + st = st * k + k.yx; + return -1. + 2. * fract(16. * k * fract(st.x * st.y * (st.x + st.y))); +} +vec3 srandom3(in vec3 p) { + p = vec3( dot(p, vec3(127.1, 311.7, 74.7)), + dot(p, vec3(269.5, 183.3, 246.1)), + dot(p, vec3(113.5, 271.9, 124.6))); + return -1. + 2. * fract(sin(p) * 43758.5453123); +} +vec2 srandom2(in vec2 p, const in float tileLength) { + p = mod(p, vec2(tileLength)); + return srandom2(p); +} +vec3 srandom3(in vec3 p, const in float tileLength) { + p = mod(p, vec3(tileLength)); + return srandom3(p); +} +#endif +/* +contributors: Inigo Quiles +description: cubic polynomial https://iquilezles.org/articles/smoothsteps/ +use: cubic( value[, in, out]); +examples: + - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag +*/ +#ifndef FNC_CUBIC +#define FNC_CUBIC +float cubic(const in float v) { return v*v*(3.0-2.0*v); } +vec2 cubic(const in vec2 v) { return v*v*(3.0-2.0*v); } +vec3 cubic(const in vec3 v) { return v*v*(3.0-2.0*v); } +vec4 cubic(const in vec4 v) { return v*v*(3.0-2.0*v); } +float cubic(const in float v, in float slope0, in float slope1) { + float a = slope0 + slope1 - 2.; + float b = -2. * slope0 - slope1 + 3.; + float c = slope0; + float v2 = v * v; + float v3 = v * v2; + return a * v3 + b * v2 + c * v; +} +vec2 cubic(const in vec2 v, in float slope0, in float slope1) { + float a = slope0 + slope1 - 2.; + float b = -2. * slope0 - slope1 + 3.; + float c = slope0; + vec2 v2 = v * v; + vec2 v3 = v * v2; + return a * v3 + b * v2 + c * v; +} +vec3 cubic(const in vec3 v, in float slope0, in float slope1) { + float a = slope0 + slope1 - 2.; + float b = -2. * slope0 - slope1 + 3.; + float c = slope0; + vec3 v2 = v * v; + vec3 v3 = v * v2; + return a * v3 + b * v2 + c * v; +} +vec4 cubic(const in vec4 v, in float slope0, in float slope1) { + float a = slope0 + slope1 - 2.; + float b = -2. * slope0 - slope1 + 3.; + float c = slope0; + vec4 v2 = v * v; + vec4 v3 = v * v2; + return a * v3 + b * v2 + c * v; +} +#endif +/* +contributors: Inigo Quiles +description: quintic polynomial https://iquilezles.org/articles/smoothsteps/ +use: quintic( value); +examples: + - https://raw.githubusercontent.com/patriciogonzalezvivo/lygia_examples/main/math_functions.frag +*/ +#ifndef FNC_QUINTIC +#define FNC_QUINTIC +float quintic(const in float v) { return v*v*v*(v*(v*6.0-15.0)+10.0); } +vec2 quintic(const in vec2 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); } +vec3 quintic(const in vec3 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); } +vec4 quintic(const in vec4 v) { return v*v*v*(v*(v*6.0-15.0)+10.0); } +#endif +/* +contributors: Patricio Gonzalez Vivo +description: Gradient Noise +use: gnoise( x) +license: + - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0 + - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license +*/ +#ifndef FNC_GNOISE +#define FNC_GNOISE +float gnoise(float x) { + float i = floor(x); // integer + float f = fract(x); // fraction + return mix(random(i), random(i + 1.0), smoothstep(0.,1.,f)); +} +float gnoise(vec2 st) { + vec2 i = floor(st); + vec2 f = fract(st); + float a = random(i); + float b = random(i + vec2(1.0, 0.0)); + float c = random(i + vec2(0.0, 1.0)); + float d = random(i + vec2(1.0, 1.0)); + vec2 u = cubic(f); + return mix( a, b, u.x) + + (c - a)* u.y * (1.0 - u.x) + + (d - b) * u.x * u.y; +} +float gnoise(vec3 p) { + vec3 i = floor(p); + vec3 f = fract(p); + vec3 u = quintic(f); + return -1.0 + 2.0 * mix( mix( mix( random(i + vec3(0.0,0.0,0.0)), + random(i + vec3(1.0,0.0,0.0)), u.x), + mix( random(i + vec3(0.0,1.0,0.0)), + random(i + vec3(1.0,1.0,0.0)), u.x), u.y), + mix( mix( random(i + vec3(0.0,0.0,1.0)), + random(i + vec3(1.0,0.0,1.0)), u.x), + mix( random(i + vec3(0.0,1.0,1.0)), + random(i + vec3(1.0,1.0,1.0)), u.x), u.y), u.z ); +} +float gnoise(vec3 p, float tileLength) { + vec3 i = floor(p); + vec3 f = fract(p); + vec3 u = quintic(f); + return mix( mix( mix( dot( srandom3(i + vec3(0.0,0.0,0.0), tileLength), f - vec3(0.0,0.0,0.0)), + dot( srandom3(i + vec3(1.0,0.0,0.0), tileLength), f - vec3(1.0,0.0,0.0)), u.x), + mix( dot( srandom3(i + vec3(0.0,1.0,0.0), tileLength), f - vec3(0.0,1.0,0.0)), + dot( srandom3(i + vec3(1.0,1.0,0.0), tileLength), f - vec3(1.0,1.0,0.0)), u.x), u.y), + mix( mix( dot( srandom3(i + vec3(0.0,0.0,1.0), tileLength), f - vec3(0.0,0.0,1.0)), + dot( srandom3(i + vec3(1.0,0.0,1.0), tileLength), f - vec3(1.0,0.0,1.0)), u.x), + mix( dot( srandom3(i + vec3(0.0,1.0,1.0), tileLength), f - vec3(0.0,1.0,1.0)), + dot( srandom3(i + vec3(1.0,1.0,1.0), tileLength), f - vec3(1.0,1.0,1.0)), u.x), u.y), u.z ); +} +vec3 gnoise3(vec3 x) { + return vec3(gnoise(x+vec3(123.456, 0.567, 0.37)), + gnoise(x+vec3(0.11, 47.43, 19.17)), + gnoise(x) ); +} +#endif +/* +contributors: Patricio Gonzalez Vivo +description: Fractal Brownian Motion +use: fbm( pos) +options: + FBM_OCTAVES: numbers of octaves. Default is 4. + FBM_NOISE_FNC(UV): noise function to use Default 'snoise(UV)' (simplex noise) + FBM_VALUE_INITIAL: initial value. Default is 0. + FBM_SCALE_SCALAR: scalar. Defualt is 2. + FBM_AMPLITUD_INITIAL: initial amplitud value. Default is 0.5 + FBM_AMPLITUD_SCALAR: amplitud scalar. Default is 0.5 +examples: + - /shaders/generative_fbm.frag +license: + - Copyright (c) 2021 Patricio Gonzalez Vivo under Prosperity License - https://prosperitylicense.com/versions/3.0.0 + - Copyright (c) 2021 Patricio Gonzalez Vivo under Patron License - https://lygia.xyz/license +*/ +#ifndef FBM_OCTAVES +#define FBM_OCTAVES 4 +#endif +#ifndef FBM_NOISE_FNC +#define FBM_NOISE_FNC(UV) snoise(UV) +#endif +#ifndef FBM_NOISE2_FNC +#define FBM_NOISE2_FNC(UV) FBM_NOISE_FNC(UV) +#endif +#ifndef FBM_NOISE3_FNC +#define FBM_NOISE3_FNC(UV) FBM_NOISE_FNC(UV) +#endif +#ifndef FBM_NOISE_TILABLE_FNC +#define FBM_NOISE_TILABLE_FNC(UV, TILE) gnoise(UV, TILE) +#endif +#ifndef FBM_NOISE3_TILABLE_FNC +#define FBM_NOISE3_TILABLE_FNC(UV, TILE) FBM_NOISE_TILABLE_FNC(UV, TILE) +#endif +#ifndef FBM_NOISE_TYPE +#define FBM_NOISE_TYPE float +#endif +#ifndef FBM_VALUE_INITIAL +#define FBM_VALUE_INITIAL 0.0 +#endif +#ifndef FBM_SCALE_SCALAR +#define FBM_SCALE_SCALAR 2.0 +#endif +#ifndef FBM_AMPLITUD_INITIAL +#define FBM_AMPLITUD_INITIAL 0.5 +#endif +#ifndef FBM_AMPLITUD_SCALAR +#define FBM_AMPLITUD_SCALAR 0.5 +#endif +#ifndef FNC_FBM +#define FNC_FBM +FBM_NOISE_TYPE fbm(in vec2 st) { + // Initial values + FBM_NOISE_TYPE value = FBM_NOISE_TYPE(FBM_VALUE_INITIAL); + float amplitud = FBM_AMPLITUD_INITIAL; + // Loop of octaves + for (int i = 0; i < FBM_OCTAVES; i++) { + value += amplitud * FBM_NOISE2_FNC(st); + st *= FBM_SCALE_SCALAR; + amplitud *= FBM_AMPLITUD_SCALAR; + } + return value; +} +FBM_NOISE_TYPE fbm(in vec3 pos) { + // Initial values + FBM_NOISE_TYPE value = FBM_NOISE_TYPE(FBM_VALUE_INITIAL); + float amplitud = FBM_AMPLITUD_INITIAL; + // Loop of octaves + for (int i = 0; i < FBM_OCTAVES; i++) { + value += amplitud * FBM_NOISE3_FNC(pos); + pos *= FBM_SCALE_SCALAR; + amplitud *= FBM_AMPLITUD_SCALAR; + } + return value; +} +FBM_NOISE_TYPE fbm(vec3 p, float tileLength) { + const float persistence = 0.5; + const float lacunarity = 2.0; + float amplitude = 0.5; + FBM_NOISE_TYPE total = FBM_NOISE_TYPE(0.0); + float normalization = 0.0; + for (int i = 0; i < FBM_OCTAVES; ++i) { + float noiseValue = FBM_NOISE3_TILABLE_FNC(p, tileLength * lacunarity * 0.5) * 0.5 + 0.5; + total += noiseValue * amplitude; + normalization += amplitude; + amplitude *= persistence; + p = p * lacunarity; + } + return total / normalization; +} +#endif