diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2021-01-01 20:48:57 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2021-01-01 20:48:57 +0100 |
| commit | ca7f65d7cc2d82ce1bd752785fd100a1855b4dc3 (patch) | |
| tree | ae1e04c5141e4addda292189bc378f4944e4afe4 /shaders | |
| parent | 84d6440f507a33d526acd15e55f73d99f747c8ec (diff) | |
Hit function return hit struct
Diffstat (limited to 'shaders')
| -rw-r--r-- | shaders/compute.comp | 53 |
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); } |
