diff --git a/RayTracer/shape/Sphere.cpp b/RayTracer/shape/Sphere.cpp index 08420e50ca55bfbc321d64ac6395ff69045bc9b3..d9c90e3e5078998c1037a98bf28580494f44291e 100644 --- a/RayTracer/shape/Sphere.cpp +++ b/RayTracer/shape/Sphere.cpp @@ -25,16 +25,18 @@ std::optional<cam::Hit> Sphere::intersect(const cam::Ray& r) const { util::Vec3 t1HitPoint = r(t1); float theta = acos(t1HitPoint.y() / radius); float phi = M_PI + atan2(t1HitPoint.x(), t1HitPoint.z()); - return std::optional<cam::Hit>( - {t1HitPoint, t1HitPoint, t1, material}); + return std::optional<cam::Hit>({t1HitPoint, t1HitPoint, + texture_coordinates(t1HitPoint), t1, + material}); } else { float t2 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a); if (r.in_range(t2)) { util::Vec3 t2HitPoint = r(t2); float theta = acos(t2HitPoint.y() / radius); float phi = M_PI + atan2(t2HitPoint.x(), t2HitPoint.z()); - return std::optional<cam::Hit>( - {t2HitPoint, t2HitPoint, t2, material}); + return std::optional<cam::Hit>({t2HitPoint, t2HitPoint, + texture_coordinates(t2HitPoint), + t2, material}); } else { return std::nullopt; } @@ -43,6 +45,12 @@ std::optional<cam::Hit> Sphere::intersect(const cam::Ray& r) const { return std::nullopt; } } +std::pair<float, float> Sphere::texture_coordinates( + const util::Vec3& pos) const { + float theta = std::acos(pos.y() / radius); + float phi = M_PI + std::atan2(pos.x(), pos.z()); + return std::pair<float, float>({phi / (2 * M_PI), theta / M_PI}); +} util::AxisAlignedBoundingBox Sphere::bounds() const { return util::AxisAlignedBoundingBox(util::Vec3(-radius), util::Vec3(radius)); @@ -56,7 +64,8 @@ util::SurfacePoint Sphere::sampleLight() const { util::Vec3 point(radius * std::cos(theta) * std::sin(phi), radius * std::sin(theta) * std::sin(phi), radius * std::cos(phi)); - return util::SurfacePoint(point, point.normalize(), material); + return util::SurfacePoint(point, point.normalize(), + texture_coordinates(point), material); } util::Vec3 Sphere::calculateLightEmission(const util::SurfacePoint& p, const util::Vec3& d) const { diff --git a/RayTracer/shape/Sphere.h b/RayTracer/shape/Sphere.h index 73edcc2a9d12a20799d69102b9c21f63c7bff657..6216575f94b380c4dac2a82ab4fab27ab188a90f 100644 --- a/RayTracer/shape/Sphere.h +++ b/RayTracer/shape/Sphere.h @@ -8,6 +8,8 @@ class Sphere : public Light, public Shape { public: Sphere(float radius, const std::shared_ptr<material::Material>& material); std::optional<cam::Hit> intersect(const cam::Ray& r) const override; + std::pair<float, float> texture_coordinates( + const util::Vec3& pos) const override; util::AxisAlignedBoundingBox bounds() const override; util::SurfacePoint sampleLight() const override; util::Vec3 calculateLightEmission(const util::SurfacePoint& p,