#define STEPS 64
float sdBox(vec3 p, vec3 b) {
vec3 q = abs(p) - b;
return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
}
float smin(float a, float b, float k) {
float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);
return mix(b, a, h) - k * h * (1.0 - h);
}
float scene(vec3 p) {
float sphere = length(p - vec3(-0.45, 0.0, 0.0)) - 0.6;
float box = sdBox(p - vec3(0.450, 0.0, 0.0), vec3(0.4));
float ground = p.y + 0.7;
return min(smin(sphere, box, 0.250), ground);
}
vec3 sceneNormal(vec3 p) {
vec2 e = vec2(0.001, 0.0);
return normalize(vec3(scene(p + e.xyy) - scene(p - e.xyy),
scene(p + e.yxy) - scene(p - e.yxy),
scene(p + e.yyx) - scene(p - e.yyx)));
}
void main() {
vec2 p = (gl_FragCoord.xy - 0.5 * uResolution) / min(uResolution.x, uResolution.y);
float a = 0.500 + uTime * 0.15;
vec3 ro = vec3(3.2 * sin(a), 1.0, 3.2 * cos(a));
vec3 forward = normalize(-ro);
vec3 right = normalize(cross(forward, vec3(0.0, 1.0, 0.0)));
vec3 up = cross(right, forward);
vec3 rd = normalize(forward * 1.6 + right * p.x + up * p.y);
float t = 0.0;
float hit = 0.0;
for (int i = 0; i < 128; i++) {
if (i >= STEPS) break;
float d = scene(ro + rd * t);
if (d < 0.001) { hit = 1.0; break; }
t += d;
if (t > 20.0) break;
}
vec3 pos = ro + rd * t;
vec3 N = sceneNormal(pos);
float diffuse = max(dot(N, normalize(vec3(0.6, 0.8, 0.4))), 0.0);
float tiles = mod(floor(pos.x * 2.0) + floor(pos.z * 2.0), 2.0);
vec3 surface = pos.y < -0.69 ? mix(vec3(0.16, 0.22, 0.25), vec3(0.24, 0.36, 0.34), tiles) : vec3(0.96, 0.43, 0.30);
vec3 color = mix(vec3(0.07, 0.11, 0.15), surface * (0.2 + 0.8 * diffuse), hit);
gl_FragColor = vec4(color, 1.0);
}