#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++) {
|
|
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, -1., MAX_STEPS);
|
|
}
|
|
|
|
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 = 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(1.0, 0.5, 1.0, 1.0);
|
|
return;
|
|
}
|
|
|
|
color = colormap(iters/MAX_STEPS+0.5);
|
|
vec3 p = eye + dir * depth;
|
|
color = shade(p);
|
|
}
|
|
|