Add fire, ocean, heartbeat, bounce, trans and storm shaders

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
April John 2026-10-16 15:03:47 +02:00
commit cebb41dbc7
6 changed files with 138 additions and 0 deletions

31
shaders/bounce.glsl Normal file
View file

@ -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);
}

24
shaders/fire.glsl Normal file
View file

@ -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);
}

19
shaders/heartbeat.glsl Normal file
View file

@ -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);
}

17
shaders/ocean.glsl Normal file
View file

@ -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);
}

28
shaders/storm.glsl Normal file
View file

@ -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);
}

19
shaders/trans.glsl Normal file
View file

@ -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);
}