aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2021-01-04 00:26:10 +0100
committerladevieq <ladevie.quentin@gmail.com>2021-01-04 00:26:10 +0100
commit558f9a40d2c1d82c808477b76fab71a8e55f1121 (patch)
treeea48e19bb87458619fbceca191848f26902cc819
parent08f2f11ce8c3eee1c6548fa69f4d5bd1931bf839 (diff)
Fix artifacts and add gamma correction
-rw-r--r--include/vk-renderer.hpp1
-rw-r--r--shaders/compute.comp59
-rw-r--r--src/main.cpp12
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();