From fa13c97b0cc3e22c24f0661f2f8865d8630f2621 Mon Sep 17 00:00:00 2001 From: abendo Date: Thu, 15 Oct 2020 02:29:59 +0200 Subject: [PATCH] Assignment 2 - Solution --- README.md | 2 +- src/LightOmni.h | 10 ++++++++-- src/PrimPlane.h | 2 +- src/PrimSphere.h | 2 +- src/PrimTriangle.h | 2 +- src/Scene.h | 15 ++++++++++++++- src/ShaderEyelight.h | 2 +- src/ShaderFlat.h | 2 +- src/ShaderMirror.h | 12 +++++++++++- src/ShaderPhong.h | 32 +++++++++++++++++++++++++++++++- 10 files changed, 70 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 616cf1b..b850bc4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Dealine**: 15.10.2020 Please put your name here: -**Name**: ....... +**Name**: Albrit Bendo ## Problem 1 ### Encapsulate camera and primitives from main application logic (Points 5) 1. Fork the current repository diff --git a/src/LightOmni.h b/src/LightOmni.h index fa17a54..bf2a1cc 100644 --- a/src/LightOmni.h +++ b/src/LightOmni.h @@ -24,11 +24,17 @@ class CLightOmni : public ILight virtual std::optional illuminate(Ray& ray) override { // --- PUT YOUR CODE HERE --- - return std::nullopt; + ray.dir = m_org - ray.org; + ray.t = norm(ray.dir); + ray.dir = normalize(ray.dir); + ray.hit = nullptr; + + double attenuation = 1 / (ray.t*ray.t); + return m_intensity * attenuation; } private: Vec3f m_intensity; ///< The emission (red, green, blue) Vec3f m_org; ///< The light source origin -}; +}; \ No newline at end of file diff --git a/src/PrimPlane.h b/src/PrimPlane.h index 42a53ec..bbacb9a 100755 --- a/src/PrimPlane.h +++ b/src/PrimPlane.h @@ -38,7 +38,7 @@ class CPrimPlane : public IPrim virtual Vec3f getNormal(const Ray& ray) const override { // --- PUT YOUR CODE HERE --- - return Vec3f(); + return m_normal; } private: diff --git a/src/PrimSphere.h b/src/PrimSphere.h index b32a9d6..8ffc1ec 100755 --- a/src/PrimSphere.h +++ b/src/PrimSphere.h @@ -58,7 +58,7 @@ class CPrimSphere : public IPrim virtual Vec3f getNormal(const Ray& ray) const override { // --- PUT YOUR CODE HERE --- - return Vec3f(); + return normalize(ray.org + ray.dir * ray.t - m_origin); } private: diff --git a/src/PrimTriangle.h b/src/PrimTriangle.h index 872f2ff..2fc6c67 100644 --- a/src/PrimTriangle.h +++ b/src/PrimTriangle.h @@ -64,7 +64,7 @@ class CPrimTriangle : public IPrim virtual Vec3f getNormal(const Ray& ray) const override { // --- PUT YOUR CODE HERE --- - return Vec3f(); + return normalize((m_b - m_a).cross(m_c - m_a)); } private: diff --git a/src/Scene.h b/src/Scene.h index e382b95..983b281 100644 --- a/src/Scene.h +++ b/src/Scene.h @@ -30,6 +30,7 @@ class CScene void add(const ptr_prim_t pPrim) { // --- PUT YOUR CODE HERE --- + m_vpPrims.push_back(pPrim); } /** * @brief Adds a new light to the scene @@ -38,6 +39,7 @@ class CScene void add(const ptr_light_t pLight) { // --- PUT YOUR CODE HERE --- + m_vpLights.push_back(pLight); } /** * @brief Adds a new camera to the scene and makes it to ba active @@ -46,6 +48,8 @@ class CScene void add(const ptr_camera_t pCamera) { // --- PUT YOUR CODE HERE --- + m_vpCameras.push_back(pCamera); + m_activeCamera = m_vpCameras.size() - 1; } /** * @brief Returns the container with all scene light source objects @@ -68,6 +72,10 @@ class CScene bool intersect(Ray& ray) const { // --- PUT YOUR CODE HERE --- + for(auto& prim : m_vpPrims) { + if(prim->intersect(ray)) { return true; } + } + return false; } @@ -77,6 +85,10 @@ class CScene bool occluded(Ray& ray) { // --- PUT YOUR CODE HERE --- + for(auto& prim : m_vpPrims) { + if(prim->intersect(ray)) { return true; } + } + return false; } @@ -87,7 +99,8 @@ class CScene Vec3f RayTrace(Ray& ray) const { // --- PUT YOUR CODE HERE --- - return Vec3f(); + if(intersect(ray)) { return ray.hit->getShader()->shade(ray); } + else { return m_bgColor; } } diff --git a/src/ShaderEyelight.h b/src/ShaderEyelight.h index 5a282aa..c000f8b 100644 --- a/src/ShaderEyelight.h +++ b/src/ShaderEyelight.h @@ -22,7 +22,7 @@ class CShaderEyelight : public CShaderFlat virtual Vec3f shade(const Ray& ray) const override { // --- PUT YOUR CODE HERE --- - return RGB(0, 0, 0); + return CShaderFlat::shade(ray) * fabs(ray.dir.dot(ray.hit->getNormal(ray))); } }; diff --git a/src/ShaderFlat.h b/src/ShaderFlat.h index 0ea92e9..6d318a3 100644 --- a/src/ShaderFlat.h +++ b/src/ShaderFlat.h @@ -18,7 +18,7 @@ class CShaderFlat : public IShader virtual Vec3f shade(const Ray& ray = Ray()) const override { // --- PUT YOUR CODE HERE --- - return RGB(0, 0, 0); + return m_color; } private: diff --git a/src/ShaderMirror.h b/src/ShaderMirror.h index 6e06d0b..6c36068 100644 --- a/src/ShaderMirror.h +++ b/src/ShaderMirror.h @@ -17,7 +17,17 @@ class CShaderMirror : public IShader virtual Vec3f shade(const Ray& ray) const override { // --- PUT YOUR CODE HERE --- - return Vec3f(0,0,0); + Ray shade; + Vec3f nrm = ray.hit->getNormal(ray); + double ray_dnrm = ray.dir.dot(nrm); + + if(ray_dnrm > 0) { nrm = -nrm; } + + shade.dir = normalize(ray.dir - ray_dnrm * nrm * 2); + shade.t = std::numeric_limits::max(); + shade.org = ray.dir * ray.t + ray.org; + + return m_scene.RayTrace(shade); } diff --git a/src/ShaderPhong.h b/src/ShaderPhong.h index 6c06294..61e071c 100644 --- a/src/ShaderPhong.h +++ b/src/ShaderPhong.h @@ -27,7 +27,37 @@ class CShaderPhong : public CShaderFlat virtual Vec3f shade(const Ray& ray) const override { // --- PUT YOUR CODE HERE --- - return RGB(0, 0, 0); + Vec3f nrm = ray.hit->getNormal(ray); + double ray_dnrm = ray.dir.dot(nrm); + + if(ray_dnrm > 0) { nrm = -nrm; } + + Vec3f ambient_col = CShaderFlat::shade(ray); + Vec3f diffuse_col = 0; + Vec3f specular_col = 0; + + Ray shade; + + int n = 1; + + shade.org = ray.dir * ray.t + ray.org; + + for(auto light : m_scene.getLights()) { + for(int i = 0; i < n; i ++) { + if(!light->illuminate(shade)) + if(m_scene.occluded(shade)) + continue; + + Vec3f res = 2 * shade.dir.dot(nrm) * nrm - shade.dir; + + diffuse_col += *light->illuminate(shade) * std::max(0.f, shade.dir.dot(nrm)); + specular_col += *light->illuminate(shade) * std::pow(std::max(0.f, res.dot(-ray.dir)), m_ke); + } + } + + return m_ka * ambient_col * 1.1 + + m_kd * ambient_col.mul(diffuse_col / n) + + m_ks * RGB(1, 1, 1).mul(specular_col / n); }