A Tribute to Phenomena +Bloom

A tribute to the unforgettable 90s aesthetics and to the pioneer giants whose shoulders we stand on, this time with some bloom post-processing.

Created by marcogomez on Wed, 03 Nov 2021 02:32:48 GMT.


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

uniform sampler2D prgm6Texture;
uniform vec2 resolution;
uniform float time;

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

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 seed = dot(uv, vec2(12.9898, 78.233));
  float noise = fract(sin(seed) * 43758.5453123 + t);
  noise = gaussian(noise, 0.0, 0.5);
  return vec3(noise);
}

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  vec4 tex = texture2D(prgm6Texture, uv);
  float frameScale = 29.97;
  float frameTime = floor(time * frameScale) / frameScale;
  vec3 grain = gaussgrain(frameTime * 1.0);
  vec3 grainB = gaussgrain(frameTime * 1.3);
  tex.rgb += grain * grainB * 0.05;
  gl_FragColor = tex;
}

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

uniform vec2 resolution;
uniform float time;

#define t time * 0.7
const int starsPerPlane = 30;
const int planes = 4;
const float barSize = 0.12;
const float barsAng = 1.4;
vec2 barPos;
vec3 barCol;
vec3 cp;

float rand (vec2 uv) {
  return fract(sin(dot(uv, vec2(12.4124, 48.4124))) * 48512.41241);
}

float noise (vec2 uv) {
  vec2 b = floor(uv);
  return mix(
    mix(rand(b), rand(b + vec2(1.0, 0.0)), 0.5),
    mix(rand(b + vec2(0.0, 1.0)), rand(b + vec2(1.0, 1.0)), 0.5),
    0.5
  );
}

vec3 mixCol(float val, float r, float g, float b) {
  return vec3(val * r, val * g, val * b);
}

void bar(float pos, float r, float g, float b) {
  if (
    (barPos.y <= pos + barSize) &&
    (barPos.y >= pos - barSize)
  ) {
    barCol = mixCol(1.0 - abs(pos - barPos.y) / barSize, r, g, b);
  }
}

vec3 twist(vec3 p) {
  float f = (sin(t / 3.0) * 1.45);
  float c = cos(f * p.y);
  float s = sin(f / 2.0 * p.y);
  mat2 m = mat2(c, -s, s, c);
  return vec3(m * p.xz, p.y);
}

float cube(vec3 p) {
  p = twist(p);
  cp.x = sin(-t);
  cp.y = cos(-t);
  mat2 m = mat2(cp.y, -cp.x, cp.x, cp.y);
  p.xy *= m; p.xy *= m; p.yz *= m;
  p.zx *= m; p.zx *= m; p.zx *= m;
  cp = p;
  return (length(max(abs(p) - vec3(0.4), 0.0)) - 0.08);
}

float face(vec2 uv) {
  uv.y = mod(uv.y, 1.0);
  return (uv.y < uv.x != 1.0 - uv.y < uv.x) ? 1.0 : 0.0;
}

