diff --git a/TODO.md b/TODO.md index c39fad5..5979742 100644 --- a/TODO.md +++ b/TODO.md @@ -5,4 +5,5 @@ - centralize asset loading in a resource manager - find a good name for the project - have a format describing scenes instead of code description -- add log system \ No newline at end of file +- add log system +- add render queue \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b19f20f..7bc8aa7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include "scenes/checkered_spheres_scene.hpp" #include "scenes/solar_system_scene.hpp" #include "scenes/quads_scene.hpp" +#include "scenes/cornell_box_scene.hpp" #include "renderer/camera.hpp" #include "export/png_exporter.hpp" @@ -29,7 +30,7 @@ int main(int argc, char *argv[]){ unique_ptr scene; - switch(4){ + switch(5){ case 1: scene = make_unique(); break; @@ -42,6 +43,9 @@ int main(int argc, char *argv[]){ case 4: scene = make_unique(); break; + case 5: + scene = make_unique(); + break; default: cout << "Problem in scene selection" << endl; return 1; diff --git a/src/material/IMaterial.hpp b/src/material/IMaterial.hpp index e13d7ab..f692655 100644 --- a/src/material/IMaterial.hpp +++ b/src/material/IMaterial.hpp @@ -13,6 +13,7 @@ class IMaterial { public: virtual ~IMaterial() {} + virtual bool Scatter( const Ray& incoming_ray, const HitRecord& rec, @@ -23,5 +24,10 @@ class IMaterial { return false; } + virtual RGBColor Emitted(double u, double v, const Point3& point) const + { + return BLACK; + } + }; \ No newline at end of file diff --git a/src/material/diffuse_light.hpp b/src/material/diffuse_light.hpp new file mode 100644 index 0000000..2751ad2 --- /dev/null +++ b/src/material/diffuse_light.hpp @@ -0,0 +1,27 @@ + +#pragma once + +#include + +#include "material/IMaterial.hpp" +#include "texture/solid_color_texture.hpp" + + +class DiffuseLight : public IMaterial { + +private: + + std::shared_ptr m_albedo; + + +public: + + DiffuseLight(const RGBColor& albedo): m_albedo{std::make_shared(albedo)} {}; + DiffuseLight(std::shared_ptr albedo): m_albedo{albedo} {}; + + RGBColor Emitted(double u, double v, const Point3& point) const override + { + return m_albedo->GetColor(u, v, point); + } + +}; \ No newline at end of file diff --git a/src/math/vec.hpp b/src/math/vec.hpp index 076c795..2636869 100644 --- a/src/math/vec.hpp +++ b/src/math/vec.hpp @@ -106,4 +106,6 @@ inline Vec3 operator*(const Vec3& u, const Vec3& v) { return Vec3{u.e[0]*v.e[0], typedef Vec3 Point3; -typedef Vec3 RGBColor; \ No newline at end of file +typedef Vec3 RGBColor; +inline const RGBColor BLACK = RGBColor(0.0, 0.0, 0.0); +inline const RGBColor WHITE = RGBColor(1.0, 1.0, 1.0); \ No newline at end of file diff --git a/src/renderer/camera.hpp b/src/renderer/camera.hpp index 213315e..6dc10b1 100644 --- a/src/renderer/camera.hpp +++ b/src/renderer/camera.hpp @@ -53,7 +53,8 @@ class Camera { double m_defocus_angle; double m_focus_dist; - Vec3 m_defocus_disk_u; // Defocus disk horizontal radius + // Defocus disk horizontal radius + Vec3 m_defocus_disk_u; Vec3 m_defocus_disk_v; diff --git a/src/renderer/pathtracing_renderer.cpp b/src/renderer/pathtracing_renderer.cpp index ca7acb7..21747f5 100644 --- a/src/renderer/pathtracing_renderer.cpp +++ b/src/renderer/pathtracing_renderer.cpp @@ -91,22 +91,25 @@ void PathTracingRenderer::Render() { RGBColor PathTracingRenderer::GetRayColor(const Ray& ray, size_t depth) { - if(depth == 0){ - return RGBColor(0, 0, 0); + if(depth <= 0){ + return BLACK; } - HitRecord hitRecord; - Interval interval = Interval(0.001, INFINITY); - if( m_scene->Hit(ray, interval, hitRecord) ){ - 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); + HitRecord hit_record; + static Interval interval = Interval(0.001, INFINITY); + if(!m_scene->Hit(ray, interval, hit_record)){ + return m_params.background_color; } - Vec3 unitDirection = ray.Direction().Normalized(); - double a = 0.5 * (unitDirection[1] + 1.0); - return lerp(RGBColor(1.0, 1.0, 1.0), RGBColor(0.5, 0.7, 1.0), a); + Ray scattered_ray; + RGBColor attenuation = BLACK; + RGBColor color_from_emission = hit_record.material->Emitted(hit_record.u, hit_record.v, hit_record.hit_point); + + if (!hit_record.material->Scatter(ray, hit_record, attenuation, scattered_ray)){ + return color_from_emission; + } + + RGBColor color_from_scatter = attenuation * GetRayColor(scattered_ray, depth-1); + + return color_from_emission + color_from_scatter; } \ No newline at end of file diff --git a/src/renderer/pathtracing_renderer.hpp b/src/renderer/pathtracing_renderer.hpp index 5529ae4..be86902 100644 --- a/src/renderer/pathtracing_renderer.hpp +++ b/src/renderer/pathtracing_renderer.hpp @@ -12,6 +12,7 @@ class Ray; struct PathTracingRendererParams { int aa_sample_per_pixel; int max_depth; + RGBColor background_color; }; diff --git a/src/scenes/checkered_spheres_scene.cpp b/src/scenes/checkered_spheres_scene.cpp index f300bfa..060f15e 100644 --- a/src/scenes/checkered_spheres_scene.cpp +++ b/src/scenes/checkered_spheres_scene.cpp @@ -58,6 +58,7 @@ shared_ptr CheckeredSpheresScene::InitRenderer() PathTracingRendererParams params; params.aa_sample_per_pixel = 100; params.max_depth = 20; + params.background_color = RGBColor(0.70, 0.80, 1.00); return make_shared(m_camera, m_objets, move(params)); } diff --git a/src/scenes/cornell_box_scene.cpp b/src/scenes/cornell_box_scene.cpp new file mode 100644 index 0000000..0978b5b --- /dev/null +++ b/src/scenes/cornell_box_scene.cpp @@ -0,0 +1,81 @@ + +#include "cornell_box_scene.hpp" + +#include "geometry/hittable_list.hpp" +#include "geometry/hittable_list.hpp" +#include "geometry/quad.hpp" +#include "material/lambertian.hpp" +#include "material/diffuse_light.hpp" +#include "texture/checker_texture.hpp" +#include "renderer/camera.hpp" +#include "renderer/pathtracing_renderer.hpp" + +#include + + +using namespace std; + + +shared_ptr CornellBoxScene::InitCamera() +{ + CameraParams camera_params; + camera_params.aspect_ratio = 1.0; + camera_params.image_width = m_params.render_width; + camera_params.vfov = 40.0; + camera_params.lookfrom = Point3(278, 278, -800); + camera_params.lookat = Point3(278, 278, 0); + camera_params.vup = Vec3(0,1,0); + camera_params.defocus_angle = 0.0; + camera_params.focus_dist = 10.0; + + return make_shared(std::move(camera_params)); +} + + +shared_ptr CornellBoxScene::InitObjects() +{ + auto hittable_list = make_shared(); + + auto red = make_shared(RGBColor(.65, .05, .05)); + auto white = make_shared(RGBColor(.73, .73, .73)); + auto green = make_shared(RGBColor(.12, .45, .15)); + auto light = make_shared(RGBColor(15, 15, 15)); + + hittable_list->AddObjects({ + make_shared(Point3(555,0,0), Vec3(0,555,0), Vec3(0,0,555), green), + make_shared(Point3(0,0,0), Vec3(0,555,0), Vec3(0,0,555), red), + make_shared(Point3(343, 554, 332), Vec3(-130,0,0), Vec3(0,0,-105), light), + make_shared(Point3(0,0,0), Vec3(555,0,0), Vec3(0,0,555), white), + make_shared(Point3(555,555,555), Vec3(-555,0,0), Vec3(0,0,-555), white), + make_shared(Point3(0,0,555), Vec3(555,0,0), Vec3(0,555,0), white) + }); + + return hittable_list; +} + + +shared_ptr CornellBoxScene::InitRenderer() +{ + PathTracingRendererParams params; + params.aa_sample_per_pixel = 1600; + params.max_depth = 20; + params.background_color = BLACK; + + return make_shared(m_camera, m_objets, move(params)); +} + + +void CornellBoxScene::Build(SceneParams &¶ms) +{ + m_params = params; + m_camera = InitCamera(); + m_objets = InitObjects(); + m_renderer = InitRenderer(); +} + + +shared_ptr CornellBoxScene::Render() +{ + m_renderer->Render(); + return m_renderer->GetBuffer(); +} diff --git a/src/scenes/cornell_box_scene.hpp b/src/scenes/cornell_box_scene.hpp new file mode 100644 index 0000000..ad9362b --- /dev/null +++ b/src/scenes/cornell_box_scene.hpp @@ -0,0 +1,25 @@ + +#pragma once + +#include "scenes/IScene.hpp" + + +class Camera; +class HittableList; +class PathTracingRenderer; + +class CornellBoxScene: public IScene { + +private: + + std::shared_ptr InitCamera(); + std::shared_ptr InitObjects(); + std::shared_ptr InitRenderer(); + + +public: + + void Build(SceneParams&& params) override; + std::shared_ptr Render() override; + +}; \ No newline at end of file diff --git a/src/scenes/quads_scene.cpp b/src/scenes/quads_scene.cpp index baadc49..f9ff179 100644 --- a/src/scenes/quads_scene.cpp +++ b/src/scenes/quads_scene.cpp @@ -58,6 +58,7 @@ shared_ptr QuadsScene::InitRenderer() PathTracingRendererParams params; params.aa_sample_per_pixel = 100; params.max_depth = 20; + params.background_color = RGBColor(0.70, 0.80, 1.00); return make_shared(m_camera, m_objets, move(params)); } diff --git a/src/scenes/solar_system_scene.cpp b/src/scenes/solar_system_scene.cpp index f6326e0..192e3ac 100644 --- a/src/scenes/solar_system_scene.cpp +++ b/src/scenes/solar_system_scene.cpp @@ -75,6 +75,7 @@ shared_ptr SolarSystemScene::InitRenderer() PathTracingRendererParams params; params.aa_sample_per_pixel = 300; params.max_depth = 50; + params.background_color = RGBColor(0.70, 0.80, 1.00); return make_shared(m_camera, m_objets, move(params)); } diff --git a/src/scenes/sparsed_spheres_scene.cpp b/src/scenes/sparsed_spheres_scene.cpp index b8e300c..faf61dd 100644 --- a/src/scenes/sparsed_spheres_scene.cpp +++ b/src/scenes/sparsed_spheres_scene.cpp @@ -105,6 +105,7 @@ shared_ptr SparsedSpheresScene::InitRenderer() PathTracingRendererParams params; params.aa_sample_per_pixel = 100; params.max_depth = 20; + params.background_color = RGBColor(0.70, 0.80, 1.00); return make_shared(m_camera, m_objets, move(params)); }