2023-01-24 11:31:09 +01:00
|
|
|
#include "sunlight.h"
|
|
|
|
|
|
|
|
|
|
|
|
SunLight::SunLight(Vector3d const &direction, float intensity, Color const &color) : Light(intensity, color),
|
|
|
|
direction(normalized(direction))
|
|
|
|
{}
|
|
|
|
|
|
|
|
Light::Illumination SunLight::illuminate(Scene const &scene, Ray const &ray) const
|
|
|
|
{
|
|
|
|
Vector3d const target = ray.origin + (ray.length - LGT_EPS) * ray.direction;
|
|
|
|
|
|
|
|
// Illumination object
|
|
|
|
Illumination illum;
|
|
|
|
illum.direction = this->direction;
|
2023-01-24 22:03:33 +01:00
|
|
|
illum.distance = INFINITY;
|
2023-01-24 11:31:09 +01:00
|
|
|
|
2023-01-27 05:22:43 +01:00
|
|
|
// Define a secondary ray from the surfa ce point to the light source.
|
2023-01-24 11:31:09 +01:00
|
|
|
Ray lightRay;
|
|
|
|
lightRay.origin = target;
|
|
|
|
lightRay.direction = -illum.direction;
|
|
|
|
lightRay.length = INFINITY;
|
|
|
|
|
|
|
|
// If the target is not in shadow...
|
|
|
|
if (!scene.findOcclusion(lightRay))
|
|
|
|
{
|
|
|
|
// Look at angleIntensity of light
|
2023-01-27 05:22:43 +01:00
|
|
|
float angleIntensity = 1;
|
|
|
|
// Only if normal is relevant, calculate angleIntensity
|
|
|
|
if (ray.normal != Vector3d(0, 0, 0))
|
|
|
|
angleIntensity = dotProduct(-ray.normal, this->direction); // 0 if light is behind surface, 1 if light is in front of surface
|
2023-01-24 21:11:30 +01:00
|
|
|
|
|
|
|
Color rayTransparency = scene.getTransparency(lightRay, INFINITY);
|
|
|
|
illum.color = this->color * this->intensity * angleIntensity * rayTransparency;
|
2023-01-24 11:31:09 +01:00
|
|
|
}
|
|
|
|
return illum;
|
|
|
|
}
|