{
    "name": "Water Caustics",
    "description": "Wasser mit Maus-Interaktion",
    "vertex_shader": "attribute vec2 a_position;\nvoid main() {\n    gl_Position = vec4(a_position, 0.0, 1.0);\n}",
    "fragment_shader": "precision mediump float;\nuniform float u_time;\nuniform vec2 u_resolution;\nuniform float u_deltaTime;\nuniform vec2 u_mouseNorm;\n\nfloat hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }\nfloat noise(vec2 p) {\n    vec2 i = floor(p), f = fract(p);\n    f = f*f*(3.0-2.0*f);\n    return mix(mix(hash(i), hash(i+vec2(1.0,0.0)), f.x),\n               mix(hash(i+vec2(0.0,1.0)), hash(i+vec2(1.0,1.0)), f.x), f.y);\n}\n\nvoid main() {\n    vec2 uv = gl_FragCoord.xy \/ u_resolution.xy;\n    float t = u_time * 0.4;\n    vec2 mouseOff = (u_mouseNorm - 0.5) * 0.1;\n    float n = noise(uv*8.0 + t + mouseOff) + noise(uv*16.0 - t*0.7) * 0.5;\n    vec3 water = vec3(0.0, 0.3, 0.5) + vec3(0.0, 0.4, 0.5) * n;\n    vec3 caustic = vec3(1.0, 0.95, 0.8) * pow(n, 3.0) * 0.8;\n    gl_FragColor = vec4(water + caustic, 1.0);\n}"
}