From 6b1f0264273f44158abd5787fe35a1b7af0de19b Mon Sep 17 00:00:00 2001 From: vonhyou Date: Sun, 3 Mar 2024 21:52:38 -0500 Subject: [PATCH] make area light --- CMakeLists.txt | 4 ++-- src/Light.cc | 32 +++++++++++++++++++++++++------- src/Light.h | 30 +++++++++++++++++------------- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 801846f..dfefc30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,8 +21,8 @@ add_compile_options(-DSTUDENT_SOLUTION) # When testing large scenes the debug mode will be very slow # so switch to release -set(CMAKE_BUILD_TYPE Debug) -#set(CMAKE_BUILD_TYPE Release) +#set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_BUILD_TYPE Release) set(CMAKE_CXX_STANDARD 14) diff --git a/src/Light.cc b/src/Light.cc index 724dade..83c5cc8 100644 --- a/src/Light.cc +++ b/src/Light.cc @@ -1,6 +1,7 @@ #include "Light.h" #include #include +#include void Light::setTransform(const Matrix4f &transform) { this->transform = transform; @@ -10,6 +11,10 @@ void Light::setGridSize(unsigned int gridSize) { this->gridSize = gridSize; } void Light::setUseCenter(bool useCenter) { this->useCenter = useCenter; } +Vector3f Light::getDiffuse() const { return diffuse; } + +Vector3f Light::getSpecular() const { return specular; } + Vector3f PointLight::illumination(const HitRecord &hit, const vector &geometries) const { Vector3f shadingPoint = hit.getPoint(); @@ -21,21 +26,34 @@ Vector3f PointLight::illumination(const HitRecord &hit, if (g != geometry && g->intersect(shadowRay).hasValue()) return Vector3f::Zero(); - float distance = (center - shadingPoint).norm(); - float att = 1.0f / distance / distance; - Vector3f ambient_ = geometry->coefAmbient() * geometry->ambient(); - Vector3f diffuse_ = att * geometry->coefDiffuse() * diffuse * + Vector3f diffuse_ = geometry->coefDiffuse() * diffuse.array() * + geometry->diffuse().array() * std::max(0.0f, hit.normal().dot(rayDirection)); Vector3f halfWay = (hit.viewDirection() + rayDirection).normalized(); Vector3f specular_ = - att * geometry->coefSpecular() * specular * + geometry->coefSpecular() * specular.array() * + geometry->specular().array() * pow(std::max(0.0f, hit.normal().dot(halfWay)), geometry->getPhong()); - return ambient_ + diffuse_ + specular_; + return diffuse_ + specular_ + ambient_; } Vector3f AreaLight::illumination(const HitRecord &hit, const vector &geometries) const { - return Vector3f::Zero(); + Vector3f u = p4 - p1; + Vector3f v = p2 - p1; + + Vector3f color = Vector3f::Zero(); + + if (useCenter) { + color += PointLight(*this, (u + v) / 2).illumination(hit, geometries); + } else { + for (int y = 0; y < gridSize; ++y) + for (int x = 0; x < gridSize; ++x) + color += PointLight(*this, (u * x + v * y) / gridSize) + .illumination(hit, geometries); + } + + return color / gridSize / gridSize; } diff --git a/src/Light.h b/src/Light.h index 84163ed..be87209 100644 --- a/src/Light.h +++ b/src/Light.h @@ -31,22 +31,11 @@ protected: bool useCenter = false; // optional member `usecenter` public: - // setters for optional members void setTransform(const Matrix4f &); void setGridSize(unsigned int); void setUseCenter(bool); -}; - -class PointLight : public Light { -public: - PointLight(const Vector3f &id, const Vector3f &is, Vector3f ¢er) - : Light(Type::Point, id, is), center(center) {} - - virtual Vector3f illumination(const HitRecord &, - const vector &) const override; - -private: - Vector3f center; + Vector3f getDiffuse() const; + Vector3f getSpecular() const; }; class AreaLight : public Light { @@ -62,4 +51,19 @@ private: Vector3f p1, p2, p3, p4; }; +class PointLight : public Light { +public: + PointLight(const Vector3f &id, const Vector3f &is, const Vector3f ¢er) + : Light(Type::Point, id, is), center(center) {} + + PointLight(const AreaLight &al, const Vector3f ¢er) + : PointLight(al.getDiffuse(), al.getSpecular(), center) {} + + virtual Vector3f illumination(const HitRecord &, + const vector &) const override; + +private: + Vector3f center; +}; + #endif // !LIGHT_H_