From c062e6107a03960f56466d1637df9d873ecfede9 Mon Sep 17 00:00:00 2001 From: Moritz Gmeiner Date: Fri, 5 Jan 2024 00:43:17 +0100 Subject: [PATCH] removed all mutable update code from Camera, now Update() needs to be called manually made Renderer methods const, so redner threads cannot accidentally step on each others feet --- src/camera.h | 87 +++++++++++--------------------------------------- src/renderer.h | 13 ++++---- 2 files changed, 26 insertions(+), 74 deletions(-) diff --git a/src/camera.h b/src/camera.h index c2871c8..2a052f2 100644 --- a/src/camera.h +++ b/src/camera.h @@ -8,10 +8,8 @@ class Camera { public: - constexpr Camera(Point3 centre, u32 image_width, u32 image_height) - : centre_{centre}, image_width_{image_width}, image_height_{image_height} { - Update(); - } + constexpr Camera(u32 image_width, u32 image_height) + : image_width_{image_width}, image_height_{image_height} {} // change paramters @@ -20,8 +18,6 @@ class Camera { centre_ = centre; focal_length_ = (look_at_ - centre_).norm(); - - need_update_ = true; } constexpr Point3 look_at() const { return look_at_; } @@ -29,69 +25,33 @@ class Camera { look_at_ = look_at; focal_length_ = (look_at_ - centre_).norm(); - - need_update_ = true; } constexpr Vec3 up() const { return up_; } - constexpr void up(Vec3 up) { - up_ = up; - - need_update_ = true; - } + constexpr void up(Vec3 up) { up_ = up; } constexpr f64 fov() const { return fov_; } - constexpr void fov(f64 fov) { - fov_ = fov; - - need_update_ = true; - } + constexpr void fov(f64 fov) { fov_ = fov; } constexpr f64 focal_length() const { return focal_length_; } - constexpr void focal_length(f64 focal_length) { - focal_length_ = focal_length; - - need_update_ = true; - } + constexpr void focal_length(f64 focal_length) { focal_length_ = focal_length; } constexpr f64 defocus_angle() const { return defocus_angle_; } constexpr void defocus_angle(f64 defocus_angle) { defocus_angle_ = defocus_angle; } // const-only accessors - constexpr Vec3 u() const { - Update(); + constexpr Vec3 u() const { return u_; } + constexpr Vec3 v() const { return v_; } + constexpr Vec3 w() const { return w_; } - return u_; - } - constexpr Vec3 v() const { - Update(); - - return v_; - } - constexpr Vec3 w() const { - Update(); - - return w_; - } - - constexpr Vec3 d_u_pixel() const { - Update(); - - return d_u_pixel_; - } - constexpr Vec3 d_v_pixel() const { - Update(); - - return d_v_pixel_; - } + constexpr Vec3 d_u_pixel() const { return d_u_pixel_; } + constexpr Vec3 d_v_pixel() const { return d_v_pixel_; } constexpr u32 image_width() const { return image_width_; } constexpr u32 image_height() const { return image_height_; } constexpr Vec3 PixelToWorld(f64 i, f64 j) const { - Update(); - return pixel_00_ + i * d_u_pixel_ + j * d_v_pixel_; } @@ -112,13 +72,7 @@ class Camera { u_ = u; v_ = v; } - - private: - constexpr void Update() const { - if (!need_update_) { - return; - } - + constexpr void Update() { f64 aspect_ratio = static_cast(image_width_) / image_height_; w_ = -(look_at_ - centre_).normed(); @@ -148,10 +102,9 @@ class Camera { auto viewport_upper_left = centre_ - u_viewport / 2 - v_viewport / 2 - focal_length_ * w_; pixel_00_ = viewport_upper_left + 0.5 * d_u_pixel_ + 0.5 * d_v_pixel_; - - need_update_ = false; } + private: // fundamental camera parameters Point3 centre_ = -Point3::e_z; @@ -164,20 +117,18 @@ class Camera { // saved camera properties, need to be recalculated after updating parameters - mutable bool need_update_ = true; + Vec3 u_ = Vec3::e_x; // points to right of camera + Vec3 v_ = Vec3::e_y; // points to up of camera + Vec3 w_ = Vec3::e_z; // points backward of camera - mutable Vec3 u_ = Vec3::e_x; // points to right of camera - mutable Vec3 v_ = Vec3::e_y; // points to up of camera - mutable Vec3 w_ = Vec3::e_z; // points backward of camera - - mutable f64 focal_length_ = 1.0; + f64 focal_length_ = 1.0; // position of pixel 0, 0 - mutable Vec3 pixel_00_; + Vec3 pixel_00_; // Vec3 pointing from pixel to right/lower neighbour resp. - mutable Vec3 d_u_pixel_; - mutable Vec3 d_v_pixel_; + Vec3 d_u_pixel_; + Vec3 d_v_pixel_; // const diff --git a/src/renderer.h b/src/renderer.h index f932c60..5a60b68 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -31,7 +31,7 @@ class Renderer { constexpr u32& max_bounces() { return max_bounces_; } constexpr u32 max_bounces() const { return max_bounces_; } - Image Render(const RenderObject& world) { + Image Render(const RenderObject& world) const { Image img{camera_.image_width(), camera_.image_height()}; constexpr u32 kNumThreads = 16; @@ -90,26 +90,27 @@ class Renderer { } private: - Ray SampleRay(u32 i, u32 j) { + Ray SampleRay(u32 i, u32 j) const { auto& rand = RandomGen::GenInstance(); auto ray_origin = camera_.centre(); /* if (camera_.defocus_angle() > 0) { - ray_origin += camera_.defocus_radius() * rand.UnitDiskVec3(camera_.w()); + Vec3 r = rand.UnitDiskVec3(); + ray_origin += camera_.defocus_radius() * (r.x() * camera_.u() + r.y() * camera_.v()); } */ f64 x_dist = rand.Uniform(-0.5, 0.5); f64 y_dist = rand.Uniform(-0.5, 0.5); - auto pixel_centre = camera_.PixelToWorld(i + x_dist, j + y_dist); + auto ray_target = camera_.PixelToWorld(i + x_dist, j + y_dist); - auto ray_direction = pixel_centre - camera_.centre(); + auto ray_direction = ray_target - camera_.centre(); return Ray{ray_origin, ray_direction}; } - constexpr Colour Cast(const Ray& ray, const RenderObject& world, u32 bounces) { + constexpr Colour Cast(const Ray& ray, const RenderObject& world, u32 bounces) const { auto hit_record = world.hit(ray, Interval{0.001, kInf}); // background