extern crate caper;
use caper::utils::demo;
fn main() {
demo(
"
#version 330
const int MAX_MARCHING_STEPS = 255;
const float MIN_DIST = 0.0;
const float MAX_DIST = 100.0;
const float EPSILON = 0.0001;
uniform vec2 resolution;
uniform vec3 cam_pos;
in vec2 v_tex_coords;
out vec4 frag_output;
float sphereSDF(vec3 p, float s) {
return length(p) - s;
}
float sceneSDF(vec3 p) {
return sphereSDF(p, 1.0);
}
float shortestDistanceToSurface(vec3 eye, vec3 marchingDirection, float start, float end) {
float depth = start;
for (int i = 0; i < MAX_MARCHING_STEPS; i++) {
float dist = sceneSDF(eye + depth * marchingDirection);
if (dist < EPSILON) {
return depth;
}
depth += dist;
if (depth >= end) {
return end;
}
}
return end;
}
vec3 rayDirection(float fieldOfView, vec2 size, vec2 fragCoord) {
vec2 xy = fragCoord - size / 2.0;
float z = size.y / tan(radians(fieldOfView) / 2.0);
return normalize(vec3(xy, -z));
}
void main() {
vec3 dir = rayDirection(45.0, resolution, v_tex_coords * resolution);
float dist = shortestDistanceToSurface(cam_pos, dir, MIN_DIST, MAX_DIST);
if (dist > MAX_DIST - EPSILON) {
// Didn't hit anything
frag_output = vec4(0.0, 0.0, 0.0, 0.0);
return;
}
frag_output = vec4(1.0, 0.0, 0.0, 1.0);
}
",
);
}