classic..not
Log in to post a comment.
#version 300 es precision highp float; uniform float iTime; uniform vec2 iResolution; out vec4 fragColor; #define PI 3.14159265359 #define MAX_STEPS 100 #define MAX_DIST 50.0 #define SURF_DIST 0.001 // triangular wave in [0,1] float tri(float t) { return abs(mod(t, 2.0) - 1.0); } // SDFs float sdSphere(vec3 p, vec3 c, float r) { return length(p - c) - r; } // plane at y = -1 float sdPlane(vec3 p) { return p.y + 1.0; } // scene‐map: sphere + finite floor float mapScene(vec3 p, out int objID) { float d = MAX_DIST; objID = -1; // bouncing sphere float hx = tri(iTime * 0.5); float hy = tri(iTime * 0.7); vec3 center = vec3( mix(-1.5, 1.5, hx), mix(-0.5, 1.5, hy), 0.0 ); float ds = sdSphere(p, center, 0.75); d = ds; objID = 1; // finite floor (disk radius = 5.0) float floorRadius = 5.0; float rad = length(p.xz); if (rad < floorRadius) { float dp = sdPlane(p); if (dp < d) { d = dp; objID = 0; } } return d; } // numerical normal vec3 getNormal(vec3 p) { vec2 e = vec2(0.001, 0.0); int tmp; return normalize(vec3( mapScene(p + e.xyy, tmp) - mapScene(p - e.xyy, tmp), mapScene(p + e.yxy, tmp) - mapScene(p - e.yxy, tmp), mapScene(p + e.yyx, tmp) - mapScene(p - e.yyx, tmp) )); } // ray‐march vec3 rayMarch(vec3 ro, vec3 rd, out int objID) { float t = 0.0; objID = -1; for (int i = 0; i < MAX_STEPS; i++) { vec3 p = ro + rd * t; float dist = mapScene(p, objID); if (dist < SURF_DIST) return p; if (t > MAX_DIST) break; t += dist; } return ro + rd * t; } // simple Phong vec3 phong(vec3 p, vec3 n, vec3 v) { vec3 Lpos = vec3(5.0, 5.0, -5.0); vec3 L = normalize(Lpos - p); float dif = max(dot(n, L), 0.0); vec3 R = reflect(-L, n); float spec = pow(max(dot(R, v), 0.0), 32.0); return vec3(0.2) + dif * vec3(1.0) + spec * vec3(1.0); } // sky gradient vec3 skyColor(vec3 rd) { // horizon is where rd.y = 0 float t = clamp(rd.y * 0.5 + 0.5, 0.0, 1.0); vec3 hor = vec3(0.8, 0.9, 1.0); vec3 zen = vec3(0.2, 0.5, 0.9); return mix(hor, zen, t); } // rotating checker on the ball vec3 checker(vec3 p, vec3 center) { vec3 d = normalize(p - center); float spin = iTime * 2.0; float cs = cos(spin), sn = sin(spin); vec3 d2 = vec3(cs * d.x - sn * d.z, d.y, sn * d.x + cs * d.z); float u = atan(d2.z, d2.x) / (2.0 * PI) + 0.5; float v = acos(d2.y) / PI; float tile = mod(floor(u * 8.0) + floor(v * 8.0), 2.0); return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), tile); } void main() { // uv + camera vec2 uv = (gl_FragCoord.xy / iResolution.xy) * 2.0 - 1.0; uv.x *= iResolution.x / iResolution.y; vec3 ro = vec3(0.0, 0.0, -3.0); vec3 rd = normalize(vec3(uv, 1.0)); int obj; vec3 hit = rayMarch(ro, rd, obj); vec3 vDir = normalize(-rd); vec3 col; if (obj == 1) { // ball vec3 n = getNormal(hit); float hx = tri(iTime * 0.5); float hy = tri(iTime * 0.7); vec3 center = vec3( mix(-1.5, 1.5, hx), mix(-0.5, 1.5, hy), 0.0 ); vec3 base = checker(hit, center); col = base * phong(hit, n, vDir); } else if (obj == 0) { // floor (finite disk) vec3 n = vec3(0.0, 1.0, 0.0); float c = mod(floor(hit.x) + floor(hit.z), 2.0); vec3 base = mix(vec3(0.1), vec3(0.8), c); col = phong(hit, n, vDir) * base; } else { // sky beyond the disk col = skyColor(rd); } fragColor = vec4(col, 1.0); }