vec3 getNormal(vec3 p) {
  vec2 e = vec2(0.005, -0.005);
  return normalize(
    e.xyy * cube(p + e.xyy) +
    e.yyx * cube(p + e.yyx) +
    e.yxy * cube(p + e.yxy) +
    e.xxx * cube(p + e.xxx)
  );
}

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  vec2 suv = uv;
  uv = uv * 2.0 - 1.0;
  float ar = resolution.x / resolution.y;
  uv.x *= ar;
  uv *= 1.2;
  float x = gl_FragCoord.x;
  float stp = 1.0;
  float dist = 0.0;
  float near = -1.0;
  float far = -1.0;
  vec3 lightPos = vec3(1.5, 0.5, 1.0);
  float hitdist = -1.0;
  float ay = max(0.1, 0.5 - t / 6.0);
  vec3 ro = vec3(0.0, 0.0, 2.1);
  vec3 rd = normalize(vec3(uv, -2.0));
  for (int i = 0; i < 128; i++) {
    stp = cube(ro + rd * dist);
    dist += stp * 0.5;
    if (dist > 3.0) { break; }
    if (stp < 0.01) {
      far = (
        face(+cp.yx) +
        face(-cp.yx) +
        face(+cp.xz) +
        face(-cp.xz) +
        face(+cp.zy) +
        face(-cp.zy)
      );
      if (hitdist < 0.0) { hitdist = dist; }
      if (near < 0.0) { near = far; }
      dist += 0.05;
    }
  }
  const float speed = 42.0;
  const int layers = 16;
  float stars = 0.0;
  float fl, s;
  for (int layer = 0; layer < layers; layer++) {
    fl = float(layer);
    s = (500.0 - fl * 30.0);
    stars += step(
      0.1,
      pow(
        abs(noise(mod(vec2(suv.x * s + time * speed - fl * 100.0, suv.y * s), resolution.x))),
        21.0
      )
    ) * (fl / float(layers));
  }
  barPos = uv;
  barCol = vec3(stars);
  float bt = time * 0.9;
  bar(sin(bt                      ), 1.0, 0.0, 0.0);
  bar(sin(bt + barsAng / 6.0      ), 1.0, 1.0, 0.0);
  bar(sin(bt + barsAng / 6.0 * 2.0), 0.0, 1.0, 0.0);
  bar(sin(bt + barsAng / 6.0 * 3.0), 0.0, 1.0, 1.0);
  bar(sin(bt + barsAng / 6.0 * 4.0), 0.5, 0.0, 1.0);
  bar(sin(bt + barsAng / 6.0 * 5.0), 1.0, 0.0, 1.0);
  vec3 col = barCol;
  if (near > 0.0) {
    vec3 sp = ro + rd * hitdist;
    vec3 ld = lightPos - sp;
    float lDist = max(length(ld), 0.001);
    ld /= lDist;
    float atten = 1.0 / (1.0 + lDist * 0.2 + lDist * 0.1);
    float ambience = 0.5;
    vec3 sn = getNormal(sp);
    float diff = min(0.3, max(dot(sn, ld), 0.0));
    float spec = pow(max(dot(reflect(-ld, sn), -rd), 0.0), 32.0);
    col = mix(
      vec3(0.12, 0.0, 0.3),
      vec3(1.0, 1.0, 1.0),
      vec3((near * 0.45 + far * far * 0.04))
    );
    col = mix(col, barCol, 0.3);
    col = col * (diff + ambience) + vec3(0.78, 0.5, 1.0) * spec / 1.5;
  }
  float gs = 2.0;
  float grid = (
    (mod(floor((suv.x) * resolution.x / gs), 2.0) == 0.0 ? 1.0 : 0.0) *
    (mod(floor((suv.y) * resolution.y / gs), 2.0) == 0.0 ? 1.0 : 0.0)
  );
  gl_FragColor = vec4(col * grid, 1.0);
}

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

uniform sampler2D prgm1Texture;
uniform vec2 resolution;

const float chx = 12.0;
const float chy = 18.0;

const float reinhardAmount = 0.9;
const float contrast = 1.0;
const float brightness = 15.0;
const float saturation = 1.0;
const vec2 vignetteSize = vec2(0.25, 0.25);
const float vignetteRoundness = 0.12;
const float vignetteMix = 1.0;
const float vignetteSmoothness = 0.30;
const float W = 1.2;
const float T = 7.5;

float filmicReinhardCurve(float x) {
  float q = (T * T + 1.0) * x * x;
  return q / (q + x + T * T);
}

vec3 filmicReinhard(vec3 c) {
  float w = filmicReinhardCurve(W);
  return vec3(
    filmicReinhardCurve(c.r),
    filmicReinhardCurve(c.g),
    filmicReinhardCurve(c.b)
  ) / w;
}

