From 342c9fdef273ef32c39d00087f5173b6c1e535d7 Mon Sep 17 00:00:00 2001 From: vonhyou Date: Thu, 21 Mar 2024 17:37:00 -0400 Subject: [PATCH 1/5] antialiasing --- src/RayTracer.cc | 46 ++++++++++++++++++++++++++-------------------- src/RayTracer.h | 3 ++- src/Scene.cc | 2 ++ src/Scene.h | 1 + 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/RayTracer.cc b/src/RayTracer.cc index c8244b8..2da8e8b 100644 --- a/src/RayTracer.cc +++ b/src/RayTracer.cc @@ -91,39 +91,37 @@ void RayTracer::render() { for (int x = 0; x < width; ++x) { Vector3f color = Scene::current->backgroundColor(); - if (Scene::current->globalIllum()) { + bool globalIllum = Scene::current->globalIllum(); + if (globalIllum || Scene::current->antiAliasing()) { int success = 0; Vector3f accumulate = Vector3f::Zero(); for (int j = 0; j < gridHeight; ++j) for (int i = 0; i < gridWidth; ++i) { - - if (x != width / 2 || y != height / 2 || i || j) - ; // goto DEBUG_COLOR; Ray ray = getRay(x, y, i, j); for (int rayNum = 0; rayNum < raysPerPixel; ++rayNum) { - utils::Optional result = trace(ray); + Optional result = + globalIllum ? trace(ray) : trace(ray, x, y); if (result.hasValue()) { accumulate += result.value(); success++; } } - - // std::cout << accumulate.transpose() << " (" << success << - // std::endl; } - if (success) - color = gammaCorrection(accumulate / success, 1.0f / 2.1f); + if (success) { + if (globalIllum) + color = gammaCorrection(accumulate / success, 1.0f / 2.1f); + else + color = accumulate / success; + } } else { Ray ray = getRay(x, y); - Optional hitRecord = getHitRecord(ray); - if (hitRecord.hasValue()) { - HitRecord hit = hitRecord.value(); - color = calculateColor(hit, y * width + x); - } + Optional result = trace(ray, x, y); + if (result.hasValue()) + color = result.value(); } - DEBUG_COLOR: + writeColor(y * width + x, clamp(color)); } } @@ -133,7 +131,7 @@ void RayTracer::render() { /** * Calculate color using phong model */ -Vector3f RayTracer::calculateColor(const HitRecord &hit, int i) const { +Vector3f RayTracer::calculateColor(const HitRecord &hit) const { Vector3f result(0, 0, 0); for (auto light : lights) result += light->isUse() ? light->illumination(hit, geometries) @@ -268,17 +266,25 @@ RETRY_TRACING: std::max(0.0f, hit.normal().dot(direction)); } -utils::Optional RayTracer::trace(Ray r) const { +Optional RayTracer::trace(Ray r, int x, int y) const { + Optional hitRecord = getHitRecord(r); + if (hitRecord.hasValue()) + return Optional(calculateColor(hitRecord.value())); + + return Optional::nullopt; +} + +Optional RayTracer::trace(Ray r) const { Optional hitRecord = getHitRecord(r); if (hitRecord.hasValue()) { Vector3f color = trace(hitRecord.value(), Scene::current->maxBounce(), Scene::current->probTerminate()); if (color != Vector3f::Zero()) - return utils::Optional(color); + return Optional(color); } - return utils::Optional::nullopt; + return Optional::nullopt; } namespace camera { diff --git a/src/RayTracer.h b/src/RayTracer.h index 2da4613..7995478 100644 --- a/src/RayTracer.h +++ b/src/RayTracer.h @@ -28,8 +28,9 @@ private: void render(); Optional getHitRecord(Ray, const Geometry *) const; Optional getHitRecord(Ray) const; - Vector3f calculateColor(const HitRecord &, int) const; + Vector3f calculateColor(const HitRecord &) const; Light *singleLightSource() const; + Optional trace(Ray, int, int) const; Optional trace(Ray) const; Vector3f trace(HitRecord, int, float) const; }; diff --git a/src/Scene.cc b/src/Scene.cc index 12c3e27..f8f561e 100644 --- a/src/Scene.cc +++ b/src/Scene.cc @@ -12,6 +12,8 @@ float Scene::fov() { return fov_; } bool Scene::globalIllum() { return globalIllum_; } +bool Scene::antiAliasing() { return antialiasing_; } + int Scene::maxBounce() { return maxBounce_; } float Scene::probTerminate() { return probTerminate_; } diff --git a/src/Scene.h b/src/Scene.h index fe033da..53b0ccf 100644 --- a/src/Scene.h +++ b/src/Scene.h @@ -41,6 +41,7 @@ public: int height(); float fov(); bool globalIllum(); + bool antiAliasing(); int maxBounce(); float probTerminate(); Vector3f ai() const; From f7e2ad664b2dcd2a9cdc5c02b2f8e4f73d9dd778 Mon Sep 17 00:00:00 2001 From: vonhyou Date: Thu, 21 Mar 2024 17:53:20 -0400 Subject: [PATCH 2/5] merge duplicate code --- src/RayTracer.cc | 55 +++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/RayTracer.cc b/src/RayTracer.cc index 2da8e8b..80dd723 100644 --- a/src/RayTracer.cc +++ b/src/RayTracer.cc @@ -8,6 +8,7 @@ #include "Ray.h" #include +#include #include #include #include @@ -27,6 +28,7 @@ Vector3f clamp(const Vector3f &); namespace camera { int width, height, gridWidth, gridHeight, raysPerPixel; Vector3f pos, u, v, du, dv, vpUpperLeft, pxUpperLeft, gdu, gdv; +bool globalIllum, antiAliasing; void init(); } // namespace camera @@ -85,41 +87,37 @@ void RayTracer::render() { using namespace camera; Output::current = new Output(Scene::current->name(), width, height); + std::cout << "Global Illumination: " << (globalIllum ? "T" : "F") << std::endl + << "Anti-aliasing: " << (antiAliasing ? "T" : "F") << std::endl; + + std::cout << gridHeight << " " << gridWidth << " " << raysPerPixel + << std::endl; for (int y = 0; y < height; ++y) { utils::Progress::of((y + 1.0f) / height); for (int x = 0; x < width; ++x) { Vector3f color = Scene::current->backgroundColor(); - bool globalIllum = Scene::current->globalIllum(); - if (globalIllum || Scene::current->antiAliasing()) { - int success = 0; - Vector3f accumulate = Vector3f::Zero(); - for (int j = 0; j < gridHeight; ++j) - for (int i = 0; i < gridWidth; ++i) { - Ray ray = getRay(x, y, i, j); - for (int rayNum = 0; rayNum < raysPerPixel; ++rayNum) { - Optional result = - globalIllum ? trace(ray) : trace(ray, x, y); - if (result.hasValue()) { - accumulate += result.value(); - success++; - } + int success = 0; + Vector3f accumulate = Vector3f::Zero(); + for (int j = 0; j < gridHeight; ++j) + for (int i = 0; i < gridWidth; ++i) { + Ray ray = getRay(x, y, i, j); + for (int rayNum = 0; rayNum < raysPerPixel; ++rayNum) { + Optional result = + globalIllum ? trace(ray) : trace(ray, x, y); + if (result.hasValue()) { + accumulate += result.value(); + success++; } } - - if (success) { - if (globalIllum) - color = gammaCorrection(accumulate / success, 1.0f / 2.1f); - else - color = accumulate / success; } - } else { - Ray ray = getRay(x, y); - Optional result = trace(ray, x, y); - if (result.hasValue()) - color = result.value(); + if (success) { + if (globalIllum) + color = gammaCorrection(accumulate / success, 1.0f / 2.1f); + else + color = accumulate / success; } writeColor(y * width + x, clamp(color)); @@ -320,7 +318,12 @@ void init() { vpUpperLeft = pos + lookAt - u / 2.0 - v / 2.0; pxUpperLeft = vpUpperLeft + (du + dv) / 2.0; - VectorXi data = Scene::current->raysPerPixel(); + globalIllum = Scene::current->globalIllum(); + antiAliasing = Scene::current->antiAliasing(); + + VectorXi data = !(globalIllum || antiAliasing) + ? VectorXi(1) + : Scene::current->raysPerPixel(); gridWidth = getGridWidth(data); gridHeight = getGridHeight(data); raysPerPixel = getRayNumber(data); From 271f213969afb1af5a6a798c09a8c13c76430f4b Mon Sep 17 00:00:00 2001 From: vonhyou Date: Thu, 21 Mar 2024 19:36:37 -0400 Subject: [PATCH 3/5] bugfix: --- src/Parser.cc | 4 ++-- src/RayTracer.cc | 56 +++++++++++++++++++++--------------------------- src/RayTracer.h | 1 - 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/Parser.cc b/src/Parser.cc index abca50e..3fee6ef 100644 --- a/src/Parser.cc +++ b/src/Parser.cc @@ -39,8 +39,8 @@ Scene *Parser::getScene(const nlohmann::json &j) { sc->setAntialiasing(j.value("antialiasing", false)); sc->setTwoSideRender(j.value("twosiderender", false)); sc->setGlobalIllum(j.value("globalillum", false)); - sc->setMaxBounce(j.value("maxbounce", 3)); - sc->setProbTerminate(j.value("probTerminate", 0.33f)); + sc->setMaxBounce(j.value("maxbounces", 3)); + sc->setProbTerminate(j.value("probterminate", 0.33f)); if (j.contains("raysperpixel")) sc->setRaysPerPixel(getRpp(j["raysperpixel"])); diff --git a/src/RayTracer.cc b/src/RayTracer.cc index 80dd723..04103a8 100644 --- a/src/RayTracer.cc +++ b/src/RayTracer.cc @@ -19,7 +19,6 @@ using Eigen::VectorXi; using std::priority_queue; // help function declarations -Ray getRay(int, int); Ray getRay(int, int, int, int); void writeColor(int, const Vector3f &); utils::Optional trace(Ray r); @@ -87,11 +86,6 @@ void RayTracer::render() { using namespace camera; Output::current = new Output(Scene::current->name(), width, height); - std::cout << "Global Illumination: " << (globalIllum ? "T" : "F") << std::endl - << "Anti-aliasing: " << (antiAliasing ? "T" : "F") << std::endl; - - std::cout << gridHeight << " " << gridWidth << " " << raysPerPixel - << std::endl; for (int y = 0; y < height; ++y) { utils::Progress::of((y + 1.0f) / height); @@ -102,10 +96,9 @@ void RayTracer::render() { Vector3f accumulate = Vector3f::Zero(); for (int j = 0; j < gridHeight; ++j) for (int i = 0; i < gridWidth; ++i) { - Ray ray = getRay(x, y, i, j); for (int rayNum = 0; rayNum < raysPerPixel; ++rayNum) { - Optional result = - globalIllum ? trace(ray) : trace(ray, x, y); + Ray ray = getRay(x, y, i, j); + Optional result = trace(ray); if (result.hasValue()) { accumulate += result.value(); success++; @@ -169,14 +162,22 @@ Light *RayTracer::singleLightSource() const { return nullptr; } -Ray getRay(int x, int y) { - using namespace camera; - return Ray(pos, pxUpperLeft + x * du + y * dv - pos); +// This should generate a higher quality random number +float getRandomNumber() { + static std::uniform_real_distribution distribution(0.0, 1.0); + static std::mt19937 generator; + return distribution(generator); } Ray getRay(int x, int y, int i, int j) { using namespace camera; - return Ray(pos, vpUpperLeft + x * du + i * gdu + y * dv + j * gdv - pos); + Vector3f offset = Vector3f::Zero(); + + if (globalIllum || antiAliasing) + offset = getRandomNumber() * gdu + getRandomNumber() * gdv; + + return Ray(pos, + vpUpperLeft + x * du + i * gdu + y * dv + j * gdv + offset - pos); } Vector3f clamp(const Vector3f &color) { @@ -189,13 +190,6 @@ void writeColor(int i, const Vector3f &color) { Output::current->b(i, color.z()); } -// This should generate a higher quality random number -float getRandomNumber() { - static std::uniform_real_distribution distribution(0.0, 1.0); - static std::mt19937 generator; - return distribution(generator); -} - // Generate a randon point on a unit hemisphere Vector3f getRandomDirection() { RETRY_RANDOM: @@ -264,22 +258,20 @@ RETRY_TRACING: std::max(0.0f, hit.normal().dot(direction)); } -Optional RayTracer::trace(Ray r, int x, int y) const { - Optional hitRecord = getHitRecord(r); - if (hitRecord.hasValue()) - return Optional(calculateColor(hitRecord.value())); - - return Optional::nullopt; -} - Optional RayTracer::trace(Ray r) const { Optional hitRecord = getHitRecord(r); - if (hitRecord.hasValue()) { - Vector3f color = trace(hitRecord.value(), Scene::current->maxBounce(), - Scene::current->probTerminate()); + if (!camera::globalIllum) { + if (hitRecord.hasValue()) + return Optional(calculateColor(hitRecord.value())); + else if (camera::antiAliasing) + return Optional(Scene::current->backgroundColor()); + } else { + if (hitRecord.hasValue()) { + Vector3f color = trace(hitRecord.value(), Scene::current->maxBounce(), + Scene::current->probTerminate()); - if (color != Vector3f::Zero()) return Optional(color); + } } return Optional::nullopt; diff --git a/src/RayTracer.h b/src/RayTracer.h index 7995478..06bf7b1 100644 --- a/src/RayTracer.h +++ b/src/RayTracer.h @@ -30,7 +30,6 @@ private: Optional getHitRecord(Ray) const; Vector3f calculateColor(const HitRecord &) const; Light *singleLightSource() const; - Optional trace(Ray, int, int) const; Optional trace(Ray) const; Vector3f trace(HitRecord, int, float) const; }; From 7dff9e711776ebf4d7b56901afced2916c9638f7 Mon Sep 17 00:00:00 2001 From: vonhyou Date: Thu, 21 Mar 2024 21:08:33 -0400 Subject: [PATCH 4/5] add more case for global illumination --- assets/cornell_box_demo.json | 365 +++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 assets/cornell_box_demo.json diff --git a/assets/cornell_box_demo.json b/assets/cornell_box_demo.json new file mode 100644 index 0000000..2d46105 --- /dev/null +++ b/assets/cornell_box_demo.json @@ -0,0 +1,365 @@ +{ + "geometry": [ + { + "comment": "back_wall", + "type": "rectangle", + "p2": [ + 556, + 0, + -559 + ], + "p1": [ + 0, + 0, + -559 + ], + "p4": [ + 0, + 548.8, + -559 + ], + "p3": [ + 556, + 548.8, + -559 + ], + "ac": [ + 1, + 1, + 1 + ], + "dc": [ + 1, + 1, + 1 + ], + "sc": [ + 0, + 0, + 0 + ], + "ka": 0, + "kd": 0.5, + "ks": 0, + "pc": 0 + }, + { + "comment": "right_wall", + "type": "rectangle", + "p1": [ + 556, + 0, + -559 + ], + "p2": [ + 556, + 0, + 0 + ], + "p3": [ + 556, + 548.8, + 0 + ], + "p4": [ + 556, + 548.8, + -559 + ], + "ac": [ + 1, + 0, + 0 + ], + "dc": [ + 1, + 0, + 0 + ], + "sc": [ + 0, + 0, + 0 + ], + "ka": 0, + "kd": 0.5, + "ks": 0, + "pc": 0 + }, + { + "comment": "left_wall", + "type": "rectangle", + "p2": [ + 0, + 0, + -559 + ], + "p1": [ + 0, + 0, + 0 + ], + "p4": [ + 0, + 548.8, + 0 + ], + "p3": [ + 0, + 548.8, + -559 + ], + "ac": [ + 0, + 1, + 0 + ], + "dc": [ + 0, + 1, + 0 + ], + "sc": [ + 0, + 0, + 0 + ], + "ka": 0, + "kd": 0.5, + "ks": 0, + "pc": 0 + }, + { + "comment": "ceiling", + "type": "rectangle", + "p1": [ + 0, + 548.8, + 0 + ], + "p2": [ + 0, + 548.8, + -559 + ], + "p3": [ + 556, + 548.8, + -559.0 + ], + "p4": [ + 556, + 548.8, + 0 + ], + "ac": [ + 1, + 1, + 1 + ], + "dc": [ + 1, + 1, + 1 + ], + "sc": [ + 0, + 0, + 0 + ], + "ka": 0, + "kd": 1, + "ks": 0, + "pc": 0 + }, + { + "comment": "floor", + "type": "rectangle", + "p1": [ + 0, + 0, + 0 + ], + "p4": [ + 0, + 0, + -559 + ], + "p3": [ + 556, + 0, + -559.0 + ], + "p2": [ + 556, + 0, + 0 + ], + "ac": [ + 1, + 1, + 1 + ], + "dc": [ + 1, + 1, + 1 + ], + "sc": [ + 0, + 0, + 0 + ], + "ka": 0, + "kd": 0.5, + "ks": 0, + "pc": 0 + }, + { + "type": "sphere", + "centre": [ + 300, + 228, + -228 + ], + "radius": 80, + "ac": [ + 1, + 1, + 1 + ], + "dc": [ + 0, + 0, + 1 + ], + "sc": [ + 1, + 1, + 1 + ], + "ka": 0, + "kd": 1, + "ks": 1, + "pc": 100 + }, + { + "type": "sphere", + "centre": [ + 140, + 228, + -228 + ], + "radius": 80, + "ac": [ + 1, + 1, + 1 + ], + "dc": [ + 1, + 1, + 1 + ], + "sc": [ + 1, + 1, + 1 + ], + "ka": 0, + "kd": 1, + "ks": 1, + "pc": 100 + }, + { + "type": "sphere", + "centre": [ + 460, + 228, + -228 + ], + "radius": 80, + "ac": [ + 1, + 1, + 1 + ], + "dc": [ + 1, + 1, + 1 + ], + "sc": [ + 1, + 1, + 1 + ], + "ka": 0, + "kd": 1, + "ks": 1, + "pc": 100 + } + ], + "light": [ + { + "type": "point", + "centre": [ + 278, + 540, + -279.5 + ], + "id": [ + 1, + 1, + 1 + ], + "is": [ + 1, + 1, + 1 + ] + } + ], + "output": [ + { + "filename": "cornell_box_demo.ppm", + "size": [ + 500, + 500 + ], + "lookat": [ + 0, + 0, + -1 + ], + "up": [ + 0, + 1, + 0 + ], + "fov": 40, + "centre": [ + 278, + 273, + 800 + ], + "ai": [ + 1, + 1, + 1 + ], + "bkc": [ + 0.5, + 0.5, + 0.5 + ], + "globalillum": true, + "raysperpixel": [ + 10, + 10 + ], + "maxbounces": 3, + "probterminate": 0.3333 + } + ] +} From 55855b6718accfa5c4b117bf9b001df977eb8586 Mon Sep 17 00:00:00 2001 From: vonhyou Date: Thu, 21 Mar 2024 21:13:39 -0400 Subject: [PATCH 5/5] remove unwanted header --- src/RayTracer.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/RayTracer.cc b/src/RayTracer.cc index 04103a8..155ab2f 100644 --- a/src/RayTracer.cc +++ b/src/RayTracer.cc @@ -8,7 +8,6 @@ #include "Ray.h" #include -#include #include #include #include