diff --git a/tools/src/generative/Accretion.frag b/tools/src/generative/Accretion.frag new file mode 100644 index 0000000..fffc857 --- /dev/null +++ b/tools/src/generative/Accretion.frag @@ -0,0 +1,38 @@ +/* + "Accretion" by @XorDev + + I discovered an interesting refraction effect + by adding the raymarch iterator to the turbulence! + https://x.com/XorDev/status/1936884244128661986 +*/ + +void mainImage(out vec4 O, vec2 I) +{ + //Raymarch depth + float z, + //Step distance + d, + //Raymarch iterator + i; + //Clear fragColor and raymarch 100 steps + for(O*=i; i++<2e1; ) + { + //Sample point (from ray direction) + vec3 p = z*normalize(vec3(I+I,0)-iResolution.xyx)+.1; + + //Polar coordinates and additional transformations + p = vec3(atan(p.y/.2,p.x)*2., p.z/3., length(p.xy)-5.-z*.2); + + //Apply turbulence and refraction effect + for(d=0.; d++<7.;) + p += sin(p.yzx*d+iTime+.3*i)/d; + + //Distance to cylinder and waves with refraction + z += d = length(vec4(.4*cos(p)-.4, p.z)); + + //Coloring and brightness + O += (1.+cos(p.x+i*.4+z+vec4(6,1,2,0)))/d; + } + //Tanh tonemap + O = tanh(O*O/4e2); +} \ No newline at end of file diff --git a/tools/src/generative/Daedra.frag b/tools/src/generative/Daedra.frag new file mode 100644 index 0000000..383bbee --- /dev/null +++ b/tools/src/generative/Daedra.frag @@ -0,0 +1,49 @@ +//const float gridSize = iResolution.x*0.1; + +bool circleTest(vec2 pos, vec2 size, vec2 uv){ + if(distance(pos,uv) < size.x){ + return true; + } else { + return false; + } +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + // Normalized pixel coordinates (from 0 to 1) + vec2 uv = fragCoord/iResolution.y; + + float gridSize = iResolution.x*0.05; + + uv = fract(uv*gridSize); + + vec4 cam = texture(iChannel0, floor((fragCoord/iResolution.xy)*gridSize)*(1.0/gridSize)); + + vec3 col = vec3(0.0); + + bool circleR = circleTest(vec2(0.7,0.7),vec2(cam.x*0.5), uv); + bool circleG = circleTest(vec2(0.3,0.5),vec2(cam.y*0.5), uv); + bool circleB = circleTest(vec2(0.7,0.3),vec2(cam.z*0.5), uv); + + // Output to screen + if(circleR){ + col.x = 1.0; + } else { + col.x = 0.0; + } + + if(circleG){ + col.y = 1.0; + } else { + col.y = 0.0; + } + + if(circleB){ + col.z = 1.0; + } else { + col.z = 0.0; + } + + fragColor = vec4(col,1.0); + +} diff --git a/tools/src/generative/Just Another Cube.frag b/tools/src/generative/Just Another Cube.frag new file mode 100644 index 0000000..383bbee --- /dev/null +++ b/tools/src/generative/Just Another Cube.frag @@ -0,0 +1,49 @@ +//const float gridSize = iResolution.x*0.1; + +bool circleTest(vec2 pos, vec2 size, vec2 uv){ + if(distance(pos,uv) < size.x){ + return true; + } else { + return false; + } +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + // Normalized pixel coordinates (from 0 to 1) + vec2 uv = fragCoord/iResolution.y; + + float gridSize = iResolution.x*0.05; + + uv = fract(uv*gridSize); + + vec4 cam = texture(iChannel0, floor((fragCoord/iResolution.xy)*gridSize)*(1.0/gridSize)); + + vec3 col = vec3(0.0); + + bool circleR = circleTest(vec2(0.7,0.7),vec2(cam.x*0.5), uv); + bool circleG = circleTest(vec2(0.3,0.5),vec2(cam.y*0.5), uv); + bool circleB = circleTest(vec2(0.7,0.3),vec2(cam.z*0.5), uv); + + // Output to screen + if(circleR){ + col.x = 1.0; + } else { + col.x = 0.0; + } + + if(circleG){ + col.y = 1.0; + } else { + col.y = 0.0; + } + + if(circleB){ + col.z = 1.0; + } else { + col.z = 0.0; + } + + fragColor = vec4(col,1.0); + +} diff --git a/tools/src/generative/Orb Symmetry.frag b/tools/src/generative/Orb Symmetry.frag new file mode 100644 index 0000000..d2ab313 --- /dev/null +++ b/tools/src/generative/Orb Symmetry.frag @@ -0,0 +1,77 @@ +// sleepy comments, most leftover from previous shader +// beware... i'll re-read tomorrow :D + + +#define T iTime + +// @FabriceNeyret2 golfed this in my "Light Hall" shader +// the idea is that you pass in the movement frequency (f) +// the z offset (Z) and the radius (c), you then just do +// a sphere calc on p: length(p - offset) - radius +// the offset vec is composed of all the trig stuff below +// but it's basically just move x and y in squiggly lines +// and move z relative to iTime and the z offset +// T*3. because the camera is moving at T*3. speed as well +#define O(f,Z,c) abs( length( /* orb */ \ +p - vec3( sin( sin(p.z*f*.5 ) +T*.7 ) * 3. , \ +sin( sin(p.z*f*1.3) +T*.5 ) * 2., \ +Z +8. +T*3. +cos(T*.3) *8. ) ) - c ) + +void mainImage(out vec4 o, vec2 u) { + + float l, // distance to light orb + s, // spiral distance + d, // total distance marched + + i, // raymarch iterator + n; // noise iterator + + // p is resolution, then raymarch position + vec3 p = iResolution; + + // scale coords + u = (u-p.xy/2.)/p.y; + + + // clear o, iterate 70 times, accumulate distance (d) and brightness (o) + // .001+abs(min(s,l)) means take the min of the spiral and the lights, + // and make it slightly translucent, *.7 to clean up some artifacts + for(o*=i; i++<60.;d += s = .001+abs(min(s,l))*.5, o += 1./s/l) + // this for-loop is the noise loop, before entering the loop body, + // we march. the below is equivalent to p = ro + rd * d, p.z += T; + // note that the orbs move at T*3. speed as well + for (p = vec3(u * d, d+T*3.), + + // mirror + p = abs(p), + + // it's just a mirrored plane with tanh wrapped around it to make it interesting + // why tanh? i was using cos for repetition and was curious, so i tried + // tanh, liked it, and kept it :) + s = tanh(4.-abs(p.x)), + + + // store dist to light in l + l = .01 + .8 * min( O(.5, 6., .4), + min( O(.4, 3., .2), + O(.3, 4., .3) )), + + + // start noise at 1, while < 6, n *= 1.3 + // n += n works, n *= 1.x works, but keep in mind the number of iterations + // the loop will need + n = 1.; n < 6.; n *= 1.3 ) + // apply the noise with a scale of .3 + // add .5*T to p to make it move, + // add p.z to make it less repetitive looking + s += abs(dot(cos(.5*T+p.z+p*n), vec3(.3))) / n; + + // tanh tonemap, vec4 divides color by d (green and blue) for depth, + // divide down brightness (o / 1e2), + // divide by distance for depth + // add a light in the center length(u), + o = tanh(2.*abs(vec4(.1,4./d, d/3e1,0)) * o/1e2/max(d,15.) / max(length(u), .001)); + + // @Shane color tip, mix o with swizzled components + o = mix(o.zyxw, o.yxzw, smoothstep(0., 1., length(u)*2.)); +} diff --git a/tools/src/generative/Phosphor.frag b/tools/src/generative/Phosphor.frag new file mode 100644 index 0000000..9d2bc93 --- /dev/null +++ b/tools/src/generative/Phosphor.frag @@ -0,0 +1,47 @@ +/* + "Phosphor 3" by @XorDev + + https://x.com/XorDev/status/1949897576435581439 + + <512 playlist: + https://www.shadertoy.com/playlist/N3SyzR +*/ + +void mainImage(out vec4 O, vec2 I) +{ + //Animation time + float t = iTime, + //Raymarch depth + z, + //Step distance + d, + //Signed distance + s, + //Raymarch iterator + i; + + + //Clear fragColor and raymarch 80 steps + for(O*=i; i++<8e1; + //Coloring and brightness + O+=(cos(s+vec4(0,1,8,0))+1.)/d) + { + //Sample point (from ray direction) + vec3 p = z*normalize(vec3(I+I,0)-iResolution.xyy), + //Rotation axis + a = normalize(cos(vec3(5,0,1)+t-d*4.)); + //Move camera back 5 units + p.z+=5., + //Rotated coordinates + a = a*dot(a,p)-cross(a,p); + + //Turbulence loop + for(d=1.;d++<9.;) + a-=sin(a*d+t).zxy/d; + + //Distance to ring + z+=d=.1*abs(length(p)-3.)+.07*abs(cos(s=a.y)); + } + //Tanh tonemap + O = tanh(O/5e3); +} \ No newline at end of file diff --git a/tools/src/generative/Self Reflection.frag b/tools/src/generative/Self Reflection.frag new file mode 100644 index 0000000..91c8de1 --- /dev/null +++ b/tools/src/generative/Self Reflection.frag @@ -0,0 +1,370 @@ +// https://www.shadertoy.com/view/XfyXRV + +// CC0: Let's self reflect +// Always enjoyed the videos of Platonic solids with inner mirrors +// I made some previous attempts but thought I make another attempt it + +// Reducing the alias effects on the inner reflections turned out to be a bit tricky. +// Simplest solution is just to run run fullscreen on a 4K screen ;) + +// Function to generate the solid found here: https://www.shadertoy.com/view/MsKGzw + +// Tinker with these parameters to create different solids +// ------------------------------------------------------- +const float rotation_speed= 0.25; + +const float poly_U = 1.; // [0, inf] +const float poly_V = 0.5; // [0, inf] +const float poly_W = 1.0; // [0, inf] +const int poly_type = 3; // [2, 5] +const float poly_zoom = 2.0; + +const float inner_sphere = 1.; + +const float refr_index = 0.9; + +#define MAX_BOUNCES2 6 +// ------------------------------------------------------- + + + +#define TIME iTime +#define RESOLUTION iResolution +#define PI 3.141592654 +#define TAU (2.0*PI) + +// License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488 +const vec4 hsv2rgb_K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); +vec3 hsv2rgb(vec3 c) { + vec3 p = abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www); + return c.z * mix(hsv2rgb_K.xxx, clamp(p - hsv2rgb_K.xxx, 0.0, 1.0), c.y); +} +// License: WTFPL, author: sam hocevar, found: https://stackoverflow.com/a/17897228/418488 +// Macro version of above to enable compile-time constants +#define HSV2RGB(c) (c.z * mix(hsv2rgb_K.xxx, clamp(abs(fract(c.xxx + hsv2rgb_K.xyz) * 6.0 - hsv2rgb_K.www) - hsv2rgb_K.xxx, 0.0, 1.0), c.y)) + +#define TOLERANCE2 0.0005 +//#define MAX_RAY_LENGTH2 10.0 +#define MAX_RAY_MARCHES2 50 +#define NORM_OFF2 0.005 +#define BACKSTEP2 + +#define TOLERANCE3 0.0005 +#define MAX_RAY_LENGTH3 10.0 +#define MAX_RAY_MARCHES3 90 +#define NORM_OFF3 0.005 + +const vec3 rayOrigin = vec3(0.0, 1., -5.); +const vec3 sunDir = normalize(-rayOrigin); + + +const vec3 sunCol = HSV2RGB(vec3(0.06 , 0.90, 1E-2))*1.; +const vec3 bottomBoxCol = HSV2RGB(vec3(0.66, 0.80, 0.5))*1.; +const vec3 topBoxCol = HSV2RGB(vec3(0.60, 0.90, 1.))*1.; +const vec3 glowCol0 = HSV2RGB(vec3(0.05 , 0.7, 1E-3))*1.; +const vec3 glowCol1 = HSV2RGB(vec3(0.95, 0.7, 1E-3))*1.; +const vec3 beerCol = -HSV2RGB(vec3(0.15+0.5, 0.7, 2.)); +const float rrefr_index = 1./refr_index; + + +// License: Unknown, author: knighty, found: https://www.shadertoy.com/view/MsKGzw +const float poly_cospin = cos(PI/float(poly_type)); +const float poly_scospin = sqrt(0.75-poly_cospin*poly_cospin); +const vec3 poly_nc = vec3(-0.5, -poly_cospin, poly_scospin); +const vec3 poly_pab = vec3(0., 0., 1.); +const vec3 poly_pbc_ = vec3(poly_scospin, 0., 0.5); +const vec3 poly_pca_ = vec3(0., poly_scospin, poly_cospin); +const vec3 poly_p = normalize((poly_U*poly_pab+poly_V*poly_pbc_+poly_W*poly_pca_)); +const vec3 poly_pbc = normalize(poly_pbc_); +const vec3 poly_pca = normalize(poly_pca_); + +mat3 g_rot; +vec2 g_gd; + +// License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/noacos/ +mat3 rot(vec3 d, vec3 z) { + vec3 v = cross( z, d ); + float c = dot( z, d ); + float k = 1.0/(1.0+c); + + return mat3( v.x*v.x*k + c, v.y*v.x*k - v.z, v.z*v.x*k + v.y, + v.x*v.y*k + v.z, v.y*v.y*k + c, v.z*v.y*k - v.x, + v.x*v.z*k - v.y, v.y*v.z*k + v.x, v.z*v.z*k + c ); +} + +// License: Unknown, author: Matt Taylor (https://github.com/64), found: https://64.github.io/tonemapping/ +vec3 aces_approx(vec3 v) { + v = max(v, 0.0); + v *= 0.6; + float a = 2.51; + float b = 0.03; + float c = 2.43; + float d = 0.59; + float e = 0.14; + return clamp((v*(a*v+b))/(v*(c*v+d)+e), 0.0, 1.0); +} + +float sphere(vec3 p, float r) { + return length(p) - r; +} + +// License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/distfunctions/ +float box(vec2 p, vec2 b) { + vec2 d = abs(p)-b; + return length(max(d,0.0)) + min(max(d.x,d.y),0.0); +} + +// License: Unknown, author: knighty, found: https://www.shadertoy.com/view/MsKGzw +void poly_fold(inout vec3 pos) { + vec3 p = pos; + + for(int i = 0; i < poly_type; ++i){ + p.xy = abs(p.xy); + p -= 2.*min(0., dot(p,poly_nc)) * poly_nc; + } + + pos = p; +} + +float poly_plane(vec3 pos) { + float d0 = dot(pos, poly_pab); + float d1 = dot(pos, poly_pbc); + float d2 = dot(pos, poly_pca); + float d = d0; + d = max(d, d1); + d = max(d, d2); + return d; +} + +float poly_corner(vec3 pos) { + float d = length(pos) - .0125; + return d; +} + +float dot2(vec3 p) { + return dot(p, p); +} + +float poly_edge(vec3 pos) { + float dla = dot2(pos-min(0., pos.x)*vec3(1., 0., 0.)); + float dlb = dot2(pos-min(0., pos.y)*vec3(0., 1., 0.)); + float dlc = dot2(pos-min(0., dot(pos, poly_nc))*poly_nc); + return sqrt(min(min(dla, dlb), dlc))-2E-3; +} + +vec3 shape(vec3 pos) { + pos *= g_rot; + pos /= poly_zoom; + poly_fold(pos); + pos -= poly_p; + + return vec3(poly_plane(pos), poly_edge(pos), poly_corner(pos))*poly_zoom; +} + +vec3 render0(vec3 ro, vec3 rd) { + vec3 col = vec3(0.0); + + float srd = sign(rd.y); + float tp = -(ro.y-6.)/abs(rd.y); + + if (srd < 0.) { + col += bottomBoxCol*exp(-0.5*(length((ro + tp*rd).xz))); + } + + if (srd > 0.0) { + vec3 pos = ro + tp*rd; + vec2 pp = pos.xz; + float db = box(pp, vec2(5.0, 9.0))-3.0; + + col += topBoxCol*rd.y*rd.y*smoothstep(0.25, 0.0, db); + col += 0.2*topBoxCol*exp(-0.5*max(db, 0.0)); + col += 0.05*sqrt(topBoxCol)*max(-db, 0.0); + } + + + col += sunCol/(1.001-dot(sunDir, rd)); + return col; +} + +float df2(vec3 p) { + vec3 ds = shape(p); + float d2 = ds.y-5E-3; + float d0 = min(-ds.x, d2); + float d1 = sphere(p, inner_sphere); + g_gd = min(g_gd, vec2(d2, d1)); + float d = (min(d0, d1)); + return d; +} + +float rayMarch2(vec3 ro, vec3 rd, float tinit) { + float t = tinit; +#if defined(BACKSTEP2) + vec2 dti = vec2(1e10,0.0); +#endif + int i; + for (i = 0; i < MAX_RAY_MARCHES2; ++i) { + float d = df2(ro + rd*t); +#if defined(BACKSTEP2) + if (d MAX_RAY_LENGTH3 */) { + break; + } + t += d; + } +#if defined(BACKSTEP2) + if(i==MAX_RAY_MARCHES2) { t=dti.y; }; +#endif + return t; +} + +vec3 normal2(vec3 pos) { + vec2 eps = vec2(NORM_OFF2,0.0); + vec3 nor; + nor.x = df2(pos+eps.xyy) - df2(pos-eps.xyy); + nor.y = df2(pos+eps.yxy) - df2(pos-eps.yxy); + nor.z = df2(pos+eps.yyx) - df2(pos-eps.yyx); + return normalize(nor); +} + +vec3 render2(vec3 ro, vec3 rd, float db) { + vec3 agg = vec3(0.0); + float ragg = 1.; + float tagg = 0.; + + for (int bounce = 0; bounce < MAX_BOUNCES2; ++bounce) { + if (ragg < 0.1) break; + g_gd = vec2(1E3); + float t2 = rayMarch2(ro, rd, min(db+0.05, 0.3)); + vec2 gd2 = g_gd; + tagg += t2; + + vec3 p2 = ro+rd*t2; + vec3 n2 = normal2(p2); + vec3 r2 = reflect(rd, n2); + vec3 rr2 = refract(rd, n2, rrefr_index); + float fre2= 1.+dot(n2,rd); + + vec3 beer = ragg*exp(0.2*beerCol*tagg); + agg += glowCol1*beer*((1.+tagg*tagg*4E-2)*6./max(gd2.x, 5E-4+tagg*tagg*2E-4/ragg)); + vec3 ocol = 0.2*beer*render0(p2, rr2); + if (gd2.y <= TOLERANCE2) { + ragg *= 1.-0.9*fre2; + } else { + agg += ocol; + ragg *= 0.8; + } + + ro = p2; + rd = r2; + db = gd2.x; + } + + + return agg; +} + +float df3(vec3 p) { + vec3 ds = shape(p); + g_gd = min(g_gd, ds.yz); + const float sw = 0.02; + float d1 = min(ds.y, ds.z)-sw; + float d0 = ds.x; + d0 = min(d0, ds.y); + d0 = min(d0, ds.z); + return d0; +} + +float rayMarch3(vec3 ro, vec3 rd, float tinit, out int iter) { + float t = tinit; + int i; + for (i = 0; i < MAX_RAY_MARCHES3; ++i) { + float d = df3(ro + rd*t); + if (d < TOLERANCE3 || t > MAX_RAY_LENGTH3) { + break; + } + t += d; + } + iter = i; + return t; +} + +vec3 normal3(vec3 pos) { + vec2 eps = vec2(NORM_OFF3,0.0); + vec3 nor; + nor.x = df3(pos+eps.xyy) - df3(pos-eps.xyy); + nor.y = df3(pos+eps.yxy) - df3(pos-eps.yxy); + nor.z = df3(pos+eps.yyx) - df3(pos-eps.yyx); + return normalize(nor); +} + +vec3 render3(vec3 ro, vec3 rd) { + int iter; + + vec3 skyCol = render0(ro, rd); + vec3 col = skyCol; + + g_gd = vec2(1E3); + float t1 = rayMarch3(ro, rd, 0.1, iter); + vec2 gd1 = g_gd; + vec3 p1 = ro+t1*rd; + vec3 n1 = normal3(p1); + vec3 r1 = reflect(rd, n1); + vec3 rr1 = refract(rd, n1, refr_index); + float fre1= 1.+dot(rd, n1); + fre1 *= fre1; + + float ifo = mix(0.5, 1., smoothstep(1.0, 0.9, float(iter)/float(MAX_RAY_MARCHES3))); + + if (t1 < MAX_RAY_LENGTH3) { + col = render0(p1, r1)*(0.5+0.5*fre1)*ifo; + vec3 icol = render2(p1, rr1, gd1.x); + if (gd1.x > TOLERANCE3 && gd1.y > TOLERANCE3 && rr1 != vec3(0.)) { + col += icol*(1.-0.75*fre1)*ifo; + } + } + + col += (glowCol0+1.*fre1*(glowCol0))/max(gd1.x, 3E-4); + return col; + +} + + +vec3 effect(vec2 p, vec2 pp) { + const float fov = 2.0; + + const vec3 up = vec3(0., 1., 0.); + const vec3 la = vec3(0.0); + + const vec3 ww = normalize(normalize(la-rayOrigin)); + const vec3 uu = normalize(cross(up, ww)); + const vec3 vv = cross(ww, uu); + + vec3 rd = normalize(-p.x*uu + p.y*vv + fov*ww); + + vec3 col = vec3(0.0); + col = render3(rayOrigin, rd); + + col -= 2E-2*vec3(2.,3.,1.)*(length(p)+0.25); + col = aces_approx(col); + col = sqrt(col); + return col; +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) { + vec2 q = fragCoord/RESOLUTION.xy; + vec2 p = -1. + 2. * q; + vec2 pp = p; + p.x *= RESOLUTION.x/RESOLUTION.y; + + float a = TIME*rotation_speed; + vec3 r0 = vec3(1.0, sin(vec2(sqrt(0.5), 1.0)*a)); + vec3 r1 = vec3(cos(vec2(sqrt(0.5), 1.0)*0.913*a), 1.0); + mat3 rot = rot(normalize(r0), normalize(r1)); + g_rot = rot; + + vec3 col = effect(p, pp); + + fragColor = vec4(col, 1.0); +} \ No newline at end of file diff --git a/tools/src/generative/Windows 10 Live.frag b/tools/src/generative/Windows 10 Live.frag new file mode 100644 index 0000000..e4c2795 --- /dev/null +++ b/tools/src/generative/Windows 10 Live.frag @@ -0,0 +1,137 @@ +// https://www.shadertoy.com/view/lllSR2 + +#define PI 3.1415926535897921284 +#define REP 25 +#define d2r(x) (x * PI / 180.0) +#define WBCOL (vec3(0.5, 0.7, 1.7)) +#define WBCOL2 (vec3(0.15, 0.8, 1.7)) +#define ZERO (min(iFrame,0)) + +float hash( vec2 p ) { + float h = dot( p, vec2( 127.1, 311.7 ) ); + return fract( sin( h ) * 458.325421) * 2.0 - 1.0; +} + +float noise( vec2 p ) { + vec2 i = floor( p ); + vec2 f = fract( p ); + + f = f * f * ( 3.0 - 2.0 * f ); + + return mix( + mix( hash( i + vec2( 0.0, 0.0 ) ), hash( i + vec2( 1.0, 0.0 ) ), f.x ), + mix( hash( i + vec2( 0.0, 1.0 ) ), hash( i + vec2( 1.0, 1.0 ) ), f.x ), + f.y + ); +} + +vec2 rot(vec2 p, float a) { + return vec2( + p.x * cos(a) - p.y * sin(a), + p.x * sin(a) + p.y * cos(a)); +} + +float nac(vec3 p, vec2 F, vec3 o) { + const float R = 0.0001; + p += o; + return length(max(abs(p.xy)-vec2(F),0.0)) - R; +} + + +float by(vec3 p, float F, vec3 o) { + const float R = 0.0001; + p += o; + return length(max(abs(mod(p.xy, 3.0))-F,0.0)) - R; +} + + +float recta(vec3 p, vec3 F, vec3 o) { + const float R = 0.0001; + p += o; + return length(max(abs(p)-F,0.0)) - R; +} + + +float map1(vec3 p, float scale) { + float G = 0.50; + float F = 0.50 * scale; + float t = nac(p, vec2(F,F), vec3( G, G, 0.0)); + t = min(t, nac(p, vec2(F,F), vec3( G, -G, 0.0))); + t = min(t, nac(p, vec2(F,F), vec3(-G, G, 0.0))); + t = min(t, nac(p, vec2(F,F), vec3(-G, -G, 0.0))); + return t; +} + +float map2(vec3 p) { + float t = map1(p, 0.9); + //t = max(t, recta(p, vec3(1.0, 1.0, 0.02), vec3(0.0, 0.0, 0.0))); + t = max(t, recta(p, vec3(1.0, 1.0, 0.02), vec3(0.0, 0.0, 0.0))); + return t; +} + + +// http://glslsandbox.com/e#26840.0 +float gennoise(vec2 p) { + float d = 0.5; + mat2 h = mat2( 1.6, 1.2, -1.2, 1.6 ); + + float color = 0.0; + for( int i = 0; i < 2; i++ ) { + color += d * noise( p * 5.0 + iTime); + p *= h; + d /= 2.0; + } + return color; +} + + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) { + fragColor = vec4(0.0); + for(int count = 0 ; count < 2; count++) { + vec2 uv = -1.0 + 2.0 * ( fragCoord.xy / iResolution.xy ); + uv *= 1.4; + uv.x += hash(uv.xy + iTime + float(count)) / 512.0; + uv.y += hash(uv.yx + iTime + float(count)) / 512.0; + vec3 dir = normalize(vec3(uv * vec2(iResolution.x / iResolution.y, 1.0), 1.0 + sin(iTime) * 0.01)); + dir.xz = rot(dir.xz, d2r(70.0)); + dir.xy = rot(dir.xy, d2r(90.0)); + vec3 pos = vec3(-0.1 + sin(iTime * 0.3) * 0.1, 2.0 + cos(iTime * 0.4) * 0.1, -3.5); + vec3 col = vec3(0.0); + float t = 0.0; + float M = 1.002; + float bsh = 0.01; + float dens = 0.0; + + for(int i = ZERO ; i < REP * 24; i++) { + float temp = map1(pos + dir * t, 0.6); + if(temp < 0.2) { + col += WBCOL * 0.005 * dens; + } + t += bsh * M; + bsh *= M; + dens += 0.025; + } + + //windows + t = 0.0; + float y = 0.0; + //for(int i = 0 ; i < REP * 50; i++) + for(int i = ZERO ; i < REP; i++) + { + float temp = map2(pos + dir * t); + if(temp < 0.025) { + //col += WBCOL2 * 0.005; + col += WBCOL2 * 0.5; + } + t += temp; + y++; + } + col += ((2.0 + uv.x) * WBCOL2) + (y / (25.0 * 50.0)); + col += gennoise(dir.xz) * 0.5; + col *= 1.0 - uv.y * 0.5; + col *= vec3(0.05); + col = pow(col, vec3(0.717)); + fragColor += vec4(col, 1.0 / (t)); + } + fragColor /= vec4(2.0); +} \ No newline at end of file diff --git a/tools/src/generative/sdEquilateral.frag b/tools/src/generative/sdEquilateral.frag new file mode 100644 index 0000000..5c68c55 --- /dev/null +++ b/tools/src/generative/sdEquilateral.frag @@ -0,0 +1,45 @@ +vec3 palette( float t ) { + vec3 a = vec3(0.2, 0.2, 0.5); // blue has a greater default + vec3 b = vec3(0.5, 0.5, 0.5); // all channels contribute + vec3 c = vec3(0.1, 0.1, 0.4); // dampen blue oscillations + vec3 d = vec3(0.0,0.33,0.67); // phase shifting by 0.33 + + return a + b*cos( 6.28318*(c*t+d) ); +} + +float sdEquilateralTriangle( in vec2 p, in float r ) +{ + const float k = sqrt(3.0); + p.x = abs(p.x) - r; + p.y = p.y + r/k; + if( p.x+k*p.y>0.0 ) p = vec2(p.x-k*p.y,-k*p.x-p.y)/2.0; + p.x -= clamp( p.x, -2.0*r, 0.0 ); + return -length(p)*sign(p.y); +} +float norm( in vec2 p ) +{ + return sdEquilateralTriangle(p*1.5, 0.1); +} + +void mainImage( out vec4 fragColour, in vec2 fragCoord ) { + vec2 uv = (fragCoord *2.0 - iResolution.xy) / iResolution.y; + uv = floor(uv*100.0f)/100.0f; + vec2 uv0 = uv; + vec3 finalColour = vec3(0.0); + + for (float i = 0.0; i < 4.0; i++) { + uv = fract(uv * 1.5) - 0.5; + + float d = norm(uv) * exp(-norm(uv0)); + + vec3 col = palette(norm(uv0) + i*.4 + iTime*.4); + + d = sin(d*8. + iTime)/8.; + d = abs(d); + d = pow(0.009 / d, 1.6); + + finalColour += col * d; + } + + fragColour = vec4(finalColour, 1.0); +} diff --git a/tools/src/manipulative/Circle Dither (Color).frag b/tools/src/manipulative/Circle Dither (Color).frag new file mode 100644 index 0000000..383bbee --- /dev/null +++ b/tools/src/manipulative/Circle Dither (Color).frag @@ -0,0 +1,49 @@ +//const float gridSize = iResolution.x*0.1; + +bool circleTest(vec2 pos, vec2 size, vec2 uv){ + if(distance(pos,uv) < size.x){ + return true; + } else { + return false; + } +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + // Normalized pixel coordinates (from 0 to 1) + vec2 uv = fragCoord/iResolution.y; + + float gridSize = iResolution.x*0.05; + + uv = fract(uv*gridSize); + + vec4 cam = texture(iChannel0, floor((fragCoord/iResolution.xy)*gridSize)*(1.0/gridSize)); + + vec3 col = vec3(0.0); + + bool circleR = circleTest(vec2(0.7,0.7),vec2(cam.x*0.5), uv); + bool circleG = circleTest(vec2(0.3,0.5),vec2(cam.y*0.5), uv); + bool circleB = circleTest(vec2(0.7,0.3),vec2(cam.z*0.5), uv); + + // Output to screen + if(circleR){ + col.x = 1.0; + } else { + col.x = 0.0; + } + + if(circleG){ + col.y = 1.0; + } else { + col.y = 0.0; + } + + if(circleB){ + col.z = 1.0; + } else { + col.z = 0.0; + } + + fragColor = vec4(col,1.0); + +} diff --git a/tools/src/manipulative/Modulo Dither.frag b/tools/src/manipulative/Modulo Dither.frag new file mode 100644 index 0000000..667d009 --- /dev/null +++ b/tools/src/manipulative/Modulo Dither.frag @@ -0,0 +1,47 @@ +// https://www.shadertoy.com/view/lcl3Rs + +// This function returns an integer to use as the modulus value for a given pixel. +// The brighter this pixel, the smaller this integer is, relative to the width of the image (so that a black pixel returns +// the image width as an integer) +int ditherModFactor(float val, vec2 imgSize){ + return int(floor((1.0-pow(val,0.01)) * imgSize.x)); + //The pow here applies an aggressive log curve to the greyscale colour of the image. This is needed due to + // multiplying the 0-1 greyscale value by such a large number (screen width in pixels). An exponent of 0.01 happens to work + // very well here, but playing around with the exponent can be interesting. +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + //Normalized pixel coordinates (from 0 to 1) + vec2 uv = fragCoord/iResolution.xy; + + //Load a pixel from the image and write it to a variable + vec4 pix = texture(iChannel0,uv); + + //If the green channel of this pixel is more than a small value, and the red and blue are less than a threshold, make this + // pixel black. + if(pix.y > 0.01 && pix.x < 0.2 && pix.z < 0.2){pix = vec4(0.0,0.0,0.0,1.0);} //uncomment to chroma key (for black background) + + //Store a float of the average value of all three colour channels of this pixel + float pixVal = (pix.x+pix.y+pix.z)/3.0; + + //Work out what number/index pixel this is in the image. It is also interesting to use the x or y coordinate of the current + // pixel (not normalised) in place of i (**try replacing i on line 39 with fragCoord.x or fragCoord.y!**). + float i = uv.x + (uv.y * iResolution.y); + + //Get the modulo value for this pixel + int shadeMod = ditherModFactor(pixVal, iResolution.xy); + + //Compare the modulo value for this pixel with it's number/index - if the pixel index is a multiple of the modulo, + // output a white pixel - if not, black. This means that brighter pixels in the original image both have more white + // neighbours and are more likely to be white themselves, based on where they fall in the image. This is why it's important + // to scale the modulo to the image width so that no repeating patterns of white appear in parts of the image that should be + // black. When this is done, the only black/dark pixels in the original image that will return white in the modulo check are + // the pixels that have the "address" (index or x or y coord) equal to the max value in range of values that address can be. + if(int(i) % shadeMod == 0){ + fragColor = vec4(1.0); + } else { + fragColor = vec4(0.0,0.0,0.0,1.0); + } + //if((1.0-uv.x) < uv.y){fragColor = vec4(pixVal,pixVal,pixVal,1.0);} //uncommenting shows undithered b&w image on half of screen +} \ No newline at end of file diff --git a/tools/src/manipulative/VHS Tape Noise 2.frag b/tools/src/manipulative/VHS Tape Noise 2.frag new file mode 100644 index 0000000..c414c4d --- /dev/null +++ b/tools/src/manipulative/VHS Tape Noise 2.frag @@ -0,0 +1,121 @@ +// https://www.shadertoy.com/view/wldBzS + +// change these values to 0.0 to turn off individual effects +float vertJerkOpt = 0.0; +float vertMovementOpt = 0.0; +float bottomStaticOpt = 1.0; +float scalinesOpt = 1.0; +float rgbOffsetOpt = 1.0; +float horzFuzzOpt = 1.0; + +// Noise generation functions borrowed from: +// https://github.com/ashima/webgl-noise/blob/master/src/noise2D.glsl + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec2 mod289(vec2 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec3 permute(vec3 x) { + return mod289(((x*34.0)+1.0)*x); +} + +float snoise(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 staticV(vec2 uv) { + float staticHeight = snoise(vec2(9.0,iTime*1.2+3.0))*0.3+5.0; + float staticAmount = snoise(vec2(1.0,iTime*1.2-6.0))*0.1+0.3; + float staticStrength = snoise(vec2(-9.75,iTime*0.6-3.0))*2.0+2.0; + return (1.0-step(snoise(vec2(5.0*pow(iTime,2.0)+pow(uv.x*7.0,1.2),pow((mod(iTime,100.0)+100.0)*uv.y*0.3+3.0,staticHeight))),staticAmount))*staticStrength; +} + + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + + vec2 uv = fragCoord.xy/iResolution.xy; + + float jerkOffset = (1.0-step(snoise(vec2(iTime*1.3,5.0)),0.8))*0.05; + + float fuzzOffset = snoise(vec2(iTime*15.0,uv.y*80.0))*0.003; + float largeFuzzOffset = snoise(vec2(iTime*1.0,uv.y*25.0))*0.004; + + float vertMovementOn = (1.0-step(snoise(vec2(iTime*0.2,8.0)),0.4))*vertMovementOpt; + float vertJerk = (1.0-step(snoise(vec2(iTime*1.5,5.0)),0.6))*vertJerkOpt; + float vertJerk2 = (1.0-step(snoise(vec2(iTime*5.5,5.0)),0.2))*vertJerkOpt; + float yOffset = abs(sin(iTime)*4.0)*vertMovementOn+vertJerk*vertJerk2*0.3; + float y = mod(uv.y+yOffset,1.0); + + + float xOffset = (fuzzOffset + largeFuzzOffset) * horzFuzzOpt; + + float staticVal = 0.0; + + for (float y = -1.0; y <= 1.0; y += 1.0) { + float maxDist = 5.0/200.0; + float dist = y/200.0; + staticVal += staticV(vec2(uv.x,uv.y+dist))*(maxDist-abs(dist))*1.5; + } + + staticVal *= bottomStaticOpt; + + float red = texture( iChannel0, vec2(uv.x + xOffset -0.01*rgbOffsetOpt,y)).r+staticVal; + float green = texture( iChannel0, vec2(uv.x + xOffset, y)).g+staticVal; + float blue = texture( iChannel0, vec2(uv.x + xOffset +0.01*rgbOffsetOpt,y)).b+staticVal; + + vec3 color = vec3(red,green,blue); + float scanline = sin(uv.y*800.0)*0.04*scalinesOpt; + color -= scanline; + + fragColor = vec4(color,1.0); +} \ No newline at end of file diff --git a/tools/src/manipulative/VHS Tape Noise.frag b/tools/src/manipulative/VHS Tape Noise.frag new file mode 100644 index 0000000..603a25c --- /dev/null +++ b/tools/src/manipulative/VHS Tape Noise.frag @@ -0,0 +1,66 @@ +//by Vladimir Storm +//https://twitter.com/vladstorm_ + +#define t iTime + +//random hash +vec4 hash42(vec2 p){ + + vec4 p4 = fract(vec4(p.xyxy) * vec4(443.8975,397.2973, 491.1871, 470.7827)); + p4 += dot(p4.wzxy, p4+19.19); + return fract(vec4(p4.x * p4.y, p4.x*p4.z, p4.y*p4.w, p4.x*p4.w)); +} + + +float hash( float n ){ + return fract(sin(n)*43758.5453123); +} + +// 3d noise function (iq's) +float n( in vec3 x ){ + vec3 p = floor(x); + vec3 f = fract(x); + f = f*f*(3.0-2.0*f); + float n = p.x + p.y*57.0 + 113.0*p.z; + float res = mix(mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x), + mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y), + mix(mix( hash(n+113.0), hash(n+114.0),f.x), + mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z); + return res; +} + +//tape noise +float nn(vec2 p){ + + + float y = p.y; + float s = t*2.; + + float v = (n( vec3(y*.01 +s, 1., 1.0) ) + .0) + *(n( vec3(y*.011+1000.0+s, 1., 1.0) ) + .0) + *(n( vec3(y*.51+421.0+s, 1., 1.0) ) + .0) + ; + //v*= n( vec3( (fragCoord.xy + vec2(s,0.))*100.,1.0) ); + v*= hash42( vec2(p.x +t*0.01, p.y) ).x +.3 ; + + + v = pow(v+.3, 1.); + if(v<.7) v = 0.; //threshold + return v; +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ){ + + vec2 uv = fragCoord.xy / iResolution.xy; + + + float linesN = 240.; //fields per seconds + float one_y = iResolution.y / linesN; //field line + uv = floor(uv*iResolution.xy/one_y)*one_y; + + float col = nn(uv); + + + + fragColor = vec4(vec3( col ),1.0); +} \ No newline at end of file diff --git a/tools/src/manipulative/Video Glitch.frag b/tools/src/manipulative/Video Glitch.frag new file mode 100644 index 0000000..d93ce05 --- /dev/null +++ b/tools/src/manipulative/Video Glitch.frag @@ -0,0 +1,106 @@ +// +// Description : Array and textureless GLSL 2D simplex noise function. +// Author : Ian McEwan, Ashima Arts. +// Maintainer : stegu +// Lastmod : 20110822 (ijm) +// License : Copyright (C) 2011 Ashima Arts. All rights reserved. +// Distributed under the MIT License. See LICENSE file. +// https://github.com/ashima/webgl-noise +// https://github.com/stegu/webgl-noise +// + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec2 mod289(vec2 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec3 permute(vec3 x) { + return mod289(((x*34.0)+1.0)*x); +} + +float snoise(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 rand(vec2 co) +{ + return fract(sin(dot(co.xy,vec2(12.9898,78.233))) * 43758.5453); +} + + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 uv = fragCoord.xy / iResolution.xy; + float time = iTime * 2.0; + + // Create large, incidental noise waves + float noise = max(0.0, snoise(vec2(time, uv.y * 0.3)) - 0.3) * (1.0 / 0.7); + + // Offset by smaller, constant noise waves + noise = noise + (snoise(vec2(time*10.0, uv.y * 2.4)) - 0.5) * 0.15; + + // Apply the noise as x displacement for every line + float xpos = uv.x - noise * noise * 0.25; + fragColor = texture(iChannel0, vec2(xpos, uv.y)); + + // Mix in some random interference for lines + fragColor.rgb = mix(fragColor.rgb, vec3(rand(vec2(uv.y * time))), noise * 0.3).rgb; + + // Apply a line pattern every 4 pixels + if (floor(mod(fragCoord.y * 0.25, 2.0)) == 0.0) + { + fragColor.rgb *= 1.0 - (0.15 * noise); + } + + // Shift green/blue channels (using the red channel) + fragColor.g = mix(fragColor.r, texture(iChannel0, vec2(xpos + noise * 0.05, uv.y)).g, 0.25); + fragColor.b = mix(fragColor.r, texture(iChannel0, vec2(xpos - noise * 0.05, uv.y)).b, 0.25); +} \ No newline at end of file diff --git a/tools/src/reactive/AudioTest.frag b/tools/src/reactive/AudioTest.frag new file mode 100644 index 0000000..65e857e --- /dev/null +++ b/tools/src/reactive/AudioTest.frag @@ -0,0 +1,40 @@ +// Created by inigo quilez - iq/2013 +// https://www.youtube.com/c/InigoQuilez +// https://iquilezles.org/ + + +// See also: +// +// Input - Keyboard : https://www.shadertoy.com/view/lsXGzf +// Input - Microphone : https://www.shadertoy.com/view/llSGDh +// Input - Mouse : https://www.shadertoy.com/view/Mss3zH +// Input - Sound : https://www.shadertoy.com/view/Xds3Rr +// Input - SoundCloud : https://www.shadertoy.com/view/MsdGzn +// Input - Time : https://www.shadertoy.com/view/lsXGz8 +// Input - TimeDelta : https://www.shadertoy.com/view/lsKGWV +// Inout - 3D Texture : https://www.shadertoy.com/view/4llcR4 + + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + // create pixel coordinates + vec2 uv = fragCoord.xy / iResolution.xy; + + // the sound texture is 512x2 + int tx = int(uv.x*512.0); + + // first row is frequency data (48Khz/4 in 512 texels, meaning 23 Hz per texel) + float fft = texelFetch( iChannel0, ivec2(tx,0), 0 ).x; + + // second row is the sound wave, one texel is one mono sample + float wave = texelFetch( iChannel0, ivec2(tx,1), 0 ).x; + + // convert frequency to colors + vec3 col = vec3( fft, 4.0*fft*(1.0-fft), 1.0-fft ) * fft; + + // add wave form on top + col += 1.0 - smoothstep( 0.0, 0.15, abs(wave - uv.y) ); + + // output final color + fragColor = vec4(col,1.0); +} \ No newline at end of file diff --git a/tools/src/reactive/AudioTest2.frag b/tools/src/reactive/AudioTest2.frag new file mode 100644 index 0000000..c948471 --- /dev/null +++ b/tools/src/reactive/AudioTest2.frag @@ -0,0 +1,37 @@ +/* +2D LED Spectrum - Visualiser +Based on Led Spectrum Analyser by: simesgreen - 27th February, 2013 https://www.shadertoy.com/view/Msl3zr +2D LED Spectrum by: uNiversal - 27th May, 2015 +Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. +*/ + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + // create pixel coordinates + vec2 uv = fragCoord.xy / iResolution.xy; + + // quantize coordinates + const float bands = 30.0; + const float segs = 40.0; + vec2 p; + p.x = floor(uv.x*bands)/bands; + p.y = floor(uv.y*segs)/segs; + + // read frequency data from first row of texture + float fft = texture( iChannel0, vec2(p.x,0.0) ).x; + + // led color + vec3 color = mix(vec3(0.0, 2.0, 0.0), vec3(2.0, 0.0, 0.0), sqrt(uv.y)); + + // mask for bar graph + float mask = (p.y < fft) ? 1.0 : 0.1; + + // led shape + vec2 d = fract((uv - p) *vec2(bands, segs)) - 0.5; + float led = smoothstep(0.5, 0.35, abs(d.x)) * + smoothstep(0.5, 0.35, abs(d.y)); + vec3 ledColor = led*color*mask; + + // output final color + fragColor = vec4(ledColor, 1.0); +} \ No newline at end of file diff --git a/tools/src/reactive/Basic Audio Visualizer.frag b/tools/src/reactive/Basic Audio Visualizer.frag new file mode 100644 index 0000000..19e3911 --- /dev/null +++ b/tools/src/reactive/Basic Audio Visualizer.frag @@ -0,0 +1,70 @@ +/* Simple audio visualizer by chronos +// Feel free to use any part of the code and/or improve it further +// Drop a link in the comments! :) +// +// Recommended tracks: +// https://soundcloud.com/kubbi/pathfinder +// https://soundcloud.com/wearecastor/rad +// https://soundcloud.com/jco-de/coronoid-soundtrack +// +*/ + +#define WIDTH 1.0 + +float audio_freq( in sampler2D channel, in float f) { return texture( channel, vec2(f, 0.25) ).x; } +float audio_ampl( in sampler2D channel, in float t) { return texture( channel, vec2(t, 0.75) ).x; } + +vec3 B2_spline(vec3 x) { // returns 3 B-spline functions of degree 2 + vec3 t = 3.0 * x; + vec3 b0 = step(0.0, t) * step(0.0, 1.0-t); + vec3 b1 = step(0.0, t-1.0) * step(0.0, 2.0-t); + vec3 b2 = step(0.0, t-2.0) * step(0.0, 3.0-t); + return 0.5 * ( + b0 * pow(t, vec3(2.0)) + + b1 * (-2.0*pow(t, vec3(2.0)) + 6.0*t - 3.0) + + b2 * pow(3.0-t,vec3(2.0)) + ); +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) { + vec2 uv = fragCoord.xy / iResolution.xy; + vec2 centered = 2.0 * uv - 1.0; + centered.x *= iResolution.x / iResolution.y; + + float dist2 = dot(centered, centered); + float clamped_dist = smoothstep(0.0, 1.0, dist2); + float arclength = abs(atan(centered.y, centered.x) / radians(360.0))+0.01; + + // Color variation functions + float t = iTime / 100.0; + float polychrome = (1.0 + sin(t*10.0))/2.0; // 0 -> uniform color, 1 -> full spectrum + vec3 spline_args = fract(vec3(polychrome*uv.x-t) + vec3(0.0, -1.0/3.0, -2.0/3.0)); + vec3 spline = B2_spline(spline_args); + + float f = abs(centered.y); + vec3 base_color = vec3(1.0, 1.0, 1.0) - f*spline; + vec3 flame_color = pow(base_color, vec3(3.0)); + vec3 disc_color = 0.20 * base_color; + vec3 wave_color = 0.10 * base_color; + vec3 flash_color = 0.05 * base_color; + + float sample1 = audio_freq(iChannel3, abs((uv.x - .5) / WIDTH) + 0.01); + float sample2 = audio_ampl(iChannel3, clamped_dist); + float sample3 = audio_ampl(iChannel3, arclength); + + float disp_dist = smoothstep(-0.2, -0.1, sample3-dist2); + disp_dist *= (1.0 - disp_dist); + + vec3 color = vec3(0.0); + + // spline debug + // vec3 s = smoothstep(-0.01, 0.01, spline-uv.y); color += (1.0-s) * s; + + float v = abs(uv.y - 0.5); + color += flame_color * smoothstep(v, v*8.0, sample1); + color += disc_color * smoothstep(0.5, 1.0, sample2) * (1.0 - clamped_dist); + color += flash_color * smoothstep(0.5, 1.0, sample3) * clamped_dist; + color += wave_color * disp_dist; + color = pow(color, vec3(0.4545)); + fragColor = vec4(color, 1.0); +} \ No newline at end of file