aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2021-03-31 23:59:51 +0200
committerladevieq <ladevie.quentin@gmail.com>2021-03-31 23:59:51 +0200
commit790f5ca6413fb14a232ed7a9dc74461a21007996 (patch)
tree53a101919df610e8c6942c3bb87370fe57a69354
parent0d84a8e2c8b683803072f76fde8824ce194c80bc (diff)
Remove most precomputed random numbers
-rw-r--r--include/utils.hpp2
-rw-r--r--shaders/compute.comp56
-rw-r--r--src/utils.cpp60
3 files changed, 57 insertions, 61 deletions
diff --git a/include/utils.hpp b/include/utils.hpp
index 8d46821..a196a73 100644
--- a/include/utils.hpp
+++ b/include/utils.hpp
@@ -16,9 +16,7 @@ struct input_data {
camera cam;
- float random_offset[2000];
float random_disk[2000];
- vec3 random_in_sphere[1000];
sphere spheres[512];
bvh_node nodes[1024];
diff --git a/shaders/compute.comp b/shaders/compute.comp
index 6f35094..d0de07c 100644
--- a/shaders/compute.comp
+++ b/shaders/compute.comp
@@ -5,6 +5,7 @@ struct ray {
vec3 direction;
};
+const float PI = 3.141592653589793;
const uint LAMBERTIAN_MATERIAL = 0;
const uint METAL_MATERIAL = 1;
const uint DIELECTRIC_MATERIAL = 2;
@@ -68,9 +69,7 @@ layout(set = 0, binding = 0) buffer Inputs {
vec4 ground_color;
camera cam;
- vec2[1000] random_offset;
vec2[1000] random_disk;
- vec4[1000] random_in_sphere;
sphere[512] spheres;
bvh_node[1024] nodes;
@@ -91,16 +90,30 @@ vec3 at(ray r, float t) {
return r.origin + r.direction * t;
}
-vec3 to_hemisphere_vec(vec3 unit_vec, vec3 normal) {
- if (dot(unit_vec, normal) > 0.0) {
- return unit_vec;
- } else {
- return -unit_vec;
- }
+
+uint wang_hash(inout uint seed)
+{
+ seed = (seed ^ 61) ^ (seed >> 16);
+ seed *= 9;
+ seed = seed ^ (seed >> 4);
+ seed *= 0x27d4eb2d;
+ seed = seed ^ (seed >> 15);
+ return seed;
+}
+
+float rand(inout uint seed)
+{
+ float r = wang_hash(seed) * (1.0 / 4294967296.0);
+ // seed += 10;
+ return r;
}
-float rand(vec2 co) {
- return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
+vec3 unit_vec(inout uint seed) {
+ float z = rand(seed) * 2.0 - 1.0;
+ float a = 2.0 * PI * rand(seed);
+ float r = sqrt(1.0 - z * z);
+
+ return vec3(cos(a) * r, sin(a) * r, z);
}
bool hit_aabb(aabb b, ray r, float min_t, float max_t) {
@@ -213,21 +226,18 @@ bool hit_spheres(ray r, float min_t, float max_t, out hit_info info) {
return hit;
}
-bool lambertian_scattering(material mat, ray incident, vec2 seed, hit_info info, out vec4 attenuation, out ray scattered) {
- vec3 unit_hemisphere_vec = to_hemisphere_vec(random_in_sphere[uint(rand(seed) * 999.0)].xyz, info.normal);
-
+bool lambertian_scattering(material mat, ray incident, inout uint seed, hit_info info, out vec4 attenuation, out ray scattered) {
attenuation = mat.albedo;
- scattered = ray(info.point, info.normal + unit_hemisphere_vec);
+ scattered = ray(info.point, normalize(info.normal + unit_vec(seed)));
return true;
}
-bool metal_scattering(material mat, ray incident, vec2 seed, hit_info info, out vec4 attenuation, out ray scattered) {
+bool metal_scattering(material mat, ray incident, inout uint seed, hit_info info, out vec4 attenuation, out ray scattered) {
vec3 reflected = reflect(normalize(incident.direction), info.normal);
- vec3 unit_sphere_vec = random_in_sphere[uint(rand(seed) * 999.0)].xyz;
attenuation = mat.albedo;
- scattered = ray(info.point, reflected + mat.fuzz * unit_sphere_vec);
+ scattered = ray(info.point, reflected + mat.fuzz * unit_vec(seed));
return (dot(scattered.direction, info.normal) > 0.0);
}
@@ -239,7 +249,7 @@ float reflectance(float cosine, float eta) {
return r0 + (1 - r0) * pow((1 - cosine), 5);
}
-bool dielectric_scattering(material mat, ray incident, vec2 seed, hit_info info, out vec4 attenuation, out ray scattered) {
+bool dielectric_scattering(material mat, ray incident, inout uint seed, hit_info info, out vec4 attenuation, out ray scattered) {
attenuation = vec4(1.0);
vec3 unit_dir = normalize(incident.direction);
@@ -260,14 +270,13 @@ bool dielectric_scattering(material mat, ray incident, vec2 seed, hit_info info,
return true;
}
-vec4 ray_color(ray r, uint sample_index) {
+vec4 ray_color(ray r, uint seed) {
hit_info info;
uint bounces = 0;
vec4 final_color = vec4(1.0);
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;
+ while (hit_spheres(current_ray, 0.001, 1e15, info) && bounces < max_bounce) {
ray scattered;
vec4 attenuation;
if ((info.mat.type == LAMBERTIAN_MATERIAL && lambertian_scattering(info.mat, current_ray, seed, info, attenuation, scattered)) ||
@@ -295,8 +304,7 @@ void main() {
vec2 uv = vec2(float(x) / (width - 1), 1.0 - (float(y) / (height - 1)));
- sample_index %= 1000;
-
+ uint seed = (y * width + x) * 100 + sample_index;
vec2 jittered_uvs = uv + vec2(random_disk[sample_index].x / (width - 1), random_disk[sample_index].y / (height - 1));
vec2 lens_disk = random_disk[sample_index] * cam.lens_radius;
vec3 offset = lens_disk.x * cam.right.xyz + lens_disk.y * cam.up.xyz;
@@ -304,7 +312,7 @@ void main() {
ray r = ray(cam.position.xyz + offset, proj_plane_pos.xyz - cam.position.xyz - offset);
- vec4 out_color = ray_color(r, sample_index);
+ vec4 out_color = ray_color(r, seed);
float spp_scale = (1.0 / samples_per_pixel);
vec4 acc_color = imageLoad(accumulation_image, ivec2(x, y));
diff --git a/src/utils.cpp b/src/utils.cpp
index 18b2580..b228e82 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -49,34 +49,34 @@ uint32_t random_scene(sphere *world) {
uint32_t world_sphere_index = 1;
int32_t spheres_count = 11;
- for (int a = -spheres_count; a < spheres_count; a++) {
- for (int b = -spheres_count; b < spheres_count; b++) {
- auto choose_mat = randd();
- point3 center(a + 0.9 * randd(), 0.2, b + 0.9 * randd());
+ // for (int a = -spheres_count; a < spheres_count; a++) {
+ // for (int b = -spheres_count; b < spheres_count; b++) {
+ // auto choose_mat = randd();
+ // point3 center(a + 0.9 * randd(), 0.2, b + 0.9 * randd());
- if ((center - point3{ 4, 0.2, 0 }).length() > 0.9) {
- material sphere_material = {};
+ // if ((center - point3{ 4, 0.2, 0 }).length() > 0.9) {
+ // material sphere_material = {};
- if (choose_mat < 0.8) {
- // diffuse
- sphere_material.albedo = color::random() * color::random();
- sphere_material.type = MATERIAL_TYPE::LAMBERTIAN;
- } else if (choose_mat < 0.95) {
- // metal
- sphere_material.albedo = color::random(0.5, 1);
- sphere_material.fuzz = randd(0, 0.5);
- sphere_material.type = MATERIAL_TYPE::METAL;
- } else {
- // glass
- sphere_material.ior = 1.5;
- sphere_material.type = MATERIAL_TYPE::DIELECTRIC;
- }
+ // if (choose_mat < 0.8) {
+ // // diffuse
+ // sphere_material.albedo = color::random() * color::random();
+ // sphere_material.type = MATERIAL_TYPE::LAMBERTIAN;
+ // } else if (choose_mat < 0.95) {
+ // // metal
+ // sphere_material.albedo = color::random(0.5, 1);
+ // sphere_material.fuzz = randd(0, 0.5);
+ // sphere_material.type = MATERIAL_TYPE::METAL;
+ // } else {
+ // // glass
+ // sphere_material.ior = 1.5;
+ // sphere_material.type = MATERIAL_TYPE::DIELECTRIC;
+ // }
- world[world_sphere_index] = { center, sphere_material, 0.2 };
- world_sphere_index++;
- }
- }
- }
+ // world[world_sphere_index] = { center, sphere_material, 0.2 };
+ // world_sphere_index++;
+ // }
+ // }
+ // }
material material1 = {};
material1.ior = 1.5;
@@ -126,22 +126,12 @@ struct input_data create_inputs(uint32_t width, uint32_t height, uint32_t sample
.sample_index = 0,
};
- // Random numbers pools
- for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index += 2) {
- inputs.random_offset[rand_number_index] = randd();
- inputs.random_offset[rand_number_index + 1] = randd();
- }
-
for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index += 2) {
vec3 random_unit_disk = random_in_unit_disk();
inputs.random_disk[rand_number_index] = random_unit_disk.x;
inputs.random_disk[rand_number_index + 1] = random_unit_disk.y;
}
- for (size_t rand_number_index = 0; rand_number_index < 1000; rand_number_index++) {
- inputs.random_in_sphere[rand_number_index] = random_in_unit_sphere();
- }
-
// World hittable objects
uint32_t spheres_count = random_scene(inputs.spheres);