The Code Therapy

Fuzzy Disco Thingie

A doodle based on the pseudo-randomness of displaced FBM patterns and a really dirty mess with the colors that ended up looking like a weird fuzzy disco thingie.

Created by marcogomez on Thu, 29 Oct 2020 23:59:35 GMT.


// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;

uniform sampler2D prgm2Texture;
uniform vec2 resolution;

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  vec4 prgm2 = texture2D(prgm2Texture, uv);
  vec3 color = prgm2.xyz * prgm2.xyz;
  gl_FragColor = vec4(color, 1.0);
}

// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;

uniform vec2 resolution;
uniform float time;
uniform float fft;

const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const float SQRT3 = sqrt(3.0);
const float TAN30 = SQRT3 / 3.0;
const float HALFPI = PI / 2.0;
const float TTP = 1.0 / 3.0;
const float SSP = 1.0 / 1.5;
const float STH = 1.0 / 6.0;
const float T1R = 120.0;
const float T2R = T1R * 3.0;

float rand(vec2 uv) {
  float d = dot(uv.xy, vec2(12.9898, 78.233));
  return fract(sin(d) * 43758.545312);
}

float dfNoise21(vec2 uv) {
  vec3 p = fract(vec3(uv.xyx) * 0.1031);
  p += dot(p, p.yzx + 33.33);
  return fract((p.x + p.y) * p.z);
}

float fbm(vec2 uv) {
  float z = 2.0;
  float c = 0.0;
  vec2 u = uv;
  for(float e = 1.0; e < 6.0; e++) {
    c += abs(
      ((mix(dfNoise21(u), rand(u), 0.5) - 0.5) * 2.0)
    ) / z;
    z=z*2.,uv=uv*2.;
  }
  return c;
}

mat2 rotate(float x) {
  float c = cos(x);
  float s = sin(x);
  return mat2( c, -s, s, c);
}

float dualFBM(vec2 a) {
  vec2 c=a*.7;
  vec2 b=vec2(fbm(c*1.65),fbm(c*1.7));b=(b-.5)*.2,a+=b;
  return fbm(a*rotate(.2));
}

vec2 curve(vec2 uv) {
  uv.x *= 1.0 + pow(abs(uv.y / 5.0), 2.0);
  uv.y *= 1.0 + pow(abs(uv.x / 4.0), 2.0);
  uv = uv * 0.92 + 0.04;
  return uv;
}

float ssin(float t) {
  return (2.0 / PI) * atan(sin(TAU * t * 0.5) / 0.1) * 2.0;
}

float nzClamp(float x) {
  return clamp(x, 0.1, 1.0);
}

vec3 nzClamp(vec3 x) {
  return clamp(x, 0.1, 1.0);
}

vec3 hsv2rgb(vec3 c) {
  c.yz = clamp(c.yz, 0.0, 1.0);
  vec3 t = vec3(0.0, SSP, TTP);
  vec3 ct = cos(PI * (c.x + t)) - 1.0;
  return c.z * (1.0 + 0.5 * c.y * ct);
}

vec3 hueRotate(vec3 c, float a) {
  vec2 zhPI = vec2(0.0, HALFPI);
  vec2 s = sin(vec2(radians(a)) + zhPI);
  vec3 rot = vec3(TAN30, s);
  vec3 cc = cross(rot.xxx, c);
  float dc = dot(rot.xxx, c);
  return mix(rot.xxx * dc, c, rot.z) + cc * rot.y;
}

