|
|
@ -0,0 +1,114 @@ |
|
|
|
#version 330 core |
|
|
|
|
|
|
|
#define FOV 8 |
|
|
|
|
|
|
|
#define EPSILON 0.01 |
|
|
|
#define MAX_STEPS 64 |
|
|
|
#define NEAR_D 0. |
|
|
|
#define FAR_D 40. |
|
|
|
|
|
|
|
#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 "hg_sdf.glsl" |
|
|
|
#include "utils.glsl" |
|
|
|
#include "march_prolog.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(fSphere(p, 2), 0.); |
|
|
|
|
|
|
|
return box; |
|
|
|
} |
|
|
|
|
|
|
|
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++) { |
|
|
|
SceneResult sr = scene_f(o + d*t); |
|
|
|
if (sr.d < EPSILON || t > end) |
|
|
|
return vec3(t, sr.mat_idx, i); |
|
|
|
|
|
|
|
t += sr.d; |
|
|
|
} |
|
|
|
return vec3(end, N_HIT_FAR_PLANE, MAX_STEPS); |
|
|
|
} |
|
|
|
|
|
|
|
vec4 flag(float p) { |
|
|
|
p = abs(p); |
|
|
|
if (p < 0.167) { |
|
|
|
return vec4(1); |
|
|
|
} else if (p < 0.5) { |
|
|
|
return vec4(0.960784, 0.662745, 0.721569, 1); |
|
|
|
} else { |
|
|
|
return vec4(0.356863, 0.807843, 0.980392, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
vec4 shade_material(vec3 p, vec3 norm, float mat_idx) { |
|
|
|
if (mat_idx == 0.) { |
|
|
|
return flag(p.y/(sin(p.z)+1)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
vec4 shade(vec3 p, float mat_idx) { |
|
|
|
vec3 norm = estimate_scene_normal(p); |
|
|
|
vec4 color_mat = shade_material(p, norm, mat_idx); |
|
|
|
|
|
|
|
return color_mat; |
|
|
|
} |
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
float an = 0.3 * u_Time; |
|
|
|
float d = 6.; |
|
|
|
vec3 eye = vec3(3. * sin(an), 2., 3. * cos(an)) * d; |
|
|
|
vec3 target = vec3(0., 0., 0.); |
|
|
|
mat3 lookAt = look_mat(eye, target, 0); |
|
|
|
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 mat_idx = result.y; |
|
|
|
float iters = result.z; |
|
|
|
if (depth >= FAR_D) { |
|
|
|
color = vec4(0.); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
vec3 p = eye + dir * depth; // recast the ray |
|
|
|
color = shade(p, mat_idx); |
|
|
|
|
|
|
|
// gamma |
|
|
|
color = vec4(pow(clamp(color.xyz, 0.0, 1.0), vec3(0.4545)), 1.0); |
|
|
|
} |
|
|
|
|