Spotlight added
This commit is contained in:
parent
0a905edf0c
commit
41ae90b1b5
5 changed files with 71 additions and 5 deletions
|
@ -25,7 +25,7 @@ file(GLOB shader_src "shader/*.cpp")
|
||||||
|
|
||||||
# The tracey library
|
# The tracey library
|
||||||
add_library(tracey STATIC ${common_src} ${camera_src} ${light_src}
|
add_library(tracey STATIC ${common_src} ${camera_src} ${light_src}
|
||||||
${primitive_src} ${renderer_src} ${scene_src} ${shader_src} light/ambientlight.cpp light/ambientlight.h)
|
${primitive_src} ${renderer_src} ${scene_src} ${shader_src} light/ambientlight.cpp light/ambientlight.h light/spotlight.cpp light/spotlight.h)
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
target_link_libraries(tracey ${CMAKE_THREAD_LIBS_INIT} ${X11_LIBRARIES})
|
target_link_libraries(tracey ${CMAKE_THREAD_LIBS_INIT} ${X11_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
6
ex3.cpp
6
ex3.cpp
|
@ -52,13 +52,13 @@ int main() {
|
||||||
// compile in release mode)
|
// compile in release mode)
|
||||||
#ifdef OBJMODEL_FOUND
|
#ifdef OBJMODEL_FOUND
|
||||||
auto teapot0 = std::make_shared<ObjModel>(orange);
|
auto teapot0 = std::make_shared<ObjModel>(orange);
|
||||||
teapot0->loadObj("data/teapot.obj", Vector3d(2.0f, 2.0f, 2.0f), Vector3d(2.5f, -1.0f, 1.0f));
|
teapot0->loadObj("../data/teapot.obj", Vector3d(2.0f, 2.0f, 2.0f), Vector3d(2.5f, -1.0f, 1.0f));
|
||||||
|
|
||||||
auto teapot1 = std::make_shared<ObjModel>(red);
|
auto teapot1 = std::make_shared<ObjModel>(red);
|
||||||
teapot1->loadObj("data/teapot.obj", Vector3d(2.0f, 2.0f, 2.0f), Vector3d(-3.0f, 1.0f, 0.0f));
|
teapot1->loadObj("../data/teapot.obj", Vector3d(2.0f, 2.0f, 2.0f), Vector3d(-3.0f, 1.0f, 0.0f));
|
||||||
|
|
||||||
auto teapot2 = std::make_shared<ObjModel>(blue);
|
auto teapot2 = std::make_shared<ObjModel>(blue);
|
||||||
teapot2->loadObj("data/teapot.obj", Vector3d(2.0f, 2.0f, 2.0f), Vector3d(-0.5f, -3.0f, -2.0f));
|
teapot2->loadObj("../data/teapot.obj", Vector3d(2.0f, 2.0f, 2.0f), Vector3d(-0.5f, -3.0f, -2.0f));
|
||||||
|
|
||||||
scene.add(teapot0);
|
scene.add(teapot0);
|
||||||
scene.add(teapot1);
|
scene.add(teapot1);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
class AmbientLight : public Light{
|
class AmbientLight : public Light{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AmbientLight(float intensity, Color const &color = Color(1, 1, 1));
|
explicit AmbientLight(float intensity, Color const &color = Color(1, 1, 1));
|
||||||
|
|
||||||
Illumination illuminate(Scene const &scene, Ray const &ray) const override;
|
Illumination illuminate(Scene const &scene, Ray const &ray) const override;
|
||||||
|
|
||||||
|
|
45
light/spotlight.cpp
Normal file
45
light/spotlight.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include "light/spotlight.h"
|
||||||
|
#include "scene/scene.h"
|
||||||
|
|
||||||
|
SpotLight::SpotLight(Vector3d position, Vector3d direction, float innerAngle, float outerAngle, float intensity,
|
||||||
|
const Color &color) : Light(intensity, color), position(position), direction(direction),
|
||||||
|
innerAngle(innerAngle), outerAngle(outerAngle) {};
|
||||||
|
|
||||||
|
Light::Illumination SpotLight::illuminate(Scene const &scene, Ray const &ray) const {
|
||||||
|
// Calculate distance to surface
|
||||||
|
Vector3d const x = ray.origin + (ray.length - SPLT_EPS) * ray.direction;
|
||||||
|
|
||||||
|
// Illumination object
|
||||||
|
Illumination illum;
|
||||||
|
illum.direction = normalized(x - this->position);
|
||||||
|
|
||||||
|
// Precompute the distance from the light source
|
||||||
|
float const distance = length(x - this->position);
|
||||||
|
|
||||||
|
// Define a secondary ray from the surface point to the light source.
|
||||||
|
Ray lightRay;
|
||||||
|
lightRay.origin = x;
|
||||||
|
lightRay.direction = -illum.direction;
|
||||||
|
lightRay.length = distance - SPLT_EPS;
|
||||||
|
|
||||||
|
//calculate angle
|
||||||
|
float angle = acos(dotProduct(x - this->position, this->direction) / (length(x - this->position)
|
||||||
|
* length(this->direction)));
|
||||||
|
|
||||||
|
if (!scene.findOcclusion(lightRay)) { // If the target is not in shadow...
|
||||||
|
|
||||||
|
// ... compute the attenuation and light color
|
||||||
|
if (angle > outerAngle * (PI / 180)) {
|
||||||
|
illum.color = Color(0, 0, 0);
|
||||||
|
} else if (angle > innerAngle * (PI / 180)) {
|
||||||
|
float outerIllumRange = (outerAngle - innerAngle) * (PI / 180);
|
||||||
|
float leftOverAngle = angle - innerAngle * (PI / 180);
|
||||||
|
float percentageOfAngle = leftOverAngle / outerIllumRange;
|
||||||
|
float illumValue = 1 - percentageOfAngle;
|
||||||
|
illum.color = (1.0f / (distance * distance) * this->color * this->intensity) * illumValue;
|
||||||
|
} else {
|
||||||
|
illum.color = 1.0f / (distance * distance) * this->color * this->intensity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return illum;
|
||||||
|
}
|
21
light/spotlight.h
Normal file
21
light/spotlight.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef CG1_TRACER_SPOTLIGHT_H
|
||||||
|
#define CG1_TRACER_SPOTLIGHT_H
|
||||||
|
|
||||||
|
#include "light/light.h"
|
||||||
|
|
||||||
|
class SpotLight : public Light{
|
||||||
|
|
||||||
|
public:
|
||||||
|
SpotLight(Vector3d position, Vector3d direction, float innerAngle, float outerAngle,float intensity, Color const &color = Color(1, 1, 1));
|
||||||
|
|
||||||
|
Illumination illuminate(Scene const &scene, Ray const &ray) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Vector3d direction;
|
||||||
|
Vector3d position;
|
||||||
|
float innerAngle;
|
||||||
|
float outerAngle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CG1_TRACER_SPOTLIGHT_H
|
Loading…
Reference in a new issue