diff --git a/shaders/bounce.glsl b/shaders/bounce.glsl new file mode 100644 index 0000000..4ad6527 --- /dev/null +++ b/shaders/bounce.glsl @@ -0,0 +1,31 @@ +// A ball bouncing up and down the stairs, new colour every bounce + +float hash(float n) { return fract(sin(n * 12.9898) * 43758.5453); } + +vec3 hue(float h) { + return clamp(abs(mod(h * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, + 0.0, 1.0); +} + +float ballPos(float t) { + return 12.0 * abs(sin(t * 0.5)); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float i = floor(fragCoord.x / iResolution.x * 16.0); + + float cyc = iTime * 0.5 / 3.14159265; + float bounce = floor(cyc); + // colour changes while the ball is on the floor, faded over the bounce + vec3 colour = mix(hue(hash(bounce + 2.0)), hue(hash(bounce + 3.0)), + smoothstep(0.0, 0.25, fract(cyc))); + + float d = i - ballPos(iTime); + float v = exp(-d * d * 1.0); + for (int j = 1; j <= 8; j++) { + float fj = float(j); + float dj = i - ballPos(iTime - fj * 0.12); + v = max(v, 0.7 * exp(-fj * 0.35) * exp(-dj * dj * 1.0)); + } + fragColor = vec4(colour * v + vec3(0.01, 0.0, 0.02), 1.0); +} diff --git a/shaders/fire.glsl b/shaders/fire.glsl new file mode 100644 index 0000000..ed67ceb --- /dev/null +++ b/shaders/fire.glsl @@ -0,0 +1,24 @@ +// Flames licking up the stairs, hottest at step 0 + +float hash(float n) { return fract(sin(n * 12.9898) * 43758.5453); } + +float noise(float x) { + float i = floor(x); + float f = fract(x); + return mix(hash(i), hash(i + 1.0), f * f * (3.0 - 2.0 * f)); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float i = floor(fragCoord.x / iResolution.x * 16.0); + float v = clamp(i / 12.5, 0.0, 1.0); + + float flicker = 0.6 * noise(i * 0.6 - iTime * 2.2) + + 0.4 * noise(i * 1.3 - iTime * 3.7 + 10.0); + float heat = (1.0 - v) * (0.45 + 0.75 * flicker); + heat = clamp(heat, 0.0, 1.0); + + vec3 col = vec3(smoothstep(0.0, 0.4, heat), + smoothstep(0.25, 0.85, heat) * 0.75, + smoothstep(0.75, 1.0, heat) * 0.35); + fragColor = vec4(col, 1.0); +} diff --git a/shaders/heartbeat.glsl b/shaders/heartbeat.glsl new file mode 100644 index 0000000..23b14a5 --- /dev/null +++ b/shaders/heartbeat.glsl @@ -0,0 +1,19 @@ +// A slow lub-dub travelling up the stairs + +float bump(float x, float c, float w) { + float d = (x - c) / w; + return exp(-d * d); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float i = floor(fragCoord.x / iResolution.x * 16.0); + + float period = 3.2; // slow, ~19 bpm + float ph = fract((iTime - i * 0.15) / period) * period; + float beat = bump(ph, 0.50, 0.20) + 0.65 * bump(ph, 1.25, 0.26); + + vec3 base = vec3(0.10, 0.0, 0.01); + vec3 col = base + vec3(1.0, 0.04, 0.06) * beat; + col += vec3(0.5) * bump(ph, 0.50, 0.08); // white-ish peak + fragColor = vec4(col, 1.0); +} diff --git a/shaders/ocean.glsl b/shaders/ocean.glsl new file mode 100644 index 0000000..a1667c4 --- /dev/null +++ b/shaders/ocean.glsl @@ -0,0 +1,17 @@ +// Slow waves with white foam on the crests + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float i = floor(fragCoord.x / iResolution.x * 16.0); + + float w = 0.5 + 0.5 * sin(i * 0.55 - iTime * 0.5); + float w2 = 0.5 + 0.5 * sin(i * 0.9 + iTime * 0.35 + 1.0); + float h = 0.6 * w + 0.4 * w2; + + vec3 deep = vec3(0.0, 0.05, 0.28); + vec3 shallow = vec3(0.0, 0.55, 0.75); + vec3 col = mix(deep, shallow, h); + + float foam = smoothstep(0.82, 0.97, h); + col = mix(col, vec3(0.9), foam * 0.8); + fragColor = vec4(col, 1.0); +} diff --git a/shaders/storm.glsl b/shaders/storm.glsl new file mode 100644 index 0000000..a58e8a9 --- /dev/null +++ b/shaders/storm.glsl @@ -0,0 +1,28 @@ +// Dark clouds with rare lightning + +float hash(float n) { return fract(sin(n * 12.9898) * 43758.5453); } + +float noise(float x) { + float i = floor(x); + float f = fract(x); + return mix(hash(i), hash(i + 1.0), f * f * (3.0 - 2.0 * f)); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float i = floor(fragCoord.x / iResolution.x * 16.0); + + float cloud = 0.6 * noise(i * 0.4 - iTime * 0.25) + + 0.4 * noise(i * 0.9 + iTime * 0.15 + 20.0); + vec3 col = mix(vec3(0.0, 0.01, 0.04), vec3(0.07, 0.10, 0.22), cloud); + + // one strike per 14 s slot, 60% of the slots + float slot = floor(iTime / 14.0); + float local = iTime - (slot * 14.0 + 1.0 + hash(slot + 5.0) * 10.0); + if (hash(slot + 9.0) < 0.6 && local > 0.0 && local < 1.2) { + float bolt = floor(hash(slot + 13.0) * 12.0); // where it strikes + float flash = exp(-local * 7.0) + 0.8 * exp(-abs(local - 0.22) * 14.0); + float near = exp(-abs(i - bolt) * 0.5); + col += vec3(0.75, 0.8, 1.0) * flash * (0.15 + 0.85 * near); + } + fragColor = vec4(col, 1.0); +} diff --git a/shaders/trans.glsl b/shaders/trans.glsl new file mode 100644 index 0000000..7383084 --- /dev/null +++ b/shaders/trans.glsl @@ -0,0 +1,19 @@ +// Trans flag, gently waving. The white stripe uses the white LEDs. + +vec3 stripe(int k) { + if (k == 0 || k == 4) return vec3(0.25, 0.75, 1.0); // blue + if (k == 1 || k == 3) return vec3(1.0, 0.35, 0.55); // pink + return vec3(1.0); // white +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float i = floor(fragCoord.x / iResolution.x * 16.0); + float x = (i + 0.5) / 13.0; + float p = x * 5.0 + 0.5 * sin(iTime * 0.3) + 0.25 * sin(x * 6.0 - iTime * 0.7); + p = clamp(p, 0.0, 4.999); + int k = int(floor(p)); + float f = smoothstep(0.7, 1.0, fract(p)); + vec3 col = mix(stripe(k), stripe(min(k + 1, 4)), f); + col *= 0.9 + 0.1 * sin(i * 0.5 - iTime * 0.8); + fragColor = vec4(col * 0.8, 1.0); +}