111 lines
2.5 KiB
GLSL
111 lines
2.5 KiB
GLSL
#version 450
|
|
|
|
layout(location = 0) in vec2 uv;
|
|
layout(location = 0) out vec4 out_color;
|
|
layout(set = 2, binding = 0) uniform sampler2D screen;
|
|
|
|
layout(std140, set = 3, binding = 0) uniform UniformBlock {
|
|
mat4 model;
|
|
mat4 view;
|
|
mat4 projection;
|
|
float time;
|
|
};
|
|
|
|
|
|
float road(float x) { return cos(x); }
|
|
|
|
vec3 backup(vec2 uv) {
|
|
float x_scale = time * 12.0;
|
|
float y_scale = uv.x;
|
|
|
|
uv.x *= x_scale;
|
|
uv.y *= 2.0;
|
|
uv.y -= 1.0;
|
|
uv.y /= 0.75;
|
|
uv.y /= y_scale;
|
|
|
|
float y = road(uv.x);
|
|
|
|
float dist = length(uv.y - y);
|
|
|
|
vec3 col = vec3(cos(time / 10.0)) - vec3(exp(-dist), cos(dist), sin(dist));
|
|
return (0.005 * (1.2 + abs(cos(time)))) / col;
|
|
}
|
|
|
|
const int MAX_MARCH_STEPS = 64;
|
|
const float EPS_DIST = 1e-6;
|
|
|
|
float sdf(vec3 point) {
|
|
// return length(point - vec3(6.0 * sin(time), 8.0*abs(sin(time * 0.7)*cos(time)), 5.0 * cos(time * 1.2))) - 0.4;
|
|
float size = 8.0 + (3.0* sin(time));
|
|
vec3 s1_local = mod(point, vec3(size)) - vec3(size/2.0);
|
|
float s1 = length(s1_local) - 0.3;
|
|
return s1;
|
|
}
|
|
|
|
vec3 getnormal(vec3 p) {
|
|
float e = EPS_DIST;
|
|
return normalize(vec3(
|
|
sdf(p + vec3(e, 0.0, 0.0)) - sdf(p - vec3(e, 0.0, 0.0)),
|
|
sdf(p + vec3(0.0, e, 0.0)) - sdf(p - vec3(0.0, e, 0.0)),
|
|
sdf(p + vec3(0.0, 0.0, e)) - sdf(p - vec3(0.0, 0.0, e))
|
|
));
|
|
}
|
|
|
|
|
|
|
|
vec4 march(vec3 point, vec3 ray) {
|
|
float MAX_DEPTH = texture(screen, uv).w * 1000.0;
|
|
float totaldist = 0.0;
|
|
|
|
int i;
|
|
for (i = 0; i < MAX_MARCH_STEPS && totaldist < MAX_DEPTH; i += 1) {
|
|
float h = sdf(point);
|
|
point += h * ray;
|
|
if (h < EPS_DIST) {
|
|
return vec4(point, totaldist + h);
|
|
}
|
|
|
|
totaldist += h;
|
|
}
|
|
|
|
return vec4(-1.0);
|
|
}
|
|
|
|
vec3 camray() {
|
|
vec2 ndc = uv * 2.0 - 1.0;
|
|
ndc.y = -ndc.y;
|
|
vec4 clip = vec4(ndc, 1.0, 1.0);
|
|
vec4 view_pos = inverse(projection) * clip;
|
|
view_pos /= view_pos.w;
|
|
|
|
vec3 ray_dir_view = normalize(view_pos.xyz);
|
|
|
|
vec3 ray_dir_world = normalize((inverse(view) * vec4(ray_dir_view, 0.0)).xyz);
|
|
|
|
return ray_dir_world;
|
|
}
|
|
|
|
vec3 camorigin() { return (inverse(view) * vec4(0, 0, 0, 1)).xyz; }
|
|
|
|
vec4 kernel() {
|
|
vec3 cam_pos = camorigin();
|
|
vec3 cam_ray = camray();
|
|
|
|
return march(cam_pos, cam_ray);
|
|
}
|
|
|
|
float t(float x, float y) { return length(texture(screen, vec2(x, y)).xyz); }
|
|
|
|
void main() {
|
|
|
|
vec2 bg = (projection * view * vec4(uv, 1.0, 1.0)).xy;
|
|
vec3 b = backup(bg);
|
|
vec4 hit = kernel();
|
|
if (hit.w > 0.0 && ((t(uv.x, uv.y) < 0.01) || (hit.w < (texture(screen, uv).w * 1000.0)))) {
|
|
out_color = vec4(getnormal(hit.xyz), 1.0);
|
|
} else {
|
|
out_color = texture(screen, uv);
|
|
}
|
|
}
|