aboutsummaryrefslogtreecommitdiff
path: root/src/illuminate/illuminate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/illuminate/illuminate.cpp')
-rw-r--r--src/illuminate/illuminate.cpp272
1 files changed, 31 insertions, 241 deletions
diff --git a/src/illuminate/illuminate.cpp b/src/illuminate/illuminate.cpp
index 39ecccb..641f06d 100644
--- a/src/illuminate/illuminate.cpp
+++ b/src/illuminate/illuminate.cpp
@@ -1,50 +1,7 @@
#include <iostream>
#include "raytracer/raytracer.h"
-glm::vec4 RayTracer::illuminationFromPointLight(
- const SceneLightData &light,
- glm::vec4 intersectionWorld,
- glm::vec4 normalWorld,
- glm::vec4 directionToCamera,
- const RenderShapeData &shape,
- const RayTraceScene &scene
- )
-{
- auto directionFromIntersectionToLight = light.pos - intersectionWorld;
- directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
-
- // check if this light is blocked by an object
- auto distanceToLight = glm::distance(light.pos, intersectionWorld);
- bool isShadow = RayTracer::isShadowed(
- light.pos,
- distanceToLight,
- glm::vec4(directionFromIntersectionToLight),
- glm::vec4(intersectionWorld),
- scene);
- if (isShadow)
- {
- // if this is a shadow, then no light contribution
- return glm::vec4(0.f);
- }
-
- // calculate attenuation
- float c1 = light.function.x;
- float c2 = light.function.y;
- float c3 = light.function.z;
- float attenuation = std::min(1.f, 1.f / (c1 + distanceToLight * c2 + (distanceToLight * distanceToLight) * c3));
-
- return phong(
- light.color,
- attenuation,
- directionFromIntersectionToLight,
- directionToCamera,
- intersectionWorld,
- normalWorld,
- shape,
- scene);
-}
-
-glm::vec4 RayTracer::illuminationFromSpotLight(
+glm::vec4 RayTracer::illuminationFromDirectionalLight(
const SceneLightData &light,
glm::vec4 intersectionWorld,
glm::vec4 normalWorld,
@@ -53,108 +10,42 @@ glm::vec4 RayTracer::illuminationFromSpotLight(
const RayTraceScene &scene
)
{
- auto distance = glm::distance(light.pos, intersectionWorld);
+ // define direction and distance of directional light
+ auto directionFromIntersectionToLight = - light.dir;
+ directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
+ float distanceToLight = FINF; // directional light infinitely far away
- // calculate the angle from the shape to the spot light
- auto directionFromIntersectionToLight = glm::normalize(light.pos - intersectionWorld);
+ float kd = scene.getGlobalData().kd;
+ float ks = scene.getGlobalData().ks;
+ auto material = shape.primitive.material;
- // calculate intensity, based on angle. apply falloff if necessary
- auto lightDirection = glm::normalize(light.dir);
- // invert the direction of the intersection to light for dot product to work correctly
- auto cosTheta = glm::dot(-directionFromIntersectionToLight, lightDirection);
- auto theta = glm::acos(cosTheta);
+ glm::vec4 illumination(0, 0, 0, 1.f);
- // determine intensity, based on location on spot cone
- glm::vec4 intensity;
- float inner = light.angle - light.penumbra;
- if (theta <= inner)
- {
- intensity = light.color;
- }
- else if
- (
- theta > inner
- && theta <= light.angle
- )
- {
- // inside the penumbra, need to apply falloff
- float falloff = -2 * std::pow(theta - inner, 3) / std::pow(light.penumbra, 3) +
- 3 * std::pow(theta - inner, 2) / std::pow(light.penumbra, 2);
- intensity = light.color * (1 - falloff);
- }
- else // theta > light.angle
- {
- return glm::vec4(0.f);
+ // calculate diffuse term
+ auto dotDiffuse = glm::dot(normalWorld, directionFromIntersectionToLight);
+ if (dotDiffuse < 0) {
+ return illumination;
}
+ // add the diffuse
+ auto diffuse = (kd * material.cDiffuse);
+ illumination += light.color * dotDiffuse * diffuse;
- // if the light is within the cone, see if it's a shadow
- auto distanceToLight = glm::distance(light.pos, intersectionWorld);
- bool isShadow = RayTracer::isShadowed(
- light.pos,
- distanceToLight,
- glm::vec4(directionFromIntersectionToLight),
- glm::vec4(intersectionWorld),
- scene);
- if (isShadow)
- {
- // if this is a shadow, then no light contribution
- return glm::vec4(0.f);
+ // if the obj has no specular, return
+ if (material.cSpecular == glm::vec4(0.f)) {
+ return illumination;
}
- // calculate attenuation
- float c1 = light.function.x;
- float c2 = light.function.y;
- float c3 = light.function.z;
- float attenuation = std::min(1.f, 1.f / (c1 + distance * c2 + (distance * distance) * c3));
+ // get the light reflection vector
+ auto reflectedDirOverNormal = glm::normalize(glm::reflect(directionFromIntersectionToLight, normalWorld));
- return phong(
- intensity,
- attenuation,
- directionFromIntersectionToLight,
- directionToCamera,
- intersectionWorld,
- normalWorld,
- shape,
- scene);
-}
-
-glm::vec4 RayTracer::illuminationFromDirectionalLight(
- const SceneLightData &light,
- glm::vec4 intersectionWorld,
- glm::vec4 normalWorld,
- glm::vec4 directionToCamera,
- const RenderShapeData &shape,
- const RayTraceScene &scene
-)
-{
- // define direction and distance of directional light
- auto directionFromIntersectionToLight = - light.dir;
- directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
- float distanceToLight = FINF; // directional light infinitely far away
-
- // check if an object blocks ours
- bool isShadow = RayTracer::isShadowed(
- light.pos,
- distanceToLight,
- directionFromIntersectionToLight,
- glm::vec4(intersectionWorld),
- scene);
- if (isShadow)
- {
- // if this is a shadow, then no light contribution
- return glm::vec4(0.f);
+ // calculate specular term
+ auto dotSpecular = glm::dot(reflectedDirOverNormal, -directionToCamera);
+ if (dotSpecular > 0) {
+ auto toPow = std::pow(dotSpecular, material.shininess);
+ illumination += light.color * toPow * (ks * material.cSpecular);
}
- float attenuation = 1.f; // directional lights don't attenuate
- return phong(
- light.color,
- attenuation,
- directionFromIntersectionToLight,
- directionToCamera,
- intersectionWorld,
- normalWorld,
- shape,
- scene);
+ return illumination;
}
@@ -182,125 +73,24 @@ glm::vec4 RayTracer::illuminatePixel(
for (const SceneLightData &light : scene.getLights()) {
switch (light.type) {
case LightType::LIGHT_POINT:
- illumination +=
- illuminationFromPointLight(light, intersectionWorld, normalWorld, directionToCamera, shape, scene);
continue;
case LightType::LIGHT_DIRECTIONAL:
illumination +=
illuminationFromDirectionalLight(light, intersectionWorld, normalWorld, directionToCamera, shape, scene);
continue;
case LightType::LIGHT_SPOT:
- illumination +=
- illuminationFromSpotLight(light, intersectionWorld, normalWorld, directionToCamera, shape, scene);
continue;
case LightType::LIGHT_AREA:
- illumination +=
- illuminationFromAreaLight(light, intersectionWorld, normalWorld, directionToCamera, shape, scene);
continue;
default:
continue;
}
}
- auto incidentDir = -directionToCamera;
+ // auto incidentDir = -directionToCamera;
// recursive raytracing for the reflection and refraction (see reflect.cpp)
- illumination += refract(intersectionWorld, normalWorld, incidentDir, shape, scene, depth + 1);
- illumination += reflect(intersectionWorld, normalWorld, incidentDir, shape, scene, depth + 1);
+ // illumination += refract(intersectionWorld, normalWorld, incidentDir, shape, scene, depth + 1);
+ // illumination += reflect(intersectionWorld, normalWorld, incidentDir, shape, scene, depth + 1);
return illumination;
-}
-
-// helper function to handle the diffuse and specular terms
-// also handles the texture within that diffuse term
-glm::vec4 RayTracer::phong(
- glm::vec4 lightColor,
- float attenuation,
- glm::vec4 directionFromIntersectionToLight,
- glm::vec4 directionToCamera,
- glm::vec4 intersectionWorld,
- glm::vec4 normalWorld,
- const RenderShapeData &shape,
- const RayTraceScene &scene)
-{
- float kd = scene.getGlobalData().kd;
- float ks = scene.getGlobalData().ks;
- auto material = shape.primitive.material;
-
- glm::vec4 illumination(0.f);
-
- // calculate diffuse term
- auto dotDiffuse = glm::dot(normalWorld, directionFromIntersectionToLight);
- if (dotDiffuse > 0) // ensure not facing away
- {
- auto diffuse = (kd * material.cDiffuse);
- // commenting out texture stuff bc 4d textures??????
-// if (material.textureMap.isUsed)
-// {
-// glm::vec4 pObject = shape.inverseCTM * glm::vec4(intersectionWorld, 1.f);
-// diffuse = interpolateTexture(pObject, shape, diffuse);
-// }
- illumination += (attenuation * lightColor) * dotDiffuse * diffuse;
- }
-
- // add specular term
- auto reflectedDirOverNormal =
- 2 * glm::dot(directionFromIntersectionToLight, normalWorld) * normalWorld -
- directionFromIntersectionToLight;
- auto dotSpecular = glm::dot(reflectedDirOverNormal, directionToCamera);
- auto toPow = std::pow(dotSpecular, material.shininess);
- if (dotSpecular > 0) {
- illumination += (attenuation * lightColor) * toPow * (ks * material.cSpecular);
- }
-
- return illumination;
-}
-
-// EXTRA CREDIT -> AREA LIGHT
-glm::vec4 RayTracer::illuminationFromAreaLight(
- const SceneLightData &light,
- glm::vec4 intersectionWorld,
- glm::vec4 normalWorld,
- glm::vec4 directionToCamera,
- const RenderShapeData &shape,
- const RayTraceScene &scene
-) {
- // select a random point within the light's height and width
- float width = light.width;
- float height = light.height;
- float x = ((float) rand() / (float) RAND_MAX) * width - width / 2.f;
- float y = ((float) rand() / (float) RAND_MAX) * height - height / 2.f;
- glm::vec4 lightPosition = light.pos + glm::vec4(x, y, 0.f, 0.f);
-
- auto directionFromIntersectionToLight = lightPosition - intersectionWorld;
- directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
-
- // check if this light is blocked by an object
- auto distanceToLight = glm::distance(lightPosition, intersectionWorld);
- bool isShadow = RayTracer::isShadowed(
- lightPosition,
- distanceToLight,
- glm::vec4(directionFromIntersectionToLight),
- glm::vec4(intersectionWorld),
- scene);
- if (isShadow)
- {
- // if this is a shadow, then show a ray to a random point in the light
- return glm::vec4(0.f);
- }
-
- // calculate attenuation
- float c1 = light.function.x;
- float c2 = light.function.y;
- float c3 = light.function.z;
- float attenuation = std::min(1.f, 1.f / (c1 + distanceToLight * c2 + (distanceToLight * distanceToLight) * c3));
-
- return phong(
- light.color,
- attenuation,
- directionFromIntersectionToLight,
- directionToCamera,
- intersectionWorld,
- normalWorld,
- shape,
- scene);
-}
+} \ No newline at end of file