diff --git a/.gitpod.yml b/.gitpod.yml index 8dd80f1..4b5f6d9 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -7,6 +7,5 @@ tasks: cmake .. && make && ./tinyraytracer && - pnmtopng out.ppm > out.png && - open out.png && + open out.jpg && cd .. diff --git a/Readme.md b/Readme.md index 09fb58d..4752387 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,8 @@ # compilation git clone https://github.com/ssloy/tinyraytracer.git cd tinyraytracer +git checkout homework_assignment +git submodule update mkdir build cd build cmake .. diff --git a/tinyraytracer.cpp b/tinyraytracer.cpp index 793a334..b581274 100644 --- a/tinyraytracer.cpp +++ b/tinyraytracer.cpp @@ -1,8 +1,11 @@ -#include +#define _USE_MATH_DEFINES #include +#include #include #include #include +#include + #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" #define STB_IMAGE_IMPLEMENTATION @@ -16,13 +19,13 @@ std::vector envmap; Model duck("../duck.obj"); struct Light { - Light(const Vec3f &p, const float &i) : position(p), intensity(i) {} + Light(const Vec3f &p, const float i) : position(p), intensity(i) {} Vec3f position; float intensity; }; struct Material { - Material(const float &r, const Vec4f &a, const Vec3f &color, const float &spec) : refractive_index(r), albedo(a), diffuse_color(color), specular_exponent(spec) {} + Material(const float r, const Vec4f &a, const Vec3f &color, const float spec) : refractive_index(r), albedo(a), diffuse_color(color), specular_exponent(spec) {} Material() : refractive_index(1), albedo(1,0,0,0), diffuse_color(), specular_exponent() {} float refractive_index; Vec4f albedo; @@ -35,7 +38,7 @@ struct Sphere { float radius; Material material; - Sphere(const Vec3f &c, const float &r, const Material &m) : center(c), radius(r), material(m) {} + Sphere(const Vec3f &c, const float r, const Material &m) : center(c), radius(r), material(m) {} bool ray_intersect(const Vec3f &orig, const Vec3f &dir, float &t0) const { Vec3f L = center - orig; @@ -55,21 +58,14 @@ Vec3f reflect(const Vec3f &I, const Vec3f &N) { return I - N*2.f*(I*N); } -Vec3f refract(const Vec3f &I, const Vec3f &N, const float &refractive_index) { // Snell's law +Vec3f refract(const Vec3f &I, const Vec3f &N, const float eta_t, const float eta_i=1.f) { // Snell's law float cosi = - std::max(-1.f, std::min(1.f, I*N)); - float etai = 1, etat = refractive_index; - Vec3f n = N; - if (cosi < 0) { // if the ray is inside the object, swap the indices and invert the normal to get the correct result - cosi = -cosi; - std::swap(etai, etat); n = -N; - } - float eta = etai / etat; + if (cosi<0) return refract(I, -N, eta_i, eta_t); // if the ray comes from the inside the object, swap the air and the media + float eta = eta_i / eta_t; float k = 1 - eta*eta*(1 - cosi*cosi); - return k < 0 ? Vec3f(0,0,0) : I*eta + n*(eta * cosi - sqrtf(k)); + return k<0 ? Vec3f(1,0,0) : I*eta + N*(eta*cosi - sqrtf(k)); // k<0 = total reflection, no ray to refract. I refract it anyways, this has no physical meaning } - - bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector &spheres, Vec3f &hit, Vec3f &N, Material &material) { float spheres_dist = std::numeric_limits::max(); for (size_t i=0; i < spheres.size(); i++) { @@ -90,8 +86,7 @@ bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector &s } void render(const std::vector &spheres, const std::vector &lights) { - const int width = 1024; - const int height = 768; - const int fov = M_PI/2.; + const int width = 1024; + const int height = 768; + const float fov = M_PI/3.; std::vector framebuffer(width*height); #pragma omp parallel for - for (size_t j = 0; j