From 08f2f11ce8c3eee1c6548fa69f4d5bd1931bf839 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Sun, 3 Jan 2021 23:36:59 +0100 Subject: Lambertian material with random numbers patern repetition artifact --- include/vk-renderer.hpp | 8 +++- shaders/compute.comp | 104 ++++++++++++++++++++++++++++++++++++++++-------- src/main.cpp | 9 +++-- 3 files changed, 101 insertions(+), 20 deletions(-) diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp index b1f8d3f..0902abd 100644 --- a/include/vk-renderer.hpp +++ b/include/vk-renderer.hpp @@ -20,9 +20,15 @@ struct input_data { struct sphere { vec3 position; + struct material { + color albedo; + } material; float radius; float padding[3]; - } sphere; + } spheres[2]; + + uint32_t max_bounce; + float padding[3]; }; struct path_tracer_data { diff --git a/shaders/compute.comp b/shaders/compute.comp index 861da63..75773b4 100644 --- a/shaders/compute.comp +++ b/shaders/compute.comp @@ -10,9 +10,15 @@ struct hit_info { bool front_face; }; +struct material { + vec4 color; +}; + struct sphere { vec4 position; + material mat; float radius; + float[3] padding; }; layout(set = 0, binding = 0) buffer Inputs { @@ -27,7 +33,10 @@ layout(set = 0, binding = 0) buffer Inputs { float[200] random_numbers; - sphere s; + sphere[2] spheres; + + uint max_bounce; + float [3] padding; vec4[] image; }; @@ -36,8 +45,33 @@ vec3 at(ray r, float t) { return r.origin + r.direction * t; } -bool hit_sphere(ray r, out hit_info info) { - // Vector from the ray origin to sphere position +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 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; + } + } +} + +bool hit_sphere(sphere s, ray r, float min_t, float max_t, out hit_info info) { vec3 origin_center = r.origin - s.position.xyz; float a = dot(r.direction, r.direction); @@ -46,11 +80,20 @@ bool hit_sphere(ray r, out hit_info info) { float discriminant = half_b * half_b - a * c; if (discriminant < 0) { - info.t = -1.0; return false; } - info.t = (-half_b - sqrt(discriminant)) / a; + float sqrt_discriminant = sqrt(discriminant); + float root = (-half_b - sqrt_discriminant) / a; + if (root < min_t || root > max_t) { + root = (-half_b + sqrt_discriminant) / a; + + if (root < min_t || root > max_t) { + return false; + } + } + + info.t = root; info.point = at(r, info.t); vec3 outward_normal = (info.point - s.position.xyz) / s.radius; @@ -60,6 +103,45 @@ bool hit_sphere(ray r, out hit_info info) { return true; } +bool hit_spheres(ray r, out hit_info info) { + float min_t = 1e20; + 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)) { + info = temp_info; + min_t = temp_info.t; + hit = true; + } + } + + return hit; +} + +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); + bounces++; + } + + if (bounces == max_bounce) { + return vec4(0.0); + } + + 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() { uint x = gl_GlobalInvocationID.x; uint y = gl_GlobalInvocationID.y; @@ -75,17 +157,7 @@ void main() { vec2 jittered_uvs = uv + vec2(random_numbers[sample_index * 2] / (width - 1), random_numbers[sample_index * 2 + 1] / (height - 1)); vec3 proj_plane_pos = first + vec3(jittered_uvs.x * viewport_width, jittered_uvs.y * viewport_height, 0.0); - ray r = ray(camera_pos.xyz, proj_plane_pos - camera_pos.xyz); - 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); - } else { - image[y * width + x] += mix(ground_color, sky_color, uv.y); - } + 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; diff --git a/src/main.cpp b/src/main.cpp index 8811c78..a10ff7e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,7 +82,7 @@ int main() { // Image dimensions // const float aspect_ratio = 16.0 / 9.0; - const float aspect_ratio = 1.0 / 1.0; + const float aspect_ratio = 1.0; const size_t width = 400; const size_t height = width / aspect_ratio; const uint32_t samples_per_pixel = 100; @@ -102,8 +102,11 @@ int main() { .viewport_width = 2.f * aspect_ratio, .viewport_height = 2.f, .proj_plane_distance = 1.f, - .sphere = { { 0.f, 0.f, -1.f }, 0.5f }, - // .sphere = { { 0.f, -100.5f, -1.f }, 100.f }, + .spheres = { + { { 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, }; for (size_t rand_number_index = 0; rand_number_index < samples_per_pixel * 2; rand_number_index++) { -- cgit v1.3