LCD image burn fix

This is an attempt to help out with image persistence or "screen burn" on LCD screens that might have been caused by "harmonic" flickering (half or a quarter of refresh rate frequency) in relation to the screen refresh rate, potentially causing static-related inversion artifacts on polarized screens.

Created by marcogomez on Tue, 09 Nov 2021 00:44:23 GMT.


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

uniform vec2 resolution;
uniform float time;

const float split = 4.0;
const float nColors = 3.0;
const vec3 r = vec3(1.0, 0.0, 0.0);
const vec3 g = vec3(0.0, 1.0, 0.0);
const vec3 b = vec3(0.0, 0.0, 1.0);

float clamps(float x) { return clamp(x, 0.0, 1.0); }
vec3 clamps(vec3 x) { return clamp(x, 0.0, 1.0); }
float ordered(float idx) { return 1.0 - mod(floor(idx + time * 2.0), 3.0); }
vec3 ss(vec3 c) { return smoothstep(0.0, 1.0, c); }

void main(void) {
  float t = 32.0 + time * 2.0;
  vec2 uv = (gl_FragCoord.xy / resolution.xy) * vec2(resolution.x / resolution.y, 1.0);
  vec3 color = vec3(0.0);
  if (mod(floor(t * 0.0325), 2.0) == 0.0) {
    color = vec3(clamps(ordered(0.0)), clamps(ordered(1.0)), clamps(ordered(2.0)));
  } else {
    uv.y -= t * 0.75;
    float degreeAng = (mod(floor(t * 0.125), 2.0) == 0.0) ? 45.0 : 0.0;
    uv.y -= tan(radians(degreeAng)) * uv.x;
    float id = mod(floor(uv.y * split), nColors);
    color = (id == 0.0) ? ss(r) : (id == 1.0) ? ss(g) : ss(b);
  }
  color = clamps(color);
  gl_FragColor = vec4(color, 1.0);
}