A Tribute to Phenomena (ASCII)

A tribute to the unforgettable 90s aesthetics and to the pioneer giants whose shoulders we stand on.

Created by marcogomez on Sat, 21 Aug 2021 06:22:35 GMT.


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

uniform	sampler2D eTexture0; // https://i.imgur.com/N9yUvGf.png
uniform sampler2D prgm1Texture;
uniform sampler2D prgm2Texture;
uniform vec2 resolution;
uniform float time;
uniform float alpha;

const vec3 tWhite = vec3(1.0);
const float tPixelSize = 8.0;
const float transitionSpread = 0.21;
const float transitionSpeed = 0.15;
const float transitionIntensity = 32.0;

void main(void) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;
  vec4 prgm1 = texture2D(prgm1Texture, uv);
  vec4 prgm2 = texture2D(prgm2Texture, uv);
  vec2 noiseCell = floor(gl_FragCoord.xy / tPixelSize);
  vec2 noiseUV = noiseCell / resolution.xy;
  float noise = texture2D(eTexture0, noiseUV).x * transitionSpread;
  float progress = (time * transitionSpeed) + noiseUV.y + noise;
  float peak = cos(progress) * transitionIntensity;
  float transition = clamp(peak, 0.0, 1.0);
  vec4 col = mix(prgm2, prgm1, transition);
  gl_FragColor = col;
}

// ╔═════════════╦═════════════════╦════════════════╗
// ║ 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 zoom = 1.0;
const float amount = 1.0;
const bool bypass = false;
const float chx = 12.0;
const float chy = 18.0;

const float reinhardAmount = 0.99;
const float contrast = 0.8;
const float brightness = 30.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.42;
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) {
  float z = zoom;
  vec2 uv = vec2(
    floor(gl_FragCoord.x / chx / z) * chx * z,
    floor(gl_FragCoord.y / chy / z) * chy * z
  ) / resolution.xy;
  ivec2 p = ivec2(mod(gl_FragCoord.x / z, chx), mod(gl_FragCoord.y / z, chy));
  vec4 prgm1 = texture2D(prgm1Texture, uv);
  vec4 prgm1Orig = prgm1;
  vec3 reinhard = filmicReinhard(prgm1.xyz);
  vec3 color = prgm1.rgb;
  color = mix(prgm1.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);
  color = mix(prgm1.xyz, color, amount);
  prgm1.xyz = color * color;
  float cha = 0.0;
  float g = gray(prgm1.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 = prgm1.xyz / max(prgm1.x, max(prgm1.y, prgm1.z));
  vec4 charColor = mix(vec4(cha * col, 1.0), vec4(cha), 0.5);
  gl_FragColor = vec4(mix(prgm1, charColor, amount).xyz, 1.0);
}