diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2021-01-04 00:26:10 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2021-01-04 00:26:10 +0100 |
| commit | 558f9a40d2c1d82c808477b76fab71a8e55f1121 (patch) | |
| tree | ea48e19bb87458619fbceca191848f26902cc819 | |
| parent | 08f2f11ce8c3eee1c6548fa69f4d5bd1931bf839 (diff) | |
Fix artifacts and add gamma correction
| -rw-r--r-- | include/vk-renderer.hpp | 1 | ||||
| -rw-r--r-- | shaders/compute.comp | 59 | ||||
| -rw-r--r-- | src/main.cpp | 12 |
3 files changed, 31 insertions, 41 deletions
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp index 0902abd..06427f0 100644 --- a/include/vk-renderer.hpp +++ b/include/vk-renderer.hpp @@ -17,6 +17,7 @@ struct input_data { float proj_plane_distance; float random_numbers[200]; + vec3 random_in_sphere[1000]; struct sphere { vec3 position; diff --git a/shaders/compute.comp b/shaders/compute.comp index 75773b4..feefbe6 100644 --- a/shaders/compute.comp +++ b/shaders/compute.comp @@ -33,6 +33,8 @@ layout(set = 0, binding = 0) buffer Inputs { float[200] random_numbers; + vec4[1000] random_in_sphere; + sphere[2] spheres; uint max_bounce; @@ -45,30 +47,16 @@ vec3 at(ray r, float t) { return r.origin + r.direction * t; } -float rand(vec2 co){ - return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); -} - -float rand(vec2 co, float min, float max){ - return min + (max - min) * rand(co); -} - -vec3 rand_vec3(vec2 co) { - return vec3(rand(co), rand(vec2(co.y, co.x)), rand(vec2(co.x, co.x))); -} - -vec3 rand_vec3(vec2 co, float min, float max) { - return vec3(rand(co, min, max), rand(co.xy * co.x, min, max), rand(co.xy * co.y, min, max)); +vec3 to_hemisphere_vec(vec3 unit_vec, vec3 normal) { + if (dot(unit_vec, normal) > 0.0) { + return unit_vec; + } else { + return -unit_vec; + } } -vec3 rand_unit_sphere(vec2 co) { - uint i = 0; - while(true) { - vec3 vec = rand_vec3(i++ * co, -1.0, 1.0); - if (length(vec) <= 1.0) { - return vec; - } - } +float rand(vec2 co) { + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); } bool hit_sphere(sphere s, ray r, float min_t, float max_t, out hit_info info) { @@ -103,14 +91,14 @@ bool hit_sphere(sphere s, ray r, float min_t, float max_t, out hit_info info) { return true; } -bool hit_spheres(ray r, out hit_info info) { - float min_t = 1e20; +bool hit_spheres(ray r, float min_t, float max_t, out hit_info info) { + float closest_t = max_t; hit_info temp_info; bool hit = false; for (uint sphere_index = 0; sphere_index < 2; sphere_index++) { - if (hit_sphere(spheres[sphere_index], r, 0.0, min_t, temp_info)) { + if (hit_sphere(spheres[sphere_index], r, min_t, closest_t, temp_info)) { info = temp_info; - min_t = temp_info.t; + closest_t = temp_info.t; hit = true; } } @@ -122,9 +110,12 @@ vec4 ray_color(ray r, uint sample_index) { hit_info info; uint bounces = 0; - while (hit_spheres(r, info) && bounces < max_bounce) { - vec3 target = info.point + info.normal + rand_unit_sphere(info.point.xy); - r = ray(info.point, target - info.point); + ray current_ray = r; + while (hit_spheres(current_ray, 0.0001, 1e15, info) && bounces < max_bounce) { + vec2 seed = vec2(info.point.x * sample_index, info.point.y * bounces) * gl_GlobalInvocationID.xy; + vec3 unit_hemisphere_vec = to_hemisphere_vec(random_in_sphere[uint(rand(seed) * 999.0)].xyz, info.normal); + vec3 target = info.point + info.normal + unit_hemisphere_vec; + current_ray = ray(info.point, target - info.point); bounces++; } @@ -133,13 +124,6 @@ vec4 ray_color(ray r, uint sample_index) { } return pow(0.5, bounces) * mix(ground_color, sky_color, (normalize(r.direction).y + 1.0) * 0.5); - - // No lambertian - // if (hit_spheres(r, info)) { - // return vec4(0.5 * (info.normal + vec3(1.0)), 0.0); - // } - - // return mix(ground_color, sky_color, (normalize(r.direction).y + 1.0) * 0.5); } void main() { @@ -160,5 +144,6 @@ void main() { image[y * width + x] += ray_color(ray(camera_pos.xyz, proj_plane_pos - camera_pos.xyz), sample_index); } - image[y * width + x] /= samples_per_pixel; + float spp_scale = (1.0 / samples_per_pixel); + image[y * width + x] = sqrt(image[y * width + x] * spp_scale); } diff --git a/src/main.cpp b/src/main.cpp index a10ff7e..885b078 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -81,9 +81,9 @@ int main() { vkrenderer renderer {}; // Image dimensions - // const float aspect_ratio = 16.0 / 9.0; - const float aspect_ratio = 1.0; - const size_t width = 400; + const float aspect_ratio = 16.0 / 9.0; + // const float aspect_ratio = 1.0; + const size_t width = 1920; const size_t height = width / aspect_ratio; const uint32_t samples_per_pixel = 100; const uint32_t max_depth = 100; @@ -106,13 +106,17 @@ int main() { { { 0.f, 0.f, -1.f }, { { 0.f, 0.f, 1.f }, }, 0.5f }, { { 0.f, -100.5f, -1.f }, { { 0.f, 1.f, 0.f }, }, 100.f } }, - .max_bounce = 50, + .max_bounce = max_depth, }; for (size_t rand_number_index = 0; rand_number_index < samples_per_pixel * 2; rand_number_index++) { inputs.random_numbers[rand_number_index] = randd(); } + for (size_t rand_number_index = 0; rand_number_index < max_depth * 10; rand_number_index++) { + inputs.random_in_sphere[rand_number_index] = random_in_unit_sphere(); + } + // World hittable objects hittable_list world = random_scene(); |
