From b7700385295fbaa41ebf49e58507bae7a226fd47 Mon Sep 17 00:00:00 2001 From: PoneyUHC Date: Thu, 11 Jul 2024 01:27:51 +0200 Subject: [PATCH 1/7] move utils to cpp because of include loop --- src/utils.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils.hpp | 52 ++++++++------------------------------------------- 2 files changed, 59 insertions(+), 44 deletions(-) create mode 100644 src/utils.cpp diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..4457fea --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,51 @@ + +#include "utils.hpp" + +#include "vec.hpp" + +#include + + +int lerp(int start, int stop, double value) +{ + return int((1-value) * start + value * stop); +} + + +double lerp(double start, double stop, double value) +{ + return (1-value) * start + value * stop; +} + + +Vec3 lerp(const Vec3& start, const Vec3& stop, double value) +{ + return start * (1-value) + stop * value; +} + + +double degrees_to_radians(double degrees) +{ + return degrees * M_PI / 180.0; +} + + +double random_double() +{ + static std::uniform_real_distribution distribution(0.0, 1.0); + static std::mt19937 generator; + return distribution(generator); +} + + +double random_double(double min, double max) +{ + static std::uniform_real_distribution distribution(min, max); + static std::mt19937 generator; + return distribution(generator); +} + +Vec3 sample_in_unit_square() +{ + return Vec3(random_double() - 0.5, random_double() - 0.5, 0); +} diff --git a/src/utils.hpp b/src/utils.hpp index ff7d260..06d5953 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -1,51 +1,15 @@ #pragma once -#include "vec.hpp" -#include +class Vec3; -inline int lerp(int start, int stop, double value) -{ - return int((1-value) * start + value * stop); -} +int lerp(int start, int stop, double value); +double lerp(double start, double stop, double value); +Vec3 lerp(const Vec3& start, const Vec3& stop, double value); +double degrees_to_radians(double degrees); +double random_double(); +double random_double(double min, double max); +Vec3 sample_in_unit_square(); - -inline double lerp(double start, double stop, double value) -{ - return (1-value) * start + value * stop; -} - - -inline Vec3 lerp(const Vec3& start, const Vec3& stop, double value) -{ - return start * (1-value) + stop * value; -} - - -inline double degrees_to_radians(double degrees) -{ - return degrees * M_PI / 180.0; -} - - -inline double random_double() -{ - static std::uniform_real_distribution distribution(0.0, 1.0); - static std::mt19937 generator; - return distribution(generator); -} - - -inline double random_double(double min, double max) -{ - static std::uniform_real_distribution distribution(min, max); - static std::mt19937 generator; - return distribution(generator); -} - -inline Vec3 sample_in_unit_square() -{ - return Vec3(random_double() - 0.5, random_double() - 0.5, 0); -} From efba30ea59b486e06c51dfc4de53c2256b0fd7aa Mon Sep 17 00:00:00 2001 From: PoneyUHC Date: Thu, 11 Jul 2024 01:32:12 +0200 Subject: [PATCH 2/7] add materials --- src/geometry/IHittable.hpp | 5 ++++- src/geometry/sphere.cpp | 1 + src/geometry/sphere.hpp | 6 +++++- src/main.cpp | 17 ++++++++++++++-- src/material/lambertian.cpp | 27 +++++++++++++++++++++++++ src/material/lambertian.hpp | 25 +++++++++++++++++++++++ src/material/material.hpp | 27 +++++++++++++++++++++++++ src/material/metal.cpp | 18 +++++++++++++++++ src/material/metal.hpp | 25 +++++++++++++++++++++++ src/ray.hpp | 1 + src/renderer/pathtracing_renderer.cpp | 11 +++++++--- src/vec.hpp | 29 +++++++++++++++++++-------- 12 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 src/material/lambertian.cpp create mode 100644 src/material/lambertian.hpp create mode 100644 src/material/material.hpp create mode 100644 src/material/metal.cpp create mode 100644 src/material/metal.hpp diff --git a/src/geometry/IHittable.hpp b/src/geometry/IHittable.hpp index 594b1c8..14d5676 100644 --- a/src/geometry/IHittable.hpp +++ b/src/geometry/IHittable.hpp @@ -8,7 +8,8 @@ #include -class IHittable; +class IHittable; +class Material; struct HitRecord { @@ -17,6 +18,7 @@ struct HitRecord { double t; bool front_face; std::shared_ptr object; + std::shared_ptr material; void SetFaceNormal(const Ray& ray, const Vec3& outwardNormal) @@ -28,6 +30,7 @@ struct HitRecord { }; +// REFACTOR: create a subclass for IHittable (Mesh for example), that is a hittable that has a material class IHittable { public: diff --git a/src/geometry/sphere.cpp b/src/geometry/sphere.cpp index df9045a..fcdf709 100644 --- a/src/geometry/sphere.cpp +++ b/src/geometry/sphere.cpp @@ -39,6 +39,7 @@ bool Sphere::Hit(const Ray& ray, const Interval& interval, HitRecord& outRecord) outRecord.hitPoint = ray.At(root); Vec3 outwardNormal = (outRecord.hitPoint - m_center) / m_radius; outRecord.SetFaceNormal(ray, outwardNormal); + outRecord.material = m_material; return true; } \ No newline at end of file diff --git a/src/geometry/sphere.hpp b/src/geometry/sphere.hpp index 38c8da8..aa95d4f 100644 --- a/src/geometry/sphere.hpp +++ b/src/geometry/sphere.hpp @@ -4,17 +4,21 @@ #include "geometry/IHittable.hpp" +class Material; + + class Sphere : public IHittable { private: Point3 m_center; double m_radius; + std::shared_ptr m_material; public: - Sphere(const Point3& center, double radius) : m_center{center}, m_radius{radius} {}; + Sphere(const Point3& center, double radius, std::shared_ptr material) : m_center{center}, m_radius{radius}, m_material{material} {}; bool Hit(const Ray& ray, const Interval& interval, HitRecord& outRecord) const override; diff --git a/src/main.cpp b/src/main.cpp index 949688c..fc386bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,8 @@ #include "utils.hpp" #include "geometry/sphere.hpp" #include "geometry/scene.hpp" +#include "material/lambertian.hpp" +#include "material/metal.hpp" #include #include @@ -30,11 +32,22 @@ int main(int argc, char *argv[]){ auto camera = make_shared(cameraPosition, aspectRatio, width, focalLength); int height = camera->ImageHeight(); + auto material_ground = make_shared(RGBColor(0.8, 0.8, 0.0)); + auto material_center = make_shared(RGBColor(0.1, 0.2, 0.5)); + auto material_left = make_shared(RGBColor(0.8, 0.8, 0.8)); + auto material_right = make_shared(RGBColor(0.8, 0.6, 0.2)); + auto scene = make_shared(); - auto sphere1 = make_shared(Point3(0,0,-1), 0.5); - auto sphere2 = make_shared(Point3(0,-100.5,-1), 100); + + auto sphere1 = make_shared(Point3( 0.0, -100.5, -1.0), 100.0, material_ground); + auto sphere2 = make_shared(Point3( 0.0, 0.0, -1.2), 0.5, material_center); + auto sphere3 = make_shared(Point3(-1.0, 0.0, -1.0), 0.5, material_left); + auto sphere4 = make_shared(Point3( 1.0, 0.0, -1.0), 0.5, material_right); + scene->AddObject(sphere1); scene->AddObject(sphere2); + scene->AddObject(sphere3); + scene->AddObject(sphere4); PathTracingRendererParams params; params.aa_sample_per_pixel = 20; diff --git a/src/material/lambertian.cpp b/src/material/lambertian.cpp new file mode 100644 index 0000000..53d1006 --- /dev/null +++ b/src/material/lambertian.cpp @@ -0,0 +1,27 @@ + +#include "lambertian.hpp" + +#include "vec.hpp" +#include "geometry/IHittable.hpp" + + +using namespace std; + + +bool Lambertian::Scatter( + const Ray& incoming_ray, + const HitRecord& rec, + RGBColor& attenuation, + Ray& scattered_ray +) const +{ + Vec3 scatter_direction = rec.normal + Vec3::RandomUnitVector(); + + if (scatter_direction.IsNearZero()){ + scatter_direction = rec.normal; + } + + scattered_ray = Ray(rec.hitPoint, scatter_direction); + attenuation = m_albedo; + return true; +} \ No newline at end of file diff --git a/src/material/lambertian.hpp b/src/material/lambertian.hpp new file mode 100644 index 0000000..b400544 --- /dev/null +++ b/src/material/lambertian.hpp @@ -0,0 +1,25 @@ + +#pragma once + +#include "material/material.hpp" + + +class Lambertian : public Material { + +private: + + RGBColor m_albedo; + + +public: + + Lambertian(const RGBColor& albedo): m_albedo{albedo} {}; + + virtual bool Scatter( + const Ray& incoming_ray, + const HitRecord& rec, + RGBColor& attenuation, + Ray& scattered_ray + ) const override; + +}; \ No newline at end of file diff --git a/src/material/material.hpp b/src/material/material.hpp new file mode 100644 index 0000000..0fcf333 --- /dev/null +++ b/src/material/material.hpp @@ -0,0 +1,27 @@ + +#pragma once + +#include "vec.hpp" + + +class Ray; +class HitRecord; + + +class Material { + +public: + + virtual ~Material() {} + virtual bool Scatter( + const Ray& incoming_ray, + const HitRecord& rec, + RGBColor& attenuation, + Ray& scattered_ray + ) const + { + return false; + } + + +}; \ No newline at end of file diff --git a/src/material/metal.cpp b/src/material/metal.cpp new file mode 100644 index 0000000..a82353b --- /dev/null +++ b/src/material/metal.cpp @@ -0,0 +1,18 @@ + +#include "material/metal.hpp" + +#include "geometry/IHittable.hpp" + + +bool Metal::Scatter( + const Ray& incoming_ray, + const HitRecord& rec, + RGBColor& attenuation, + Ray& scattered_ray +) const +{ + Vec3 reflected = incoming_ray.Direction().Reflect(rec.normal); + scattered_ray = Ray(rec.hitPoint, reflected); + attenuation = m_albedo; + return true; +} \ No newline at end of file diff --git a/src/material/metal.hpp b/src/material/metal.hpp new file mode 100644 index 0000000..ac783e1 --- /dev/null +++ b/src/material/metal.hpp @@ -0,0 +1,25 @@ + +#pragma once + +#include "material/material.hpp" + + +class Metal : public Material { + +private: + + RGBColor m_albedo; + + +public: + + Metal(const RGBColor& albedo): m_albedo{albedo} {}; + + virtual bool Scatter( + const Ray& incoming_ray, + const HitRecord& rec, + RGBColor& attenuation, + Ray& scattered_ray + ) const override; + +}; \ No newline at end of file diff --git a/src/ray.hpp b/src/ray.hpp index 590fa65..00c8f26 100644 --- a/src/ray.hpp +++ b/src/ray.hpp @@ -14,6 +14,7 @@ class Ray { public: + Ray() : m_origin{Point3(0,0,0)}, m_direction{Vec3(0,0,0)} {}; Ray(const Point3& origin, const Vec3& direction) : m_origin{origin}, m_direction{direction} {}; inline Point3 At(double time) const { return m_origin + m_direction * time; } diff --git a/src/renderer/pathtracing_renderer.cpp b/src/renderer/pathtracing_renderer.cpp index 5cd03dc..2e424a3 100644 --- a/src/renderer/pathtracing_renderer.cpp +++ b/src/renderer/pathtracing_renderer.cpp @@ -1,6 +1,8 @@ #include "renderer/pathtracing_renderer.hpp" #include "utils.hpp" +#include "material/material.hpp" +#include "vec.hpp" #include @@ -50,9 +52,12 @@ RGBColor PathTracingRenderer::GetRayColor(const Ray& ray, size_t depth) HitRecord hitRecord; if( m_scene->Hit(ray, Interval(0.001, INFINITY), hitRecord) ){ - Vec3 bounce_direction = hitRecord.normal + Vec3::RandomUnitVector(); - Ray newRay = Ray(hitRecord.hitPoint, bounce_direction); - return 0.5 * GetRayColor(newRay, depth-1); + Ray scattered_ray; + RGBColor attenuation(0, 0, 0); + if (hitRecord.material->Scatter(ray, hitRecord, attenuation, scattered_ray)){ + return attenuation * GetRayColor(scattered_ray, depth-1); + } + return RGBColor(0, 0, 0); } Vec3 unitDirection = ray.Direction().Normalized(); diff --git a/src/vec.hpp b/src/vec.hpp index 4863bc7..fc2cc8d 100644 --- a/src/vec.hpp +++ b/src/vec.hpp @@ -2,12 +2,9 @@ #pragma once #include - #include - -double random_double(); -double random_double(double min, double max); +#include "utils.hpp" class Vec3 { @@ -29,14 +26,16 @@ class Vec3 { Vec3 operator*(double n) const { return Vec3{e[0]*n, e[1]*n, e[2]*n}; } Vec3 operator/(double n) const { return Vec3{e[0]/n, e[1]/n, e[2]/n}; } - Vec3& operator+=(const Vec3& other) { + Vec3& operator+=(const Vec3& other) + { this->e[0] += other.e[0]; this->e[1] += other.e[1]; this->e[2] += other.e[2]; return *this; } - Vec3& operator/=(double n) { + Vec3& operator/=(double n) + { this->e[0] /= n; this->e[1] /= n; this->e[2] /= n; @@ -48,9 +47,21 @@ class Vec3 { inline double MagnitudeSquared() const { return e[0] * e[0] + e[1] * e[1] + e[2] * e[2]; } inline Vec3 Normalized() const { return *this / this->Magnitude(); } + inline bool IsNearZero() const + { + double s = 1e-8; + return (fabs(e[0]) < s) && (fabs(e[1]) < s) && (fabs(e[2]) < s); + } + + inline Vec3 Reflect(const Vec3& normal) + { + return *this - normal*2*this->Dot(normal); + } + // Requieres the current object to be a unit vector - inline Vec3 RandomInSameHemisphere() const { + inline Vec3 RandomInSameHemisphere() const + { Vec3 other = RandomUnitVector(); return other.Dot(*this) > 0.0 ? other : -other; } @@ -59,7 +70,8 @@ class Vec3 { // as the distribution in the square would be uniform, // but not the distribution of the projected vectors on unit-sphere // Thus, we only take vector generated inside the sphere. - static inline Vec3 RandomUnitVector() { + static inline Vec3 RandomUnitVector() + { Vec3 result; while(true){ result = Vec3::Random(-1, 1); @@ -76,6 +88,7 @@ class Vec3 { inline Vec3 operator*(double n, const Vec3& u) { return Vec3{n*u.e[0], n*u.e[1], n*u.e[2]}; } +inline Vec3 operator*(const Vec3& u, const Vec3& v) { return Vec3{u.e[0]*v.e[0], u.e[1]*v.e[1], u.e[2]*v.e[2]}; } typedef Vec3 Point3; From 324ffe65f598e40442c3056f087c01260fdffb2c Mon Sep 17 00:00:00 2001 From: PoneyUHC Date: Thu, 11 Jul 2024 01:36:11 +0200 Subject: [PATCH 3/7] add TODO list --- TODO.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..953b232 --- /dev/null +++ b/TODO.md @@ -0,0 +1,8 @@ + +- Section 10.6 +- reorganize main in different functions +- improve compilation time + - move as much code as possible in .cpp files + - create blobs +- accelerate with GPU compute shaders + - use raytracing extensions if possible \ No newline at end of file From c82ab66c2772fc74dd8c30cee503fa8cc7d33f6f Mon Sep 17 00:00:00 2001 From: PoneyUHC Date: Thu, 11 Jul 2024 15:38:07 +0200 Subject: [PATCH 4/7] Add metal fuziness --- src/main.cpp | 4 ++-- src/material/metal.cpp | 3 ++- src/material/metal.hpp | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fc386bb..637ac26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,8 +34,8 @@ int main(int argc, char *argv[]){ auto material_ground = make_shared(RGBColor(0.8, 0.8, 0.0)); auto material_center = make_shared(RGBColor(0.1, 0.2, 0.5)); - auto material_left = make_shared(RGBColor(0.8, 0.8, 0.8)); - auto material_right = make_shared(RGBColor(0.8, 0.6, 0.2)); + auto material_left = make_shared(RGBColor(0.8, 0.8, 0.8), 0.3); + auto material_right = make_shared(RGBColor(0.8, 0.6, 0.2), 1.0); auto scene = make_shared(); diff --git a/src/material/metal.cpp b/src/material/metal.cpp index a82353b..5e7c683 100644 --- a/src/material/metal.cpp +++ b/src/material/metal.cpp @@ -12,7 +12,8 @@ bool Metal::Scatter( ) const { Vec3 reflected = incoming_ray.Direction().Reflect(rec.normal); + reflected = reflected.Normalized() + (m_fuzziness * Vec3::RandomUnitVector()); scattered_ray = Ray(rec.hitPoint, reflected); attenuation = m_albedo; - return true; + return rec.normal.Dot(reflected) > 0; } \ No newline at end of file diff --git a/src/material/metal.hpp b/src/material/metal.hpp index ac783e1..82742c0 100644 --- a/src/material/metal.hpp +++ b/src/material/metal.hpp @@ -9,11 +9,13 @@ class Metal : public Material { private: RGBColor m_albedo; + double m_fuzziness; public: - Metal(const RGBColor& albedo): m_albedo{albedo} {}; + Metal(const RGBColor& albedo, double fuzziness): + m_albedo{albedo}, m_fuzziness{fuzziness < 1 ? fuzziness : 1} {}; virtual bool Scatter( const Ray& incoming_ray, From d0669137201b7926a2bf09764010b9b96dd2bd57 Mon Sep 17 00:00:00 2001 From: PoneyUHC Date: Thu, 11 Jul 2024 15:39:06 +0200 Subject: [PATCH 5/7] proper init of HitRecord, compilation to -O3 --- Makefile | 2 +- TODO.md | 3 ++- src/geometry/IHittable.hpp | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 5acfb25..1f0470c 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ EXEC_NAME = render.exe OUTPUT_DIR = output SRC_DIR = src SRC = $(wildcard $(SRC_DIR)/*.cpp) $(wildcard $(SRC_DIR)/**/*.cpp) -CFLAGS = -g -Og -Wall -Wpedantic -std=c++17 +CFLAGS = -g -O3 -Wall -Wpedantic -std=c++17 default: render.exe diff --git a/TODO.md b/TODO.md index 953b232..3f7a302 100644 --- a/TODO.md +++ b/TODO.md @@ -5,4 +5,5 @@ - move as much code as possible in .cpp files - create blobs - accelerate with GPU compute shaders - - use raytracing extensions if possible \ No newline at end of file + - use raytracing extensions if possible +- make buildchain crossplatform with CMake \ No newline at end of file diff --git a/src/geometry/IHittable.hpp b/src/geometry/IHittable.hpp index 14d5676..6fdb487 100644 --- a/src/geometry/IHittable.hpp +++ b/src/geometry/IHittable.hpp @@ -15,8 +15,8 @@ struct HitRecord { Point3 hitPoint; Vec3 normal; - double t; - bool front_face; + double t = 0.0; + bool front_face = true; std::shared_ptr object; std::shared_ptr material; From 7a86d966b22f93b71eb6b369aa32ffded4274172 Mon Sep 17 00:00:00 2001 From: PoneyUHC Date: Thu, 11 Jul 2024 15:46:23 +0200 Subject: [PATCH 6/7] split main in init functions --- TODO.md | 3 +-- src/main.cpp | 49 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/TODO.md b/TODO.md index 3f7a302..ceb4a6e 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,5 @@ -- Section 10.6 -- reorganize main in different functions +- Section 11 - improve compilation time - move as much code as possible in .cpp files - create blobs diff --git a/src/main.cpp b/src/main.cpp index 637ac26..66b3aab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,48 +15,65 @@ using namespace std; -int main(int argc, char *argv[]){ - - if (argc != 2){ - cout << "Usage : " << argv[0] << " width" << endl; - return 1; - } - - int width = atoi(argv[1]); - - +shared_ptr InitCamera(int width) +{ Point3 cameraPosition = Point3{0,0,0}; double aspectRatio = 16.0 / 9.0; double focalLength = 1.0; - auto camera = make_shared(cameraPosition, aspectRatio, width, focalLength); - int height = camera->ImageHeight(); + return make_shared(cameraPosition, aspectRatio, width, focalLength); +} + +shared_ptr InitScene() +{ auto material_ground = make_shared(RGBColor(0.8, 0.8, 0.0)); auto material_center = make_shared(RGBColor(0.1, 0.2, 0.5)); auto material_left = make_shared(RGBColor(0.8, 0.8, 0.8), 0.3); auto material_right = make_shared(RGBColor(0.8, 0.6, 0.2), 1.0); - auto scene = make_shared(); - auto sphere1 = make_shared(Point3( 0.0, -100.5, -1.0), 100.0, material_ground); auto sphere2 = make_shared(Point3( 0.0, 0.0, -1.2), 0.5, material_center); auto sphere3 = make_shared(Point3(-1.0, 0.0, -1.0), 0.5, material_left); auto sphere4 = make_shared(Point3( 1.0, 0.0, -1.0), 0.5, material_right); + auto scene = make_shared(); scene->AddObject(sphere1); scene->AddObject(sphere2); scene->AddObject(sphere3); scene->AddObject(sphere4); + return scene; +} + + +PathTracingRenderer InitRenderer(shared_ptr camera, shared_ptr scene) +{ PathTracingRendererParams params; params.aa_sample_per_pixel = 20; params.max_depth = 5; - PathTracingRenderer renderer(camera, scene, std::move(params)); + + return PathTracingRenderer(camera, scene, std::move(params)); +} + + +int main(int argc, char *argv[]){ + + if (argc != 2){ + cout << "Usage : " << argv[0] << " width" << endl; + return 1; + } + + int width = atoi(argv[1]); + + shared_ptr camera = InitCamera(width); + shared_ptr scene = InitScene(); + + PathTracingRenderer renderer = InitRenderer(camera, scene); renderer.Render(); PpmExporter ppmExporter("output/render.ppm"); - ppmExporter.Export(width, height, renderer.GetBuffer()); + ppmExporter.Export(camera->ImageWidth(), camera->ImageHeight(), renderer.GetBuffer()); return 0; } \ No newline at end of file From 9e530642a047ffd65ed52188e8cbec67944ef1d1 Mon Sep 17 00:00:00 2001 From: PoneyUHC Date: Thu, 11 Jul 2024 16:18:48 +0200 Subject: [PATCH 7/7] clean dependency tree, reduce compile time --- src/camera.cpp | 12 ++++-------- src/camera.hpp | 6 +----- src/export/ppm_exporter.cpp | 6 +++--- src/geometry/IHittable.cpp | 11 +++++++++++ src/geometry/IHittable.hpp | 12 ++++-------- src/geometry/scene.cpp | 2 ++ src/geometry/scene.hpp | 1 + src/geometry/sphere.cpp | 3 +++ src/interval.cpp | 3 +++ src/interval.hpp | 2 -- src/material/lambertian.cpp | 1 + src/material/metal.cpp | 1 + src/ray.cpp | 7 +++++++ src/ray.hpp | 2 +- src/renderer/pathtracing_renderer.cpp | 6 +++++- src/renderer/pathtracing_renderer.hpp | 7 +++++-- src/vec.hpp | 21 ++++++++++----------- 17 files changed, 62 insertions(+), 41 deletions(-) create mode 100644 src/geometry/IHittable.cpp diff --git a/src/camera.cpp b/src/camera.cpp index 0162d00..54a6220 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -25,12 +25,8 @@ Camera::Camera(const Point3& camera_center, double aspect_ratio, int width, doub } -std::optional Camera::GetPixelPosition(int i, int j) const +Vec3 Camera::GetPixelPosition(int i, int j) const { - if(i < 0 || i >= m_image_width || j < 0 || j >= m_image_width) { - return std::nullopt; - } - return m_pixel00_loc + m_pixel_delta_u * i + m_pixel_delta_v * j; } @@ -39,9 +35,9 @@ Vec3 Camera::SamplePositionAroundPixel(int i, int j) const { Vec3 offset = sample_in_unit_square(); - Vec3 samplePosition = GetPixelPosition(i, j).value() - + offset.x() * m_pixel_delta_u - + offset.y() * m_pixel_delta_v; + Vec3 samplePosition = GetPixelPosition(i, j) + + offset.X() * m_pixel_delta_u + + offset.Y() * m_pixel_delta_v; return samplePosition; } \ No newline at end of file diff --git a/src/camera.hpp b/src/camera.hpp index 7feb7bc..8f3d944 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -2,10 +2,6 @@ #pragma once #include "vec.hpp" -#include "ray.hpp" -#include "utils.hpp" - -#include class Camera { @@ -40,7 +36,7 @@ class Camera { inline double ImageWidth() const { return m_image_width; } inline Point3 CameraCenter() const { return m_camera_center; } - std::optional GetPixelPosition(int i, int j) const; + Point3 GetPixelPosition(int i, int j) const; Vec3 SamplePositionAroundPixel(int i, int j) const; diff --git a/src/export/ppm_exporter.cpp b/src/export/ppm_exporter.cpp index 237e76d..efc4e82 100644 --- a/src/export/ppm_exporter.cpp +++ b/src/export/ppm_exporter.cpp @@ -32,9 +32,9 @@ int PpmExporter::Export(int width, int height, std::shared_ptr buffe for(int i=0; i class IHittable; class Material; +class Interval; +class Ray; + struct HitRecord { @@ -21,12 +22,7 @@ struct HitRecord { std::shared_ptr material; - void SetFaceNormal(const Ray& ray, const Vec3& outwardNormal) - { - front_face = ray.Direction().Dot(outwardNormal) < 0.0; - normal = front_face ? outwardNormal : -outwardNormal; - } - + void SetFaceNormal(const Ray& ray, const Vec3& outwardNormal); }; diff --git a/src/geometry/scene.cpp b/src/geometry/scene.cpp index 88fc049..2a2038f 100644 --- a/src/geometry/scene.cpp +++ b/src/geometry/scene.cpp @@ -1,6 +1,8 @@ #include "geometry/scene.hpp" +#include "interval.hpp" + using namespace std; diff --git a/src/geometry/scene.hpp b/src/geometry/scene.hpp index 4dd2e19..7567570 100644 --- a/src/geometry/scene.hpp +++ b/src/geometry/scene.hpp @@ -6,6 +6,7 @@ #include #include + class Scene : public IHittable { private: diff --git a/src/geometry/sphere.cpp b/src/geometry/sphere.cpp index fcdf709..bf46758 100644 --- a/src/geometry/sphere.cpp +++ b/src/geometry/sphere.cpp @@ -1,6 +1,9 @@ #include "sphere.hpp" +#include "ray.hpp" +#include "interval.hpp" + #include diff --git a/src/interval.cpp b/src/interval.cpp index e8f1fb0..732722f 100644 --- a/src/interval.cpp +++ b/src/interval.cpp @@ -1,5 +1,8 @@ #include "interval.hpp" +#include + + const Interval Interval::Empty = Interval(INFINITY, -INFINITY); const Interval Interval::Universe = Interval(-INFINITY, INFINITY); \ No newline at end of file diff --git a/src/interval.hpp b/src/interval.hpp index f6f8137..e226af5 100644 --- a/src/interval.hpp +++ b/src/interval.hpp @@ -1,8 +1,6 @@ #pragma once -#include - class Interval { diff --git a/src/material/lambertian.cpp b/src/material/lambertian.cpp index 53d1006..6b11782 100644 --- a/src/material/lambertian.cpp +++ b/src/material/lambertian.cpp @@ -2,6 +2,7 @@ #include "lambertian.hpp" #include "vec.hpp" +#include "ray.hpp" #include "geometry/IHittable.hpp" diff --git a/src/material/metal.cpp b/src/material/metal.cpp index 5e7c683..7593429 100644 --- a/src/material/metal.cpp +++ b/src/material/metal.cpp @@ -1,6 +1,7 @@ #include "material/metal.hpp" +#include "ray.hpp" #include "geometry/IHittable.hpp" diff --git a/src/ray.cpp b/src/ray.cpp index c86cd11..6a60778 100644 --- a/src/ray.cpp +++ b/src/ray.cpp @@ -1,3 +1,10 @@ #include "ray.hpp" +#include "vec.hpp" + + +Point3 Ray::At(double time) const +{ + return m_origin + m_direction * time; +} \ No newline at end of file diff --git a/src/ray.hpp b/src/ray.hpp index 00c8f26..256662f 100644 --- a/src/ray.hpp +++ b/src/ray.hpp @@ -17,7 +17,7 @@ class Ray { Ray() : m_origin{Point3(0,0,0)}, m_direction{Vec3(0,0,0)} {}; Ray(const Point3& origin, const Vec3& direction) : m_origin{origin}, m_direction{direction} {}; - inline Point3 At(double time) const { return m_origin + m_direction * time; } + Point3 At(double time) const; inline Vec3 Direction() const { return m_direction; } inline Point3 Origin() const { return m_origin; } diff --git a/src/renderer/pathtracing_renderer.cpp b/src/renderer/pathtracing_renderer.cpp index 2e424a3..b502c8b 100644 --- a/src/renderer/pathtracing_renderer.cpp +++ b/src/renderer/pathtracing_renderer.cpp @@ -3,6 +3,10 @@ #include "utils.hpp" #include "material/material.hpp" #include "vec.hpp" +#include "ray.hpp" +#include "camera.hpp" +#include "geometry/scene.hpp" +#include "interval.hpp" #include @@ -61,7 +65,7 @@ RGBColor PathTracingRenderer::GetRayColor(const Ray& ray, size_t depth) } Vec3 unitDirection = ray.Direction().Normalized(); - double a = 0.5 * (unitDirection.y() + 1.0); + double a = 0.5 * (unitDirection.Y() + 1.0); return lerp(RGBColor(1.0, 1.0, 1.0), RGBColor(0.5, 0.7, 1.0), a); } diff --git a/src/renderer/pathtracing_renderer.hpp b/src/renderer/pathtracing_renderer.hpp index f1d0bc8..01ed24d 100644 --- a/src/renderer/pathtracing_renderer.hpp +++ b/src/renderer/pathtracing_renderer.hpp @@ -2,8 +2,11 @@ #pragma once #include "renderer/IRenderer.hpp" -#include "geometry/scene.hpp" -#include "camera.hpp" + + +class Camera; +class Scene; +class Ray; struct PathTracingRendererParams { diff --git a/src/vec.hpp b/src/vec.hpp index fc2cc8d..e10a835 100644 --- a/src/vec.hpp +++ b/src/vec.hpp @@ -2,7 +2,6 @@ #pragma once #include -#include #include "utils.hpp" @@ -16,17 +15,17 @@ class Vec3 { Vec3() : e{0,0,0} {} Vec3(double x, double y, double z): e{x,y,z} {} - double x() const { return e[0]; } - double y() const { return e[1]; } - double z() const { return e[2]; } + inline double X() const { return e[0]; } + inline double Y() const { return e[1]; } + inline double Z() const { return e[2]; } - Vec3 operator+(const Vec3& other) const { return Vec3{e[0]+other.e[0], e[1]+other.e[1], e[2]+other.e[2]}; } - Vec3 operator-() const { return Vec3{-e[0], -e[1], -e[2]}; } - Vec3 operator-(const Vec3& other) const { return Vec3{e[0]-other.e[0], e[1]-other.e[1], e[2]-other.e[2]}; } - Vec3 operator*(double n) const { return Vec3{e[0]*n, e[1]*n, e[2]*n}; } - Vec3 operator/(double n) const { return Vec3{e[0]/n, e[1]/n, e[2]/n}; } + inline Vec3 operator+(const Vec3& other) const { return Vec3{e[0]+other.e[0], e[1]+other.e[1], e[2]+other.e[2]}; } + inline Vec3 operator-() const { return Vec3{-e[0], -e[1], -e[2]}; } + inline Vec3 operator-(const Vec3& other) const { return Vec3{e[0]-other.e[0], e[1]-other.e[1], e[2]-other.e[2]}; } + inline Vec3 operator*(double n) const { return Vec3{e[0]*n, e[1]*n, e[2]*n}; } + inline Vec3 operator/(double n) const { return Vec3{e[0]/n, e[1]/n, e[2]/n}; } - Vec3& operator+=(const Vec3& other) + inline Vec3& operator+=(const Vec3& other) { this->e[0] += other.e[0]; this->e[1] += other.e[1]; @@ -34,7 +33,7 @@ class Vec3 { return *this; } - Vec3& operator/=(double n) + inline Vec3& operator/=(double n) { this->e[0] /= n; this->e[1] /= n;