aboutsummaryrefslogtreecommitdiffstats
path: root/shaders
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2021-01-01 20:48:57 +0100
committerladevieq <ladevie.quentin@gmail.com>2021-01-01 20:48:57 +0100
commitca7f65d7cc2d82ce1bd752785fd100a1855b4dc3 (patch)
treeae1e04c5141e4addda292189bc378f4944e4afe4 /shaders
parent84d6440f507a33d526acd15e55f73d99f747c8ec (diff)
Hit function return hit struct
Diffstat (limited to 'shaders')
-rw-r--r--shaders/compute.comp53
1 files changed, 43 insertions, 10 deletions
diff --git a/shaders/compute.comp b/shaders/compute.comp
index 1f901dc..b9c165e 100644
--- a/shaders/compute.comp
+++ b/shaders/compute.comp
@@ -3,6 +3,22 @@ struct ray {
vec3 direction;
};
+struct hit_info {
+ float t;
+ vec3 point;
+ vec3 normal;
+ bool front_face;
+};
+
+struct sphere {
+ vec4 position;
+ float radius;
+};
+
+vec3 at(ray r, float t) {
+ return r.origin + r.direction * t;
+}
+
layout(set = 0, binding = 0) buffer Inputs {
vec4 sky_color;
vec4 ground_color;
@@ -13,21 +29,33 @@ layout(set = 0, binding = 0) buffer Inputs {
float proj_plane_distance;
float padding;
- vec4 sphere_position;
+ sphere s;
- vec4 [] image;
+ vec4[] image;
};
-bool hit_sphere(vec3 position, float radius, ray r) {
+bool hit_sphere(ray r, out hit_info info) {
// Vector from the ray origin to sphere position
- vec3 origin_center = r.origin - position;
+ vec3 origin_center = r.origin - s.position.xyz;
float a = dot(r.direction, r.direction);
float half_b = dot(r.direction, origin_center);
- float c = dot(origin_center, origin_center) - radius * radius;
+ float c = dot(origin_center, origin_center) - s.radius * s.radius;
float discriminant = half_b * half_b - a * c;
- return (discriminant > 0);
+ if (discriminant < 0) {
+ info.t = -1.0;
+ return false;
+ }
+
+ info.t = (-half_b - sqrt(discriminant)) / a;
+ info.point = at(r, info.t);
+
+ vec3 outward_normal = (info.point - s.position.xyz) / s.radius;
+ info.front_face = dot(outward_normal, r.direction) < 0.0;
+ info.normal = info.front_face ? outward_normal : -outward_normal;
+
+ return true;
}
void main() {
@@ -36,16 +64,21 @@ void main() {
uint width = gl_NumWorkGroups.x;
uint height = gl_NumWorkGroups.y;
- vec2 uv = vec2(float(x) / (width - 1), float(y) / (height - 1));
+ vec2 uv = vec2(float(x) / (width - 1), 1.0 - (float(y) / (height - 1)));
vec3 first = camera_pos.xyz - vec3(viewport_width / 2.0, viewport_height / 2.0, proj_plane_distance);
vec3 proj_plane_pos = first + vec3(uv.x * viewport_width, uv.y * viewport_height, 0.0);
ray r = ray(camera_pos.xyz, proj_plane_pos - camera_pos.xyz);
- if (hit_sphere(sphere_position.xyz, 0.5, r)) {
- image[y * width + x] = vec4(1.0, 0.0, 0.0, 0.0);
+ hit_info info;
+
+ if (hit_sphere(r, info)) {
+ vec3 hit_normal = normalize(info.normal);
+ hit_normal = (hit_normal + 1.0) * 0.5;
+
+ image[y * width + x] = vec4(hit_normal, 0.0);
return;
}
- image[y * width + x] = mix(sky_color, ground_color, uv.y);
+ image[y * width + x] = mix(ground_color, sky_color, uv.y);
}