diff --git a/CMakeLists.txt b/CMakeLists.txt index f2e5585..621f203 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,5 +35,6 @@ endif() add_executable(tracey_ex1 ex1.cpp) target_link_libraries(tracey_ex1 tracey) - +add_executable(tracey_ex2 ex2.cpp) +target_link_libraries(tracey_ex2 tracey) diff --git a/ex2.cpp b/ex2.cpp new file mode 100644 index 0000000..637dba9 --- /dev/null +++ b/ex2.cpp @@ -0,0 +1,57 @@ +#include "camera/perspectivecamera.h" + +#include "renderer/simplerenderer.h" + +#include "scene/simplescene.h" + +#include "primitive/box.h" +#include "primitive/infiniteplane.h" +#include "primitive/sphere.h" +#include "primitive/triangle.h" + +#include "shader/mirrorshader.h" +#include "shader/refractionshader.h" +#include "shader/simpleshadowshader.h" + +#include "light/pointlight.h" + +int main() +{ + // Let's create a simple cornell box scene... + SimpleScene scene; + scene.setEnvironmentMap(std::make_shared("data/lion_env.png")); + + auto mirror = std::make_shared(); + auto glass = std::make_shared(1.31f, 1.0f); + + // add some lights + scene.add(std::make_shared(Vector3d(0.0f, 10.0f, -10.0f), 250.f, Color(1.0f, 1.0f, 1.0f))); + scene.add(std::make_shared(Vector3d(0.0f, 10.0f, 10.0f), 250.f, Color(1.0f, 1.0f, 1.0f))); + + // Add shaders for the objects + auto orange = std::make_shared(Color(1.0f, 0.5f, 0.0f)); + auto red = std::make_shared(Color(1.0f, 0.3f, 0.2f)); + + // Add objects + scene.add(std::make_shared(Vector3d(-3.0f, 0.0f, 0.0f), 1.5f, glass)); + scene.add(std::make_shared(Vector3d(3.5f, -1.0f, 0.0f), Vector3d(3.0f, 3.0f, 3.0f), mirror)); + scene.add(std::make_shared(Vector3d(5.0f, -5.0f, 5.0f), Vector3d(-10.0f, -5.0f, 10.0f), + Vector3d(-2.0f, -5.0f, -2.0f), orange)); + scene.add(std::make_shared(Vector3d(-2.0f, -5.0f, -2.0f), Vector3d(10.0f, -5.0f, -10.0f), + Vector3d(5.0f, -5.0f, 5.0f), orange)); + scene.add(std::make_shared(Vector3d(0.0f, -2.0f, 0.0f), Vector3d(2.0f, -2.0f, 0.0f), + Vector3d(0.0f, 0.0f, 0.0f), red)); + + // Set up the camera + PerspectiveCamera camera; + camera.setFovAngle(70.0f); + camera.setPosition(Vector3d(-2.5f, 2.5f, -10.0f)); + camera.setForwardDirection(Vector3d(0.4f, -0.33f, 1.0f)); + camera.setUpDirection(Vector3d(0.0f, 1.0f, 0.0f)); + + // Render the scene + SimpleRenderer renderer; + renderer.renderImage(scene, camera, 1024, 768).save("result.png"); + + return 0; +} diff --git a/light/pointlight.cpp b/light/pointlight.cpp new file mode 100644 index 0000000..936ea7a --- /dev/null +++ b/light/pointlight.cpp @@ -0,0 +1,24 @@ +#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 +{ + // IMPLEMENT ME + // Get the point on the surface + + // Create an instance of the Illumination object, fill in the direction (from + // surface point to light source) + Light::Illumination illum; + + // Define a secondary ray from the surface point to the light source. + + // If the target is not in shadow... (use scene.findOcclusion()) + + // Compute the brightness-color of this light using inverse squared distance + // to light source (i.e. 1/(d^2)), the color of this light source and the + // intensity + + return illum; +} diff --git a/light/pointlight.h b/light/pointlight.h new file mode 100644 index 0000000..e50d88e --- /dev/null +++ b/light/pointlight.h @@ -0,0 +1,22 @@ +#ifndef POINTLIGHT_H +#define POINTLIGHT_H + +#include "light/light.h" + +class PointLight : public Light +{ + +public: + PointLight(Vector3d const &position, float intensity, Color const &color = Color(1, 1, 1)); + + // Set + void setPosition(Vector3d const &position) { this->position = position; } + + // Light functions + Illumination illuminate(Scene const &scene, Ray const &ray) const override; + +protected: + Vector3d position; +}; + +#endif diff --git a/primitive/box.cpp b/primitive/box.cpp new file mode 100644 index 0000000..1596dc0 --- /dev/null +++ b/primitive/box.cpp @@ -0,0 +1,36 @@ +#include "common/ray.h" +#include "primitive/box.h" +#include +#include + +// Constructor ///////////////////////////////////////////////////////////////// + +Box::Box(std::shared_ptr const &shader) : Primitive(shader), size(Vector3d(1, 1, 1)) {} + +Box::Box(Vector3d const ¢er, Vector3d const &size, std::shared_ptr const &shader) + : Primitive(shader), center(center), size(size) {} + +// Primitive functions ///////////////////////////////////////////////////////// + +bool Box::intersect(Ray &ray) const +{ + // IMPLEMENT ME! + + // Determine whether the ray intersects the box + + // Test whether this is the foremost primitive in front of the camera + + // (Optional for now) Calculate the normal + + // (Optional for now) Calculate the surface position + + // Set the new length and the current primitive + + return false; +} + +// Bounding box //////////////////////////////////////////////////////////////// + +float Box::minimumBounds(int dimension) const { return this->center[dimension] - this->size[dimension] / 2; } + +float Box::maximumBounds(int dimension) const { return this->center[dimension] + this->size[dimension] / 2; } diff --git a/primitive/box.h b/primitive/box.h new file mode 100644 index 0000000..6d171e0 --- /dev/null +++ b/primitive/box.h @@ -0,0 +1,30 @@ +#ifndef BOX_H +#define BOX_H + +#include "primitive/primitive.h" + +class Box : public Primitive +{ + +public: + // Constructor + Box(std::shared_ptr const &shader); + Box(Vector3d const ¢er, Vector3d const &size, std::shared_ptr const &shader); + + // Set + void setCenter(Vector3d const ¢er) { this->center = center; } + void setSize(Vector3d const &size) { this->size = size; } + + // Primitive functions + bool intersect(Ray &ray) const override; + + // Bounding box + float minimumBounds(int dimension) const override; + float maximumBounds(int dimension) const override; + +protected: + Vector3d center; + Vector3d size; +}; + +#endif diff --git a/shader/mirrorshader.cpp b/shader/mirrorshader.cpp new file mode 100644 index 0000000..8c035a7 --- /dev/null +++ b/shader/mirrorshader.cpp @@ -0,0 +1,13 @@ +#include "scene/scene.h" +#include "shader/mirrorshader.h" + +MirrorShader::MirrorShader() {} + +Color MirrorShader::shade(Scene const &scene, Ray const &ray) const +{ + // IMPLEMENT ME + // Calculate the reflection vector + // Create a new reflection ray + // Send the new ray out into the scene and return the result + return Color(0, 0, 1); +} diff --git a/shader/mirrorshader.h b/shader/mirrorshader.h new file mode 100644 index 0000000..1424043 --- /dev/null +++ b/shader/mirrorshader.h @@ -0,0 +1,17 @@ +#ifndef MIRRORSHADER_H +#define MIRRORSHADER_H + +#include "shader/shader.h" + +class MirrorShader : public Shader +{ + +public: + // Constructor + MirrorShader(); + + // Shader functions + Color shade(Scene const &scene, Ray const &ray) const override; +}; + +#endif diff --git a/shader/refractionshader.cpp b/shader/refractionshader.cpp new file mode 100644 index 0000000..86917e6 --- /dev/null +++ b/shader/refractionshader.cpp @@ -0,0 +1,16 @@ +#include "scene/scene.h" +#include "shader/refractionshader.h" + +RefractionShader::RefractionShader(float indexInside, float indexOutside) : indexInside(indexInside), indexOutside(indexOutside) {} + +Color RefractionShader::shade(Scene const &scene, Ray const &ray) const +{ + // IMPLEMENT ME + // Calculate the refracted ray using the surface normal vector and + // indexInside, indexOutside + // Also check for total internal reflection + // Send out a new refracted ray into the scene; recursively call traceRay() + return Color(1, 0, 0); +} + +bool RefractionShader::isTransparent() const { return true; } diff --git a/shader/refractionshader.h b/shader/refractionshader.h new file mode 100644 index 0000000..449bd2c --- /dev/null +++ b/shader/refractionshader.h @@ -0,0 +1,22 @@ +#ifndef REFRACTIONSHADER_H +#define REFRACTIONSHADER_H + +#include "shader/shader.h" + +class RefractionShader : public Shader +{ + +public: + // Constructor + RefractionShader(float indexInside, float indexOutside); + + // Shader functions + Color shade(Scene const &scene, Ray const &ray) const override; + bool isTransparent() const override; + +private: + float indexInside; + float indexOutside; +}; + +#endif diff --git a/shader/simpleshadowshader.cpp b/shader/simpleshadowshader.cpp new file mode 100644 index 0000000..d725e1b --- /dev/null +++ b/shader/simpleshadowshader.cpp @@ -0,0 +1,13 @@ +#include "light/light.h" +#include "scene/scene.h" +#include "shader/simpleshadowshader.h" + +SimpleShadowShader::SimpleShadowShader(Color const &objectColor) : objectColor(objectColor) {} + +Color SimpleShadowShader::shade(Scene const &scene, Ray const &ray) const +{ + // IMPLEMENT ME + // loop over all light sources to check for visibility and multiply "light + // strength" with this objects albedo (color) + return Color(0, 1, 0); +} diff --git a/shader/simpleshadowshader.h b/shader/simpleshadowshader.h new file mode 100644 index 0000000..de77c12 --- /dev/null +++ b/shader/simpleshadowshader.h @@ -0,0 +1,20 @@ +#ifndef SIMPLESHADOWSHADER_H +#define SIMPLESHADOWSHADER_H + +#include "shader/shader.h" + +class SimpleShadowShader : public Shader +{ + +public: + // Constructor + SimpleShadowShader(Color const &objectColor); + + // Shader functions + Color shade(Scene const &scene, Ray const &ray) const override; + +private: + Color objectColor; +}; + +#endif