treppe-gl/shaders/reef-2d.glsl
April John d917860201 Add 2D canvas mode compacted to the steps, ocean-chaos and reef-2d shaders
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 15:28:41 +02:00

46 lines
1.9 KiB
GLSL

// canvas: 256x48 compact: mean
//
// A real 2D picture, compacted to the stairs by treppe-gl: every step is the
// average of a 16 pixel wide column of the canvas. Fish swim through slowly,
// caustics ripple near the surface, the colours drift around the wheel.
float hash(float n) { return fract(sin(n * 12.9898) * 43758.5453); }
vec3 hsv(float h, float s, float v) {
vec3 rgb = clamp(abs(mod(h * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0,
0.0, 1.0);
return v * mix(vec3(1.0), rgb, s);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord / iResolution.xy; // 0..1, y up
float t = iTime;
float drift = t / 180.0;
// water, darker towards the bottom
vec3 col = hsv(0.55 + drift + 0.08 * sin(uv.x * 3.0 + t * 0.05),
0.95, 0.12 + 0.55 * uv.y);
// caustics near the surface
float c = sin(uv.x * 60.0 + t * 0.4 + 2.0 * sin(uv.y * 8.0 + t * 0.3))
* sin(uv.x * 41.0 - t * 0.3 + uv.y * 6.0);
col += hsv(0.50 + drift, 0.4, 1.0) * pow(max(c, 0.0), 3.0) * uv.y * 0.5;
// fish
for (int k = 0; k < 5; k++) {
float fk = float(k);
float speed = 0.02 + 0.015 * hash(fk + 1.0); // screen widths / s
float dir = mod(fk, 2.0) < 1.0 ? 1.0 : -1.0;
float fx = fract(t * speed * dir + fk * 0.23) * 1.4 - 0.2;
float fy = 0.25 + 0.5 * hash(fk + 7.0) + 0.05 * sin(t * 0.5 + fk);
vec2 d = vec2((uv.x - fx) / 0.10, (uv.y - fy) / 0.30);
float body = 1.0 - smoothstep(0.7, 1.0, length(d));
// tail behind the fish
vec2 dt = vec2((uv.x - (fx - dir * 0.09)) / 0.04, (uv.y - fy) / 0.22);
float tail = 1.0 - smoothstep(0.6, 1.0, length(dt));
vec3 fc = hsv(hash(fk + 3.0) + 0.5 + drift, 0.85, 1.0);
col = mix(col, fc, clamp(body + 0.8 * tail, 0.0, 1.0) * 0.9);
}
fragColor = vec4(col, 1.0);
}