vec3 contrastSaturationBrightness(vec3 color, float brt, float sat, float con) {
  const float AvgLumR = 0.5;
  const float AvgLumG = 0.5;
  const float AvgLumB = 0.5;
  const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
  vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
  vec3 brtColor = color * brt;
  vec3 intensity = vec3(dot(brtColor, LumCoeff));
  vec3 satColor = mix(intensity, brtColor, sat);
  vec3 conColor = mix(AvgLumin, satColor, con);
  return conColor;
}

float sdSquare(vec2 point, float width) {
  vec2 d = abs(point) - width;
  return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
}

float vignette(vec2 uv, vec2 size, float roundness, float smoothness) {
  uv -= 0.5;
  float minWidth = min(size.x, size.y);
  uv.x = sign(uv.x) * clamp(abs(uv.x) - abs(minWidth - size.x), 0.0, 1.0);
  uv.y = sign(uv.y) * clamp(abs(uv.y) - abs(minWidth - size.y), 0.0, 1.0);
  float boxSize = minWidth * (1.0 - roundness);
  float dist = sdSquare(uv, boxSize) - (minWidth * roundness);
  return 1.0 - smoothstep(0.0, smoothness, dist);
}

float gray(vec3 c) {
  return c.x * 0.299 + c.y * 0.587 + c.z * 0.114;
}

void P(
  in int id,
  in int a, in int b, in int c, in int d,
  in int e, in int f, in int g, in int h,
  inout ivec2 p, inout float cha
) {
  if (id == int(p.y)) {
    int pa = (a + 2 * (b + 2 * (c + 2 * (d + 2 * (e + 2 * (f + 2 * (g + 2 * h)))))));
    cha = floor(mod(float(pa) / pow(abs(2.0), float(p.x) -1.0), 2.0));
  }
}

