#version 430 layout(local_size_x = 1, local_size_y = 1) in; uniform float seconds = 0; layout(rgba8) uniform writeonly image2D outputImg; #define MAX_ITERATIONS 500 #define MAX_DISTANCE 100.0 #define SURF_DIST 0.01 float sdfCircle(in vec3 p, in vec3 origin, in float radius) { return length(p - origin) - radius; } 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(in vec3 p) { float c1 = sdfCircle(p, vec3(0, 1, 2.4), 0.2); float c2 = sdfCircle(p, vec3(-0.6, 1, 3), 0.3); return min(c1, c2); } float ray_march_scene(in vec3 ray_origin, in vec3 ray_direction) { float dist = 0.; for (int i = 0; i < MAX_ITERATIONS && dist < MAX_DISTANCE; i++) { vec3 p = ray_origin + dist * ray_direction; float gap = scene(p); dist += gap; if (gap <= SURF_DIST) return dist; } return dist; } vec3 surface_normal_scene(in vec3 p) { vec2 inc = vec2(0.01, 0); return normalize(vec3(scene(p + inc.xyy) - scene(p - inc.xyy), scene(p + inc.yxy) - scene(p - inc.yxy), scene(p + inc.yyx) - scene(p - inc.yyx))); } void main() { vec2 resolution = vec2(imageSize(outputImg).xy); vec3 uv = vec3((gl_GlobalInvocationID.xy - resolution / 2.0) / resolution, 0); float aspect_ratio = resolution.y / resolution.x; uv /= vec3(aspect_ratio, 1, 1); vec3 camera_pos = vec3(0, 1, 0); vec3 camera_direction = normalize(vec3(uv.x, uv.y, 1.)); vec3 light_pos = vec3(1, 2. * sin(seconds), 1); float depth = ray_march_scene(camera_pos, camera_direction); vec3 p = camera_pos + camera_direction * depth; vec3 normal = surface_normal_scene(p); vec3 light_vec = normalize(light_pos - p); float contrast = dot(normal, light_vec); contrast = clamp(contrast, 0.1, 1.); vec3 col = vec3(0.15); if (depth < MAX_DISTANCE) { float light_ray_dist = ray_march_scene(p + 10. * normal * SURF_DIST, light_vec); if (light_ray_dist < length(light_pos - p)) contrast *= 0.3; col = vec3(0, 1. - (depth / MAX_DISTANCE), 0.4); col *= contrast; } imageStore(outputImg, ivec2(gl_GlobalInvocationID.xy), vec4(col, 1.)); }