#version 330 core #define FOV 90 #define EPSILON 0.01 #define MAX_STEPS 64 #define NEAR_D 0. #define FAR_D 20. #define GRAD_EPSILON 0.0001 #define saturate(x) clamp(x, 0, 1) uniform vec2 u_Resolution; uniform vec4 u_Mouse; uniform float u_Time; out vec4 color; #include "utils.glsl" #include "march_prolog.glsl" #include "hg_sdf.glsl" #include "colormap_cool.glsl" vec3 ray_dir(float fov, vec2 uv) { float z = 1./tan(radians(fov)/2.); return normalize(vec3(uv, z)); } SceneResult scene_f(vec3 p) { SceneResult box = SceneResult(fBox(p, vec3(1)), 1.); SceneResult sphere = SceneResult(fSphere(p + vec3(1), 1.0), 2.); return min_sr(box, sphere); } vec3 estimate_scene_normal(vec3 p) { vec3 dx = vec3(GRAD_EPSILON, 0, 0); vec3 dy = vec3(0, GRAD_EPSILON, 0); vec3 dz = vec3(0, 0, GRAD_EPSILON); return normalize(vec3( scene_f(p + dx).d - scene_f(p - dx).d, scene_f(p + dy).d - scene_f(p - dy).d, scene_f(p + dz).d - scene_f(p - dz).d )); } vec3 raymarch(vec3 o, vec3 d, float start, float end) { float t = start; for (int i = 0; i < MAX_STEPS; i++) { float dist = scene_f(o + d*t); if (dist < EPSILON || t > end) return vec3(t, i, 0.); t += dist; } return vec3(end, MAX_STEPS, 0.); } vec4 shade(vec3 p) { vec3 normal = estimate_scene_normal(p); return vec4((normal + vec3(1.0))/2.0, 1.0); } void main() { vec2 mouse_uv = u_Mouse.xy * 2.0 / u_Resolution.xy - 1.0; vec2 uv = gl_FragCoord.xy * 2.0 / u_Resolution.xy - 1.0; uv.x *= u_Resolution.x/u_Resolution.y; vec3 eye = vec3(0., 0., -5.); mat3 lookAt = calcLookAtMatrix(eye, vec3(0., 0., 0.), u_Time); vec3 dir = normalize(lookAt * ray_dir(FOV, uv)); color = vec4(0.); vec3 result = raymarch(eye, dir, NEAR_D, FAR_D); float depth = result.x; float iters = result.y; if (depth >= FAR_D) { color = vec4(1.0, 0.5, 1.0, 1.0); return; } color = colormap(iters/MAX_STEPS+0.5); vec3 p = eye + dir * depth; color = shade(p); }