void main(void) {
  vec2 uv = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;
  float ar = resolution.x / resolution.y;
  uv.x *= ar;
  vec2 c = curve(gl_FragCoord.xy / resolution.xy);
  float t1 = mod(time * 6.0, T1R);
  float t2 = mod(time * 0.3, T2R);
  float ot1 = nzClamp(ssin(t2 * STH) + 1.0);
  float ot2 = nzClamp(ssin(t2 * TTP) + 1.0);
  float T = 2.0 - mix(mix(1.0, 0.125, ot2), mix(0.5, 0.25, ot2), ot1) * 0.5;
  uv *= 1.0 - 0.2 * cos(uv.yx) * sin(PI / 10.0);
  uv *= 9.0 * T;
  uv.x += sin(0.125 * uv.y + time) * 0.1;
  uv.y += cos(0.125 * uv.x + time) * 0.1;
  float f = fft * 0.5;
  f *= f;
  float fbmA = dualFBM(floor(uv)) + f;
  float fbmB = dualFBM(floor(uv * 0.5)) + f;
  float fbmC = dualFBM(floor(uv * 0.25)) + f;
  float fbmD = dualFBM(floor(uv * 0.125))+f;
  float rnd = nzClamp(mix(mix(fbmA, fbmD, ot2), mix(fbmB, fbmC, ot2), ot1));
  vec2 black = clamp(smoothstep(2.5, 0.0, cos(uv * TAU)), 0.1, 0.9);
  vec3 colA = clamp(
    hsv2rgb(vec3(8.0 * cos(rnd), 1.5 / rnd, 5.0 * pow(abs(rnd), rnd))), 0.5, 0.9
  );
  vec3 colB = clamp(
    hsv2rgb(vec3(7.0 * cos(fbmA), 1.5 / fbmA, 5.0 * pow(abs(fbmA), abs(fbmA)))), 0.2, 0.9
  );
  float p = nzClamp(black.x * black.y * smoothstep(0.9, 0.2, length(fract(uv) - 0.5)));
  float u = nzClamp(0.5 + 0.5 * cos(rnd * t1 + TAU));
  colA *= p; colB *= p; colA *= u; colB *= u;
  vec3 cA = colA;
  vec3 v = sqrt(colA * colA * colB);
  vec3 w = sqrt(colA * colA / colB);
  cA = clamp(cA * 2.0, 0.1, 0.9);
  vec3 cB = nzClamp(sqrt(mix(mix(cA, colB, ot2),mix(v, w, ot2), ot1) / w * v));
  cB = hueRotate(cB, 210.);
  cB *= (0.99 + 0.01 * sin(110.0 * t1)) * 5.0;
  float vig = 16.0 * c.x * c.y * (1.0 - c.x) * (1.0 - c.y);
  cB *= vec3(pow(abs(vig), 0.5));
  if (c.x < 0.0 || c.x > 1.0) { cB *= 0.0; }
  if (c.y < 0.0 || c.y > 1.0) { cB *= 0.0; }
  vec4 color = vec4(cB * 2.0, colA.x * colB.x * cA.x + p * cA.x + p * 0.95);
  color.xyz *= cA.x * 0.25; //(1.0 - vec3(cA.x));
  gl_FragColor=clamp(color * fbmA * 2.0, 0.0, 1.0);
}

// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;

uniform sampler2D prgm1Texture;
uniform vec2 resolution;
uniform vec2 mouselerp;
uniform float time;
uniform float fft;

const float PI = acos(-1.0);
const float TAU = PI * 2.0;

const int NUM_SAMPLES = 32;
const float Density = 0.5;
const float Exposure = 0.3;
float Weight = 1.0 + fft * 0.5;

float rand(vec2 uv, float t) {
  float seed = dot(uv, vec2(12.9898, 78.233));
  return fract(sin(seed) * 43758.5453123 + t);
}

float gaussian(float z, float u, float o) {
  return (
    (1.0 / (o * sqrt(TAU))) *
    (exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))
  );
}

vec3 gaussgrain(float t) {
  vec2 ps = vec2(1.0) / resolution.xy;
  vec2 uv = gl_FragCoord.xy * ps;
  float noise = rand(uv, t);
  noise = gaussian(noise, 0.0, 0.5);
  return vec3(noise);
}

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  uv.x += sin(0.0625 * uv.y + time) * 0.025;
  uv.y += cos(0.0625 * uv.x + time) * 0.025;
  vec2 dist = uv - 0.5;
  dist.x += sin(0.125 * dist.y + time) * 0.1;
  dist.y += cos(0.125 * dist.x + time) * 0.1;
  float Density = 0.75 + 0.2 * sin(2.0 * radians(360.0));
  dist *= 1.0 / float(NUM_SAMPLES) * Density;
  float frameScale = 29.97;
  float frameTime = floor(time * frameScale) / frameScale;
  vec3 g = gaussgrain(frameTime) * 0.3;
  vec3 color = texture2D(prgm1Texture, uv).rgb;
  vec3 cc = color;
  float illuminationDecay = 1.0;
  for (int i = 0; i < NUM_SAMPLES; i++)   {
    uv -= dist;
    vec3 sample_ = texture2D(prgm1Texture, uv + dist * rand(uv, time)).rgb + g;
    sample_ *= illuminationDecay * Weight;
    color += sample_;
    float Decay = 0.6 + fft * 0.4;
    illuminationDecay *= Decay;
  }
  gl_FragColor = vec4(mix(color * color * Exposure, cc, 0.5), 1.0);
}