{
    "name": "Starfield Warp",
    "description": "Warp-Geschwindigkeit durch ein Sternenfeld",
    "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 vec2 u_mouseNorm;\nuniform float u_zoom;\n\nfloat hash(float n) { return fract(sin(n) * 43758.5453123); }\nfloat noise(vec2 x) {\n    vec2 p = floor(x);\n    vec2 f = fract(x);\n    f = f * f * (3.0 - 2.0 * f);\n    float n = p.x + p.y * 57.0;\n    return mix(mix(hash(n), hash(n + 1.0), f.x),\n               mix(hash(n + 57.0), hash(n + 58.0), f.x), f.y);\n}\n\nvoid main() {\n    vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) \/ u_resolution.y;\n    float t = u_time * 0.5 * u_zoom;\n    vec3 col = vec3(0.0);\n    float mouseInfluence = length(uv - (u_mouseNorm - 0.5) * vec2(u_resolution.x\/u_resolution.y, 1.0));\n    for (float i = 0.0; i < 3.0; i++) {\n        float fi = i + 1.0;\n        vec2 p = uv * fi * 3.0;\n        float a = atan(p.y, p.x);\n        float r = length(p);\n        float warp = t * fi * 0.5;\n        float stars = noise(vec2(a * 10.0 + warp, r * 2.0 - warp * 2.0));\n        stars = pow(stars, 8.0) * smoothstep(5.0, 0.0, r);\n        vec3 starCol = vec3(0.8, 0.9, 1.0) * stars;\n        if (i == 1.0) starCol = vec3(1.0, 0.8, 0.6) * stars;\n        if (i == 2.0) starCol = vec3(0.6, 0.8, 1.0) * stars;\n        col += starCol \/ fi;\n    }\n    col += vec3(0.05, 0.02, 0.1) \/ (length(uv) + 0.3);\n    col += smoothstep(0.3, 0.0, mouseInfluence) * vec3(0.2, 0.4, 1.0) * 0.3;\n    gl_FragColor = vec4(col, 1.0);\n}"
}