From ca0480a8c55b38d9a5651c34b7b9b0defac22b3a Mon Sep 17 00:00:00 2001 From: Syndamia Date: Tue, 4 Jun 2024 12:22:39 +0300 Subject: [PATCH] [hw12-hard] Implemented proper solid angle for rectangular lights --- flake.lock | 27 +++++++++++++++++++++++++++ flake.nix | 26 ++++++++++++++++++++++++++ src/lights.cpp | 32 +++++++++++++++++++------------- src/lights.h | 2 ++ src/main.cpp | 2 +- src/vector.h | 4 ++++ 6 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..25db693 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1716061101, + "narHash": "sha256-H0eCta7ahEgloGIwE/ihkyGstOGu+kQwAiHvwVoXaA0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e7cc61784ddf51c81487637b3031a6dd2d6673a2", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..d0a99fd --- /dev/null +++ b/flake.nix @@ -0,0 +1,26 @@ +# Този файл, заедно с flake.lock са си за моета система, да имам копие ако случайно изтрия нещо +{ + description = "hexray raytracer in FMI elective"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11"; + }; + + outputs = inputs: + let + pkgs = inputs.nixpkgs.legacyPackages."x86_64-linux"; + in { + devShells."x86_64-linux".default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ + cmake + pkg-config + ]; + + buildInputs = with pkgs; [ + SDL2 + openexr_3 + zlib + ]; + }; + }; +} diff --git a/src/lights.cpp b/src/lights.cpp index f6edef4..d5b0ed6 100644 --- a/src/lights.cpp +++ b/src/lights.cpp @@ -74,9 +74,8 @@ int RectLight::intersect(const Ray& ray, double& intersectionDist) void RectLight::beginFrame() { - Vector pts[3]; - for (int i = 0; i < 3; i++) { - pts[i].x = (i % 2) ? -0.5 : 0.5; + for (int i = 0; i < 4; i++) { + pts[i].x = (i % 3) ? -0.5 : 0.5; pts[i].y = 0; pts[i].z = (i < 2) ? -0.5 : 0.5; pts[i] = T.transformPoint(pts[i]); @@ -87,16 +86,23 @@ void RectLight::beginFrame() scaleFactor = 1 / m_area; } +static Vector projectOnUnitSphere(const Vector& toProj, const Vector& sphereCenter) { + return sphereCenter + normalize(toProj - sphereCenter); +} + double RectLight::getSolidAngle(const Vector& p) { - Vector lightDirCanonic(0, -1, 0); - // - Vector lightDirWorld = T.transformDir(lightDirCanonic); - Vector lightPosWorld = T.transformPoint(Vector(0, 0, 0)); - Vector lightToP = p - lightPosWorld; - double cosTerm = dot(lightToP, lightDirWorld); - if (cosTerm < 0) return 0; - double d = lightToP.length(); - cosTerm /= d; - return m_area * cosTerm / sqr(1 + d); + Vector ppts[4]; + for (int i = 0; i < 4; i++) { + ppts[i] = projectOnUnitSphere(this->pts[i], p); + } + + double dihedrals = 0.0; + for (int i = 0; i < 4; i++) { + Vector n1 = (ppts[(i - 1 + 4) % 4] - p) ^ (ppts[i] - p); + Vector n2 = (ppts[(i + 1) % 4] - p) ^ (ppts[i] - p); + dihedrals += radBetween(n1, n2); + } + + return dihedrals - 2.0 * M_PI; } diff --git a/src/lights.h b/src/lights.h index c144577..e469c9d 100644 --- a/src/lights.h +++ b/src/lights.h @@ -100,6 +100,8 @@ class RectLight: public Light { int xSubd = 3, ySubd = 3; float scaleFactor; double m_area; + + Vector pts[4]; public: void fillProperties(ParsedBlock& pb) override { diff --git a/src/main.cpp b/src/main.cpp index 5af773d..f0a71e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -379,7 +379,7 @@ bool renderStatic() return render(true); } -const char* DEFAULT_SCENE = "data/smallpt.hexray"; +const char* DEFAULT_SCENE = "data/hw12/sphtri.hexray"; int main(int argc, char** argv) { diff --git a/src/vector.h b/src/vector.h index ed4c8cf..149d173 100644 --- a/src/vector.h +++ b/src/vector.h @@ -205,3 +205,7 @@ inline std::pair othonormedBasis(const Vector& v) result.second = result.first ^ v; return result; } + +inline double radBetween(const Vector& a, const Vector& b) { + return acos(dot(normalize(a), normalize(b))); +} -- 2.42.0