void main(void) {
  vec2 uv = vec2(
    floor(gl_FragCoord.x / chx) * chx,
    floor(gl_FragCoord.y / chy) * chy
  ) / resolution.xy;
  ivec2 p = ivec2(mod(gl_FragCoord.x, chx), mod(gl_FragCoord.y, chy));
  vec4 tex = texture2D(prgm1Texture, uv);
  vec4 texOrig = tex;
  vec3 reinhard = filmicReinhard(tex.xyz);
  vec3 color = tex.rgb;
  color = mix(tex.xyz + vec3(0.1), reinhard, reinhardAmount);
  color = contrastSaturationBrightness(color, brightness, saturation, contrast);
  float v = vignette(uv, vignetteSize, vignetteRoundness, vignetteSmoothness);
  vec3 vig = color * v;
  color = mix(color, vig, vignetteMix);
  tex.xyz = color * color;
  float cha = 0.0;
  float g = gray(tex.xyz);
  if ( g < 0.125 ) {
    P(11,0,0,0,0,0,0,0,0, p, cha);
    P(10,0,0,0,0,0,0,0,0, p, cha);
    P( 9,0,0,0,0,0,0,0,0, p, cha);
    P( 8,0,0,0,0,0,0,0,0, p, cha);
    P( 7,0,0,0,0,0,0,0,0, p, cha);
    P( 6,0,0,0,0,0,0,0,0, p, cha);
    P( 5,0,0,0,0,0,0,0,0, p, cha);
    P( 4,0,0,0,0,0,0,0,0, p, cha);
    P( 3,0,0,0,0,0,0,0,0, p, cha);
    P( 2,0,0,0,0,0,0,0,0, p, cha);
    P( 1,0,0,0,0,0,0,0,0, p, cha);
    P( 0,0,0,0,0,0,0,0,0, p, cha);
  } else if (g < 0.25) {
    P(11,0,0,0,0,0,0,0,0, p, cha);
    P(10,0,0,0,0,0,0,0,0, p, cha);
    P( 9,0,0,0,0,0,0,0,0, p, cha);
    P( 8,0,0,0,0,0,0,0,0, p, cha);
    P( 7,0,0,0,0,0,0,0,0, p, cha);
    P( 6,0,0,0,0,0,0,0,0, p, cha);
    P( 5,0,0,0,0,0,0,0,0, p, cha);
    P( 4,0,0,0,1,1,0,0,0, p, cha);
    P( 3,0,0,0,1,1,0,0,0, p, cha);
    P( 2,0,0,0,0,0,0,0,0, p, cha);
    P( 1,0,0,0,0,0,0,0,0, p, cha);
    P( 0,0,0,0,0,0,0,0,0, p, cha);
  } else if (g < 0.375) {
    P(11,0,0,0,0,0,0,0,0, p, cha);
    P(10,0,0,0,0,0,0,0,0, p, cha);
    P( 9,0,0,0,0,0,0,0,0, p, cha);
    P( 8,0,0,0,0,0,0,0,0, p, cha);
    P( 7,0,0,0,0,0,0,0,0, p, cha);
    P( 6,0,0,0,0,0,0,0,0, p, cha);
    P( 5,0,0,0,0,0,0,0,0, p, cha);
    P( 4,0,0,0,1,1,0,0,0, p, cha);
    P( 3,0,0,0,1,1,0,0,0, p, cha);
    P( 2,0,0,0,0,1,0,0,0, p, cha);
    P( 1,0,0,0,1,0,0,0,0, p, cha);
    P( 0,0,0,0,0,0,0,0,0, p, cha);
  } else if (g < 0.5) {
    P(11,0,0,0,0,0,0,0,0, p, cha);
    P(10,0,0,0,0,0,0,0,0, p, cha);
    P( 9,0,0,0,0,0,0,0,0, p, cha);
    P( 8,0,0,0,0,0,0,0,0, p, cha);
    P( 7,0,0,0,0,0,0,0,0, p, cha);
    P( 6,1,1,1,1,1,1,1,0, p, cha);
    P( 5,0,0,0,0,0,0,0,0, p, cha);
    P( 4,0,0,0,0,0,0,0,0, p, cha);
    P( 3,0,0,0,0,0,0,0,0, p, cha);
    P( 2,0,0,0,0,0,0,0,0, p, cha);
    P( 1,0,0,0,0,0,0,0,0, p, cha);
    P( 0,0,0,0,0,0,0,0,0, p, cha);
  } else if (g < 0.625) {
    P(11,0,0,0,0,0,0,0,0, p, cha);
    P(10,0,0,0,0,0,0,0,0, p, cha);
    P( 9,0,0,0,1,0,0,0,0, p, cha);
    P( 8,0,0,0,1,0,0,0,0, p, cha);
    P( 7,0,0,0,1,0,0,0,0, p, cha);
    P( 6,1,1,1,1,1,1,1,0, p, cha);
    P( 5,0,0,0,1,0,0,0,0, p, cha);
    P( 4,0,0,0,1,0,0,0,0, p, cha);
    P( 3,0,0,0,1,0,0,0,0, p, cha);
    P( 2,0,0,0,0,0,0,0,0, p, cha);
    P( 1,0,0,0,0,0,0,0,0, p, cha);
    P( 0,0,0,0,0,0,0,0,0, p, cha);
  } else if (g < 0.75) {
    P(11,0,0,0,0,0,0,0,0, p, cha);
    P(10,0,0,0,1,0,0,0,0, p, cha);
    P( 9,1,0,0,1,0,0,1,0, p, cha);
    P( 8,0,1,0,1,0,1,0,0, p, cha);
    P( 7,0,0,1,1,1,0,0,0, p, cha);
    P( 6,0,0,0,1,0,0,0,0, p, cha);
    P( 5,0,0,1,1,1,0,0,0, p, cha);
    P( 4,0,1,0,1,0,1,0,0, p, cha);
    P( 3,1,0,0,1,0,0,1,0, p, cha);
    P( 2,0,0,0,1,0,0,0,0, p, cha);
    P( 1,0,0,0,0,0,0,0,0, p, cha);
    P( 0,0,0,0,0,0,0,0,0, p, cha);
  } else if (g < 0.875) {
    P(11,0,0,0,0,0,0,0,0, p, cha);
    P(10,0,0,1,0,0,1,0,0, p, cha);
    P( 9,0,0,1,0,0,1,0,0, p, cha);
    P( 8,1,1,1,1,1,1,1,0, p, cha);
    P( 7,0,0,1,0,0,1,0,0, p, cha);
    P( 6,0,0,1,0,0,1,0,0, p, cha);
    P( 5,0,1,0,0,1,0,0,0, p, cha);
    P( 4,0,1,0,0,1,0,0,0, p, cha);
    P( 3,1,1,1,1,1,1,1,0, p, cha);
    P( 2,0,1,0,0,1,0,0,0, p, cha);
    P( 1,0,1,0,0,1,0,0,0, p, cha);
    P( 0,0,0,0,0,0,0,0,0, p, cha);
  } else {
    P(11,0,0,0,0,0,0,0,0, p, cha);
    P(10,0,0,1,1,1,1,0,0, p, cha);
    P( 9,0,1,0,0,0,0,1,0, p, cha);
    P( 8,1,0,0,0,1,1,1,0, p, cha);
    P( 7,1,0,0,1,0,0,1,0, p, cha);
    P( 6,1,0,0,1,0,0,1,0, p, cha);
    P( 5,1,0,0,1,0,0,1,0, p, cha);
    P( 4,1,0,0,1,0,0,1,0, p, cha);
    P( 3,1,0,0,1,1,1,1,0, p, cha);
    P( 2,0,1,0,0,0,0,0,0, p, cha);
    P( 1,0,0,1,1,1,1,1,0, p, cha);
    P( 0,0,0,0,0,0,0,0,0, p, cha);
  }
  vec3 col = clamp(tex.xyz / max(tex.x, max(tex.y, tex.z)), 0.0, 1.0);
  vec4 charColor = mix(vec4(cha * col, 1.0), vec4(cha), 0.5);
  gl_FragColor = clamp(charColor, 0.0, 1.0);
}

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

