2022-11-11 14:39:48 +01:00
|
|
|
#include "light/pointlight.h"
|
|
|
|
#include "scene/scene.h"
|
|
|
|
|
|
|
|
PointLight::PointLight(Vector3d const &position, float intensity, Color const &color) : Light(intensity, color), position(position) {}
|
|
|
|
|
|
|
|
Light::Illumination PointLight::illuminate(Scene const &scene, Ray const &ray) const {
|
2022-11-18 11:43:53 +01:00
|
|
|
Vector3d const target = ray.origin + (ray.length - LGT_EPS) * ray.direction;
|
2022-11-11 14:39:48 +01:00
|
|
|
|
2022-11-18 11:43:53 +01:00
|
|
|
// Illumination object
|
|
|
|
Illumination illum;
|
|
|
|
illum.direction = normalized(target - this->position);
|
2022-11-11 14:39:48 +01:00
|
|
|
|
2022-11-18 11:43:53 +01:00
|
|
|
// Precompute the distance from the light source
|
|
|
|
float const distance = length(target - this->position);
|
2022-11-11 14:39:48 +01:00
|
|
|
|
2022-11-18 11:43:53 +01:00
|
|
|
// Define a secondary ray from the surface point to the light source.
|
|
|
|
Ray lightRay;
|
|
|
|
lightRay.origin = target;
|
|
|
|
lightRay.direction = -illum.direction;
|
|
|
|
lightRay.length = distance - LGT_EPS;
|
2022-11-11 14:39:48 +01:00
|
|
|
|
2022-11-18 11:43:53 +01:00
|
|
|
// If the target is not in shadow...
|
2023-01-24 21:11:30 +01:00
|
|
|
if (!scene.findOcclusion(lightRay)) {
|
2022-11-18 11:43:53 +01:00
|
|
|
// ... compute the attenuation and light color
|
2023-01-24 21:11:30 +01:00
|
|
|
Color rayTransparency = scene.getTransparency(lightRay, distance);
|
|
|
|
illum.color = 1.0f / (distance * distance) * this->color * this->intensity * rayTransparency;
|
|
|
|
}
|
2022-11-11 14:39:48 +01:00
|
|
|
return illum;
|
|
|
|
}
|