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 | |
| parent | 84d6440f507a33d526acd15e55f73d99f747c8ec (diff) | |
Hit function return hit struct
| -rw-r--r-- | include/vk-renderer.hpp | 6 | ||||
| -rw-r--r-- | shaders/compute.comp | 53 | ||||
| -rw-r--r-- | src/main.cpp | 8 |
3 files changed, 53 insertions, 14 deletions
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp index cc27d02..ca3e182 100644 --- a/include/vk-renderer.hpp +++ b/include/vk-renderer.hpp @@ -16,7 +16,11 @@ struct input_data { float proj_plane_distance; float pad; - vec3 sphere_position; + struct sphere { + vec3 position; + float radius; + float padding[3]; + } sphere; }; struct path_tracer_data { 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); } diff --git a/src/main.cpp b/src/main.cpp index 97624ea..b769dd3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -81,8 +81,9 @@ int main() { vkrenderer renderer {}; // Image dimensions - const float aspect_ratio = 16.0 / 9.0; - const size_t width = 1920; + // const float aspect_ratio = 16.0 / 9.0; + const float aspect_ratio = 1.0 / 1.0; + const size_t width = 400; const size_t height = width / aspect_ratio; const uint32_t samples_per_pixel = 1; const uint32_t max_depth = 100; @@ -100,7 +101,8 @@ int main() { .viewport_width = 2.f * aspect_ratio, .viewport_height = 2.f, .proj_plane_distance = 1.f, - .sphere_position = { 0.f, 0.f, -1.f }, + .sphere = { { 0.f, 0.f, -1.f }, 0.5f }, + // .sphere = { { 0.f, -100.5f, -1.f }, 100.f }, }; // World hittable objects |
