diff --git a/Makefile b/Makefile index c983530..1c30415 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ INCLUDE=./include LIBS=-pthread -lm FLAGS=-Ofast -march=native -g -Wall -Wextra -Wpedantic -raytracer: camera.hpp color.hpp hittable.hpp hittable_list.hpp main.cpp material.hpp random.h ray.hpp rtweekend.hpp sphere.hpp vec3.hpp $(INCLUDE)/Remotery.c $(INCLUDE)/Remotery.h +raytracer: camera.hpp color.hpp hittable.hpp hittable_list.hpp main.cpp material.hpp ray.hpp rtweekend.hpp sphere.hpp vec3.hpp $(INCLUDE)/Remotery.c $(INCLUDE)/Remotery.h g++ $(FLAGS) -I$(INCLUDE) $(LIBS) main.cpp -o raytracer make debug: diff --git a/camera.hpp b/camera.hpp index 5de6d7d..cd28486 100644 --- a/camera.hpp +++ b/camera.hpp @@ -40,9 +40,9 @@ struct camera { /* Methods */ - ray get_ray(float s, float t, int32_t thread_id = 0) const + ray get_ray(float s, float t) const { - vec3 rd = lens_radius * random_in_unit_disk(thread_id); + vec3 rd = lens_radius * random_in_unit_disk(); vec3 offset = u * rd.x + v * rd.y; return ray(origin + offset, lower_left_corner + s*horizontal + t*vertical - origin - offset); diff --git a/main.cpp b/main.cpp index 7b3291a..8ff4582 100644 --- a/main.cpp +++ b/main.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #define RMT_ENABLED 0 @@ -118,7 +117,7 @@ hittable_list random_scene() { } template -color ray_color(const ray& r, hittable_list& world, int32_t depth, int32_t thread_id) +color ray_color(const ray& r, hittable_list& world, int32_t depth) { rmt_ScopedCPUSample(Scatter, RMTSF_Aggregate | RMTSF_Recursive); if (depth <= 0) @@ -132,11 +131,11 @@ color ray_color(const ray& r, hittable_list& world, int32_t depth, int32_t th ray scattered; color attenuation; rmt_BeginCPUSample(Scatter, RMTSF_Aggregate); - bool visible = rec.mat_ptr->scatter(r, rec, attenuation, scattered, thread_id); + bool visible = rec.mat_ptr->scatter(r, rec, attenuation, scattered); rmt_EndCPUSample(); if (visible) { - return attenuation * ray_color(scattered, world, depth-1, thread_id); + return attenuation * ray_color(scattered, world, depth-1); } else { @@ -164,9 +163,6 @@ float hit_sphere(const point3& center, float radius, const ray& r) int32_t main(int argc, char *argv[]) { - - - /* Argument parsing */ int32_t c; bool using_default_output = true; @@ -229,30 +225,6 @@ int32_t main(int argc, char *argv[]) //indicators::show_console_cursor(false); - - // Get the number of logical CPUs - int32_t ncores = sysconf(_SC_NPROCESSORS_ONLN); - // Initialize and seed the random number generators - pcg_table = (pcg32_random_t *) malloc(sizeof(pcg32_random_t) * ncores); - for (int32_t i = 0; i < ncores; ++i) - { - struct timespec ts; - if (timespec_get(&ts, TIME_UTC)) - { - // Use higher quality seed - uint64_t seed = (uint64_t)(ts.tv_nsec ^ ts.tv_sec); - pcg_table[i] = { seed, seed }; - } - else - { - // Error, use default seed - pcg_table[i] = default_pcg; - } - - - - } - // Image aspect_ratio = 3.0 / 2.0; image_width = 1200; @@ -285,11 +257,11 @@ int32_t main(int argc, char *argv[]) // Render fprintf(output_file_handle, "P3\n%d %d\n255\n", image_width, image_height); - + int32_t ncores = sysconf(_SC_NPROCESSORS_ONLN); // Get the number of logical CPUs std::vector threads; std::vector args; threads.reserve(ncores); - args.reserve(ncores); + args.reserve(ncores); std::vector bar_memory; bar_memory.reserve(ncores); @@ -409,10 +381,10 @@ void *raytrace_lines(void *arg) color pixel_color = color(0,0,0); for (int32_t s = 0; s < samples_per_pixel; ++s) { - float u = ((i + random_float(thread_id)) / (image_width-1)); - float v = ((j + random_float(thread_id)) / (image_height-1)); - ray r = global_camera->get_ray(u,v, thread_id); - pixel_color += ray_color(r, world, max_depth, thread_id); + float u = ((i + random_float()) / (image_width-1)); + float v = ((j + random_float()) / (image_height-1)); + ray r = global_camera->get_ray(u,v); + pixel_color += ray_color(r, world, max_depth); } int32_t index = j * image_width + i; image[index] = pixel_color; diff --git a/material.hpp b/material.hpp index 5665533..0e2e5fd 100644 --- a/material.hpp +++ b/material.hpp @@ -4,7 +4,7 @@ #include "rtweekend.hpp" struct material { - virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, int32_t thread_id = 0) const = 0; + virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const = 0; }; struct lambertian : material { @@ -15,9 +15,9 @@ struct lambertian : material { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" - virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, int32_t thread_id = 0) const override + virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const override { - vec3 scatter_direction = rec.normal + random_unit_vector(thread_id); + vec3 scatter_direction = rec.normal + random_unit_vector(); /* NOTE: it is possible that the random vector we generate is exactly opposite to the normal vector, in which case it will sum to a near-zero scatter vector and generate degenerate results. @@ -45,10 +45,10 @@ struct metal : material { fuzz = f; }; - virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, int32_t thread_id) const override + virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const override { vec3 reflected = reflect(normalize(r_in.direction), rec.normal); - scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere(thread_id)); + scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere()); attenuation = albedo; return (dot(scattered.direction, rec.normal) > 0); } @@ -74,7 +74,7 @@ struct dielectric : material /* Virtual methods */ - virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, int32_t thread_id) const override + virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const override { attenuation = color(1,1,1); float refraction_ratio = rec.front_face ? (1.0/ri) : ri; @@ -87,7 +87,7 @@ struct dielectric : material bool cannot_refract = refraction_ratio * sin_theta > 1.0; vec3 direction; - if (cannot_refract || reflectance(cos_theta, refraction_ratio) > random_float(thread_id)) + if (cannot_refract || reflectance(cos_theta, refraction_ratio) > random_float()) direction = reflect(unit_direction, rec.normal); else direction = refract(unit_direction, rec.normal, refraction_ratio); diff --git a/rtweekend.hpp b/rtweekend.hpp index 136efe7..412dbaf 100644 --- a/rtweekend.hpp +++ b/rtweekend.hpp @@ -8,8 +8,11 @@ #include "timer.hpp" #include "random.h" -pcg32_random_t *pcg_table; -pcg32_random_t default_pcg = { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL }; +#define FAST_RANDOM 1 +#ifdef FAST_RANDOM +pcg32_random_t pcg = { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL }; +#define rand() pcg32_random_r(&pcg) +#endif /* Utility functions */ inline float degrees_to_radians(float d) @@ -18,21 +21,15 @@ inline float degrees_to_radians(float d) } /* Returns a float in the range [0,1) */ -inline float random_float_() +inline float random_float() { return rand() * (1.0 / RAND_MAX); } -/* Returns a float in the range [0,1) */ -inline float random_float(int32_t thread_id = 0) -{ - return pcg32_random_r(&pcg_table[thread_id]) * (1.0 / UINT32_MAX); -} - /* Returns a float in the range [min,max) */ -inline float random_float(float min, float max, int32_t thread_id = 0) +inline float random_float(float min, float max) { - return min + (max-min) * random_float(thread_id); + return min + (max-min) * random_float(); } /* Clamps a value between [min,max] */ diff --git a/vec3.hpp b/vec3.hpp index 2396617..ca7f2c8 100644 --- a/vec3.hpp +++ b/vec3.hpp @@ -66,15 +66,15 @@ struct vec3 { } // Get a vec3 with random components in the range [0,1) - inline static vec3 random(int32_t thread_id = 0) + inline static vec3 random() { - return vec3(random_float(thread_id), random_float(thread_id), random_float(thread_id)); + return vec3(random_float(), random_float(), random_float()); } // Get a vec3 with random components in the range [min, max) - inline static vec3 random(float min, float max, int32_t thread_id = 0) + inline static vec3 random(float min, float max) { - return vec3(random_float(min, max, thread_id), random_float(min, max, thread_id), random_float(min, max, thread_id)); + return vec3(random_float(min, max), random_float(min, max), random_float(min, max)); } // Check if all vector components are near zero @@ -162,12 +162,12 @@ inline vec3 normalize(const vec3 v) } // Returns a vec3 of random components between [-1,1) that is inside a unit sphere -vec3 random_in_unit_sphere(int32_t thread_id) +vec3 random_in_unit_sphere() { // Iterate until we find a vector with length < 1 while (true) { - vec3 p = vec3::random(-1,1, thread_id); + vec3 p = vec3::random(-1,1); if (p.length_squared() >= 1) continue; return p; @@ -175,14 +175,14 @@ vec3 random_in_unit_sphere(int32_t thread_id) } // Returns a normalized version of the above vector -vec3 random_unit_vector(int32_t thread_id) +vec3 random_unit_vector() { - return normalize(random_in_unit_sphere(thread_id)); + return normalize(random_in_unit_sphere()); } -vec3 random_in_hemisphere(const vec3& normal, int32_t thread_id) +vec3 random_in_hemisphere(const vec3& normal) { - vec3 in_unit_sphere = random_in_unit_sphere(thread_id); + vec3 in_unit_sphere = random_in_unit_sphere(); if (dot(in_unit_sphere, normal) > 0.0) return in_unit_sphere; @@ -204,11 +204,11 @@ vec3 refract(const vec3& uv, const vec3& n, float etai_over_etat) return r_out_perp + r_out_parallel; } -vec3 random_in_unit_disk(int32_t thread_id) +vec3 random_in_unit_disk() { while (true) { - auto p = vec3(random_float(-1,1,thread_id), random_float(-1,1,thread_id), 0); + auto p = vec3(random_float(-1,1), random_float(-1,1), 0); if (p.length_squared() >= 1) continue; return p; }