From ec40eb11c13f14f18019ea0d801f25054cf34532 Mon Sep 17 00:00:00 2001 From: Moritz Gmeiner Date: Fri, 29 Dec 2023 10:59:06 +0100 Subject: [PATCH] added Philox random gen --- .gitmodules | 3 +++ meson.build | 9 +++++-- src/main.cc | 12 +++++----- src/rand.h | 58 +++++++++++++++++++++++----------------------- src/renderer.h | 19 +++++++++------ subprojects/philox | 1 + 6 files changed, 58 insertions(+), 44 deletions(-) create mode 100644 .gitmodules create mode 160000 subprojects/philox diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d9e77f8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "subprojects/philox"] + path = subprojects/philox + url = git@github.com:MorizzG/philox diff --git a/meson.build b/meson.build index 23ab233..dbf7d53 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project('ray-tracer', 'cpp', default_options : [ 'werror=true', 'cpp_std=c++23', 'b_lto=true', - 'b_lto_mode=thin', + # 'b_lto_mode=thin', ]) add_project_arguments( @@ -12,9 +12,14 @@ add_project_arguments( language : 'cpp' ) + +philox_proj = subproject('philox', default_options : ['warning_level=0', 'werror=false']) +philox_dep = philox_proj.get_variable('philox_dep') + + sources = [] subdir('src') inc = include_directories('src') -executable('ray-tracer', sources, include_directories : inc) +executable('ray-tracer', sources, include_directories : inc, dependencies : [philox_dep]) diff --git a/src/main.cc b/src/main.cc index 9eecf53..fc81e8c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -15,18 +15,18 @@ int main(int /* argc */, char* /* argv */[]) { RenderObjectList world; - // world.Add(std::make_shared(Vec3{0, -100.5, -1}, 100)); + world.Add(std::make_shared(Vec3{0, -100.5, -1}, 100)); world.Add(std::make_shared(-Vec3::e_z, 0.5)); // camera - // constexpr f64 aspect_ratio = 16.0 / 9.0; + constexpr f64 aspect_ratio = 16.0 / 9.0; - // constexpr u32 image_width = 800; - // constexpr auto image_height = static_cast(image_width / aspect_ratio); + constexpr u32 image_width = 800; + constexpr auto image_height = static_cast(image_width / aspect_ratio); - constexpr u32 image_width = 1920; - constexpr u32 image_height = 1080; + // constexpr u32 image_width = 1920; + // constexpr u32 image_height = 1080; static_assert(image_height >= 1); diff --git a/src/rand.h b/src/rand.h index 9144fe8..fec80ed 100644 --- a/src/rand.h +++ b/src/rand.h @@ -1,47 +1,47 @@ #pragma once -#include +#include #include "raytracer.h" -class Random { +#include "vec3.h" + +class RandomGen { public: - constexpr explicit Random(u64 j) { - assert(j != v_); + constexpr u64 GenU64() { return philox_.Next(); } + // constexpr u32 GenU32() { return static_cast(GenU64()); } - u_ = j ^ v_; - GenU64(); + constexpr f64 GenUniform() { return philox_.NextF64(); } - v_ = u_; - GenU64(); + constexpr f64 GenUniform(f64 min, f64 max) { return min + (max - min) * GenUniform(); } - w_ = v_; - GenU64(); + constexpr Vec3 GenVec3() { return Vec3{GenUniform(), GenUniform(), GenUniform()}; } + + constexpr Vec3 GenVec3(f64 min, f64 max) { + return Vec3{GenUniform(min, max), GenUniform(min, max), GenUniform(min, max)}; } - constexpr u64 GenU64() { - u_ = u_ * 2862933555777941757ULL + 7046029254386353087ULL; + constexpr Vec3 GenInUnitBall() { + while (true) { + Vec3 v = GenVec3(-1.0, 1.0); - v_ ^= v_ >> 17; - v_ ^= v_ << 31; - v_ ^= v_ >> 8; - - w_ = 4294957665ULL * (w_ & 0xffffffffULL) + (w_ >> 32); - - u64 x = u_ ^ (u_ << 21); - x ^= x >> 35; - x ^= x << 4; - - return (x + v_) ^ w_; + if (v.norm() < 1.0) { + return v; + } + } } - constexpr u32 GenU32() { return static_cast(GenU64()); } + constexpr Vec3 GenOnUnitSphere() { return GenInUnitBall().normed(); } - constexpr f64 GenF64() { return 5.42101086242752217E-20 * static_cast(GenU64()); } + constexpr Vec3 GenOnHemisphere(const Vec3& normal) { + Vec3 v = GenOnUnitSphere(); - constexpr f64 GenF64(f64 min, f64 max) { return min + (max - min) * GenF64(); } + if (dot(v, normal) < 0) { + v = -v; + } + + return v; + } private: - u64 u_ = 0ULL; - u64 v_ = 4101842887655102017ULL; - u64 w_ = 1ULL; + Philox philox_; }; diff --git a/src/renderer.h b/src/renderer.h index b093770..c534af5 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -15,7 +15,7 @@ class Renderer { public: constexpr explicit Renderer(Camera camera, u32 samples_per_pixel = 10) - : camera_{camera}, rand_{0}, samples_per_pixel_{samples_per_pixel} {} + : camera_{camera}, samples_per_pixel_{samples_per_pixel} {} constexpr Image Render(const RenderObject& world) { Image img{camera_.image_width(), camera_.image_height()}; @@ -43,8 +43,8 @@ class Renderer { constexpr Ray SampleRay(u32 i, u32 j) { auto pixel_centre = camera_.PixelToWorld(i, j); - Vec3 random_shift = rand_.GenF64(-0.5, 0.5) * camera_.d_u_pixel() + - rand_.GenF64(-0.5, 0.5) * camera_.d_v_pixel(); + Vec3 random_shift = rand_.GenUniform(-0.5, 0.5) * camera_.d_u_pixel() + + rand_.GenUniform(-0.5, 0.5) * camera_.d_v_pixel(); pixel_centre += random_shift; @@ -53,17 +53,22 @@ class Renderer { return Ray{camera_.centre(), ray_direction}; } - static constexpr Colour Cast(const Ray& ray, const RenderObject& world) { + constexpr Colour Cast(const Ray& ray, const RenderObject& world) { auto hit_record = world.hit(ray, Interval::kPositive); if (hit_record.has_value()) { - Vec3 n = hit_record->normal; + Vec3 normal = hit_record->normal; if (!hit_record->front_face) { return Colour::kBlack; } - return Colour{0.5 * (n + Vec3{1, 1, 1})}; + Vec3 new_origin = hit_record->p; + Vec3 new_direction = rand_.GenOnHemisphere(normal); + + Ray new_ray{new_origin, new_direction}; + + return 0.5 * Cast(new_ray, world); } auto unit_dir = ray.direction().normed(); @@ -75,7 +80,7 @@ class Renderer { Camera camera_; - Random rand_; + RandomGen rand_{}; u32 samples_per_pixel_; }; diff --git a/subprojects/philox b/subprojects/philox new file mode 160000 index 0000000..cf69284 --- /dev/null +++ b/subprojects/philox @@ -0,0 +1 @@ +Subproject commit cf69284bd2d82b279c34fb1cf90543fd04b3a038