uniform sampler2D prgm2Texture;
uniform vec2 resolution;

const float threshold = 1.2;

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  gl_FragColor = texture2D(prgm2Texture, uv);
  if (length(gl_FragColor.rgb) < threshold) { gl_FragColor = vec4(0.0); }
}

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

uniform sampler2D prgm3Texture;
uniform vec2 resolution;

const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const float gaussf = 1.0 / sqrt(TAU);
const float blur = 10.0;
const float width = 30.0;

float gaussian(float x, float sigma) {
  x /= sigma;
  return gaussf / (sigma * exp(0.5 * x * x));
}

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  gl_FragColor = vec4(0.0);
  float total = 0.0;
  for (float x = -width; x < width; x++) {
    float weight = gaussian(x, blur);
    gl_FragColor += vec4(
      texture2D(
        prgm3Texture,
        (gl_FragCoord.xy + vec2(x, 0.0)) / resolution.xy
      ).rgb * weight, weight
    );
  }
  gl_FragColor.rgb /= gl_FragColor.a;
}

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

uniform sampler2D prgm4Texture;
uniform vec2 resolution;

const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const float gaussf = 1.0 / sqrt(TAU);
const float blur = 10.0;
const float height = 30.0;

float gaussian(float x, float sigma) {
  x /= sigma;
  return gaussf / (sigma * exp(0.5 * x * x));
}

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  gl_FragColor = vec4(0.0);
  float total = 0.0;
  for (float y = -height; y < height; y++) {
    float weight = gaussian(y, blur);
    gl_FragColor += vec4(
      texture2D(
        prgm4Texture,
        (gl_FragCoord.xy + vec2(0.0, y)) / resolution.xy
      ).rgb * weight, weight
    );
  }
  gl_FragColor.rgb /= gl_FragColor.a;
}

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

uniform sampler2D prgm2Texture;
uniform sampler2D prgm5Texture;
uniform vec2 resolution;

const float strength = 1.5;

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  gl_FragColor = texture2D(prgm2Texture, uv);
  gl_FragColor += texture2D(prgm5Texture, uv) * strength;
}