{
    "name": "Ray Marching",
    "description": "3D-Sphaere mit Kamera",
    "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 vec3 u_cameraPos;\nuniform float u_cameraFov;\n\nfloat sdSphere(vec3 p, float r) { return length(p) - r; }\nfloat map(vec3 p) { return sdSphere(p, 0.8); }\nvec3 getNormal(vec3 p) {\n    float d = map(p); vec2 e = vec2(0.001, 0.0);\n    return normalize(d - vec3(map(p-e.xyy), map(p-e.yxy), map(p-e.yyx)));\n}\n\nvoid main() {\n    vec2 uv = (gl_FragCoord.xy - 0.5*u_resolution.xy) \/ u_resolution.y;\n    vec3 ro = u_cameraPos;\n    vec3 rd = normalize(vec3(uv, -1.0 \/ tan(radians(u_cameraFov) * 0.5)));\n    float t = 0.0;\n    for (int i = 0; i < 64; i++) {\n        vec3 p = ro + rd * t;\n        float d = map(p);\n        if (d < 0.001 || t > 10.0) break;\n        t += d;\n    }\n    vec3 col = vec3(0.05);\n    if (t < 10.0) {\n        vec3 p = ro + rd * t;\n        vec3 n = getNormal(p);\n        vec3 light = normalize(vec3(sin(u_time), 1.0, cos(u_time)));\n        float diff = max(dot(n, light), 0.0);\n        float spec = pow(max(dot(reflect(-light, n), -rd), 0.0), 32.0);\n        col = vec3(0.2, 0.5, 0.9) * diff + vec3(1.0) * spec * 0.5;\n    }\n    gl_FragColor = vec4(col, 1.0);\n}"
}