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