diff --git a/disk.hpp b/disk.hpp index feb01d7..4471e25 100644 --- a/disk.hpp +++ b/disk.hpp @@ -13,20 +13,11 @@ class Disk : public Plane { public: float m_radius; - Disk(): m_radius(1.0f) { - m_point = vec3(0.0f); - m_normal = vec3(0.0f, 1.0f, 0.0f); - } + Disk(BRDF * _brdf = NULL): Plane(_brdf), m_radius(1.0f) { } - Disk(float x, float y, float z, float nx, float ny, float nz, float _r): m_radius(_r) { - m_point = vec3(x, y, z); - m_normal = normalize(vec3(nx, ny, nz)); - } + Disk(float x, float y, float z, float nx, float ny, float nz, float _r, BRDF * _brdf = NULL): Plane(x, y, z, nx, ny, nz, _brdf), m_radius(_r) { } - Disk(vec3 _p, vec3 _n, float _r): m_radius(_r) { - m_point = _p; - m_normal = normalize(_n); - } + Disk(vec3 _p, vec3 _n, float _r, BRDF * _brdf = NULL): Plane(_p, _n, _brdf), m_radius(_r) { } virtual ~Disk() { } diff --git a/figure.hpp b/figure.hpp index 23f7f66..b047978 100644 --- a/figure.hpp +++ b/figure.hpp @@ -11,9 +11,15 @@ using glm::vec3; class Figure { public: - Material m_mat; + Material * m_mat; - virtual ~Figure() { } + Figure(BRDF * brdf = NULL) { + m_mat = new Material(brdf); + } + + virtual ~Figure() { + delete m_mat; + } virtual bool intersect(Ray & r, float & t) const = 0; virtual vec3 normal_at_int(Ray & r, float & t) const = 0; diff --git a/main.cpp b/main.cpp index d2becff..469e5d7 100644 --- a/main.cpp +++ b/main.cpp @@ -292,56 +292,56 @@ void scene_1(vector
& vf, vector & vl, mat4x4 & i_model_view) DirectionalLight * l; s = new Sphere(1.0f, 1.0f, -2.0f, 0.5f); - s->m_mat.m_diffuse = vec3(1.0f, 0.0f, 0.0f); + s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 0.0f); vf.push_back(static_cast
(s)); s = new Sphere(-1.0f, 1.0f, -2.0f, 0.5f); - s->m_mat.m_diffuse = vec3(0.0f, 1.0f, 0.0f); + s->m_mat->m_diffuse = vec3(0.0f, 1.0f, 0.0f); vf.push_back(static_cast
(s)); s = new Sphere(1.0f, -1.0f, -2.0f, 0.5f); - s->m_mat.m_diffuse = vec3(0.0f, 0.0f, 1.0f); + s->m_mat->m_diffuse = vec3(0.0f, 0.0f, 1.0f); vf.push_back(static_cast
(s)); s = new Sphere(-1.0f, -1.0f, -2.0f, 0.5f); - s->m_mat.m_diffuse = vec3(1.0f, 0.0f, 1.0f); + s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f); vf.push_back(static_cast
(s)); s = new Sphere(0.0f, 0.0f, -2.0f, 1.0f); - s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f); + s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f); vf.push_back(static_cast
(s)); p = new Plane(vec3(0.0f, -1.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); - p->m_mat.m_diffuse = vec3(1.0f, 0.5f, 0.4f); + p->m_mat->m_diffuse = vec3(1.0f, 0.5f, 0.4f); vf.push_back(static_cast
(p)); s = new Sphere(-1.5f, 0.0f, -2.0f, 0.5f); - s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f); - s->m_mat.m_rho = 0.3f; + s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 1.0f); + s->m_mat->m_rho = 0.3f; vf.push_back(static_cast
(s)); s = new Sphere(1.5f, 0.0f, -2.0f, 0.5f); - s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f); - s->m_mat.m_rho = 0.08f; - s->m_mat.m_refract = true; - s->m_mat.m_ref_index = 1.1f; + s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 1.0f); + s->m_mat->m_rho = 0.08f; + s->m_mat->m_refract = true; + s->m_mat->m_ref_index = 1.1f; vf.push_back(static_cast
(s)); s = new Sphere(0.0f, 1.5f, -2.0f, 0.5f); - s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f); - s->m_mat.m_rho = 0.5f; + s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 1.0f); + s->m_mat->m_rho = 0.5f; vf.push_back(static_cast
(s)); s = new Sphere(0.0f, 0.0f, -1.0f, 0.25f); - s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f); - s->m_mat.m_rho = 0.1f; + s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 1.0f); + s->m_mat->m_rho = 0.1f; vf.push_back(static_cast
(s)); d = new Disk(vec3(-0.0f, -0.0f, -0.5f), vec3(0.0f, 0.0f, 0.1f), 0.25f); - d->m_mat.m_diffuse = vec3(1.0f, 0.0f, 0.0f); - d->m_mat.m_rho = 0.3f; - d->m_mat.m_refract = true; - d->m_mat.m_ref_index = 1.33f; + d->m_mat->m_diffuse = vec3(1.0f, 0.0f, 0.0f); + d->m_mat->m_rho = 0.3f; + d->m_mat->m_refract = true; + d->m_mat->m_ref_index = 1.33f; vf.push_back(static_cast
(d)); l = new DirectionalLight(); @@ -367,59 +367,59 @@ void scene_2(vector
& vf, vector & vl, mat4x4 & i_model_view) PointLight * l; s = new Sphere(0.2f, 0.0f, -0.75f, 0.25f); - s->m_mat.m_diffuse = vec3(1.0f); - s->m_mat.m_rho = 0.2f; + s->m_mat->m_diffuse = vec3(1.0f); + s->m_mat->m_rho = 0.2f; vf.push_back(static_cast
(s)); p = new Plane(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); - p->m_mat.m_diffuse = vec3(0.0f, 1.0f, 0.0f); + p->m_mat->m_diffuse = vec3(0.0f, 1.0f, 0.0f); vf.push_back(static_cast
(p)); p = new Plane(vec3(-2.0f, 0.0f, 0.0f), vec3(1.0f, 0.0f, 0.0f)); - p->m_mat.m_diffuse = vec3(1.0f, 0.0f, 0.0f); + p->m_mat->m_diffuse = vec3(1.0f, 0.0f, 0.0f); vf.push_back(static_cast
(p)); p = new Plane(vec3(2.0f, 0.0f, 0.0f), vec3(-1.0f, 0.0f, 0.0f)); - p->m_mat.m_diffuse = vec3(0.0f, 0.0f, 1.0f); + p->m_mat->m_diffuse = vec3(0.0f, 0.0f, 1.0f); vf.push_back(static_cast
(p)); p = new Plane(vec3(0.0f, 1.0f, 0.0f), vec3(0.0f, -1.0f, 0.0f)); - p->m_mat.m_diffuse = vec3(0.0f, 1.0f, 1.0f); + p->m_mat->m_diffuse = vec3(0.0f, 1.0f, 1.0f); vf.push_back(static_cast
(p)); p = new Plane(vec3(0.0f, 0.0f, -2.0f), vec3(0.0f, 0.0f, 1.0f)); - p->m_mat.m_diffuse = vec3(1.0f, 0.0f, 1.0f); + p->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f); vf.push_back(static_cast
(p)); p = new Plane(vec3(0.0f, 0.0f, 1.1f), vec3(0.0f, 0.0f, -1.0f)); - p->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f); + p->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f); vf.push_back(static_cast
(p)); s = new Sphere(-0.5f, -0.5f, -1.5f, 0.5f); - s->m_mat.m_diffuse = vec3(0.0f); - s->m_mat.m_rho = 1.0f; + s->m_mat->m_diffuse = vec3(0.0f); + s->m_mat->m_rho = 1.0f; vf.push_back(static_cast
(s)); s = new Sphere(-0.5f, -0.5f, 0.6f, 0.5f); - s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f); - s->m_mat.m_refract = true; - s->m_mat.m_ref_index = 1.33f; + s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f); + s->m_mat->m_refract = true; + s->m_mat->m_ref_index = 1.33f; vf.push_back(static_cast
(s)); d = new Disk(vec3(-0.25f, 1.0f, -1.0f), vec3(1.0f, 0.0f, 0.0f), 0.25f); - d->m_mat.m_diffuse = vec3(1.0f); + d->m_mat->m_diffuse = vec3(1.0f); vf.push_back(static_cast
(d)); d = new Disk(vec3(0.25f, 1.0f, -1.0f), vec3(-1.0f, 0.0f, 0.0f), 0.25f); - d->m_mat.m_diffuse = vec3(1.0f); + d->m_mat->m_diffuse = vec3(1.0f); vf.push_back(static_cast
(d)); d = new Disk(vec3(0.0f, 1.0f, -1.25f), vec3(0.0f, 0.0f, 1.0f), 0.25f); - d->m_mat.m_diffuse = vec3(1.0f); + d->m_mat->m_diffuse = vec3(1.0f); vf.push_back(static_cast
(d)); d = new Disk(vec3(0.0f, 1.0f, -0.75f), vec3(0.0f, 0.0f, -1.0f), 0.25f); - d->m_mat.m_diffuse = vec3(1.0f); + d->m_mat->m_diffuse = vec3(1.0f); vf.push_back(static_cast
(d)); l = new PointLight(); @@ -438,35 +438,35 @@ void scene_3(vector
& vf, vector & vl, mat4x4 & i_model_view) vec3 up = cross(center - eye, left); s = new Sphere(0.0f, -0.15f, -2.0f, 1.0f); - s->m_mat.m_diffuse = vec3(1.0f, 0.5f, 0.0f); - s->m_mat.m_specular = vec3(0.3f); - s->m_mat.m_shininess = 5.0f; - s->m_mat.m_rho = 0.4f; - s->m_mat.m_refract = true; - s->m_mat.m_ref_index = 1.33f; + s->m_mat->m_diffuse = vec3(1.0f, 0.5f, 0.0f); + s->m_mat->m_specular = vec3(0.3f); + s->m_mat->m_shininess = 5.0f; + s->m_mat->m_rho = 0.4f; + s->m_mat->m_refract = true; + s->m_mat->m_ref_index = 1.33f; vf.push_back(static_cast
(s)); s = new Sphere(0.0f, -0.15f, -2.0f, 0.5f); - s->m_mat.m_diffuse = vec3(0.0f); - s->m_mat.m_specular = vec3(0.0f); - s->m_mat.m_rho = 0.0f; - s->m_mat.m_refract = true; - s->m_mat.m_ref_index = 2.6f; + s->m_mat->m_diffuse = vec3(0.0f); + s->m_mat->m_specular = vec3(0.0f); + s->m_mat->m_rho = 0.0f; + s->m_mat->m_refract = true; + s->m_mat->m_ref_index = 2.6f; vf.push_back(static_cast
(s)); s = new Sphere(2.0f, 0.0f, -2.0f, 1.0f); - s->m_mat.m_diffuse = vec3(1.0f, 0.0f, 1.0f); - s->m_mat.m_rho = 1.0f; + s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f); + s->m_mat->m_rho = 1.0f; vf.push_back(static_cast
(s)); s = new Sphere(-1.0f, 0.25f, -3.25f, 1.0f); - s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f); - s->m_mat.m_shininess = 20.0f; + s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f); + s->m_mat->m_shininess = 20.0f; vf.push_back(static_cast
(s)); p = new Plane(vec3(0.0f, -1.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); - p->m_mat.m_diffuse = vec3(1.0f); - p->m_mat.m_specular = vec3(0.0f); + p->m_mat->m_diffuse = vec3(1.0f); + p->m_mat->m_specular = vec3(0.0f); vf.push_back(static_cast
(p)); l = new DirectionalLight(); @@ -500,11 +500,11 @@ void scene_4(vector
& vf, vector & vl, mat4x4 & i_model_view) Plane * p; s = new Sphere(0.0f, 0.0f, -2.0f, 1.0f); - s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f); + s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f); vf.push_back(static_cast
(s)); p = new Plane(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); - p->m_mat.m_diffuse = vec3(1.0f); - p->m_mat.m_specular = vec3(0.0f); + p->m_mat->m_diffuse = vec3(1.0f); + p->m_mat->m_specular = vec3(0.0f); vf.push_back(static_cast
(p)); } diff --git a/output.png b/output.png index 357304b..5c19ea2 100644 Binary files a/output.png and b/output.png differ diff --git a/path_tracer.cpp b/path_tracer.cpp index 688bdf8..f0ccd17 100644 --- a/path_tracer.cpp +++ b/path_tracer.cpp @@ -37,7 +37,7 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vectornormal_at_int(r, t); // Check if the material is not reflective/refractive. - if (!_f->m_mat.m_refract) { + if (!_f->m_mat->m_refract) { // Calculate the direct lighting. for (size_t l = 0; l < v_lights.size(); l++) { // For every light source @@ -53,8 +53,8 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vectordiffuse(n, r, i_pos, _f->m_mat) : vec3(0.0f); - dir_spec_color += vis ? v_lights[l]->specular(n, r, i_pos, _f->m_mat) : vec3(0.0f); + dir_diff_color += vis ? v_lights[l]->diffuse(n, r, i_pos, *_f->m_mat) : vec3(0.0f); + dir_spec_color += vis ? v_lights[l]->specular(n, r, i_pos, *_f->m_mat) : vec3(0.0f); } // Calculate indirect lighting contribution. @@ -88,18 +88,18 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vectorm_mat.m_diffuse / pi())) + (_f->m_mat.m_specular * dir_spec_color); + color += ((dir_diff_color + ind_color + amb_color) * (_f->m_mat->m_diffuse / pi())) + (_f->m_mat->m_specular * dir_spec_color); // Determine the specular reflection color. - if (_f->m_mat.m_rho > 0.0f && rec_level < m_max_depth) { + if (_f->m_mat->m_rho > 0.0f && rec_level < m_max_depth) { rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS); - color += _f->m_mat.m_rho * trace_ray(rr, v_figures, v_lights, rec_level + 1); - } else if (_f->m_mat.m_rho > 0.0f && rec_level >= m_max_depth) + color += _f->m_mat->m_rho * trace_ray(rr, v_figures, v_lights, rec_level + 1); + } else if (_f->m_mat->m_rho > 0.0f && rec_level >= m_max_depth) return vec3(0.0f); } else { // If the material has transmission enabled, calculate the Fresnel term. - kr = fresnel(r.m_direction, n, r.m_ref_index, _f->m_mat.m_ref_index); + kr = fresnel(r.m_direction, n, r.m_ref_index, _f->m_mat->m_ref_index); // Determine the specular reflection color. if (kr > 0.0f && rec_level < m_max_depth) { @@ -109,8 +109,8 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vectorm_mat.m_refract && kr < 1.0f && rec_level < m_max_depth) { - rr = Ray(normalize(refract(r.m_direction, n, r.m_ref_index / _f->m_mat.m_ref_index)), i_pos - n * BIAS, _f->m_mat.m_ref_index); + if (_f->m_mat->m_refract && kr < 1.0f && rec_level < m_max_depth) { + rr = Ray(normalize(refract(r.m_direction, n, r.m_ref_index / _f->m_mat->m_ref_index)), i_pos - n * BIAS, _f->m_mat->m_ref_index); color += (1.0f - kr) * trace_ray(rr, v_figures, v_lights, rec_level + 1); } else if (rec_level >= m_max_depth) return vec3(0.0f); diff --git a/plane.hpp b/plane.hpp index 5ac3baa..00e3ffa 100644 --- a/plane.hpp +++ b/plane.hpp @@ -14,11 +14,11 @@ public: vec3 m_point; vec3 m_normal; - Plane(): m_point(vec3(0.0f)), m_normal(0.0f, 0.0f, 1.0f) { } + Plane(BRDF * _brdf = NULL): Figure(_brdf), m_point(vec3(0.0f)), m_normal(vec3(0.0f, 0.0f, 1.0f)) { } - Plane(float x, float y, float z, float nx, float ny, float nz): m_point(vec3(x, y, z)), m_normal(normalize(vec3(nx, ny, nz))) { } + Plane(float x, float y, float z, float nx, float ny, float nz, BRDF * _brdf = NULL): Figure(_brdf), m_point(vec3(x, y, z)), m_normal(normalize(vec3(nx, ny, nz))) { } - Plane(vec3 _p, vec3 _n): m_point(_p), m_normal(normalize(_n)) { } + Plane(vec3 _p, vec3 _n, BRDF * _brdf = NULL): Figure(_brdf), m_point(_p), m_normal(normalize(_n)) { } virtual ~Plane() { } diff --git a/sphere.hpp b/sphere.hpp index 63092ea..555187e 100644 --- a/sphere.hpp +++ b/sphere.hpp @@ -13,11 +13,11 @@ public: vec3 m_center; float m_radius; - Sphere(): m_center(vec3(0.0f)), m_radius(0.5f) { } + Sphere(BRDF * _brdf = NULL): Figure(_brdf), m_center(vec3(0.0f)), m_radius(0.5f) { } - Sphere(float x, float y, float z, float r): m_center(vec3(x, y, z)), m_radius(r) { } + Sphere(float x, float y, float z, float r, BRDF * _brdf = NULL): Figure(_brdf), m_center(vec3(x, y, z)), m_radius(r) { } - Sphere(vec3 _c, float r): m_center(_c), m_radius(r) { } + Sphere(vec3 _c, float r, BRDF * _brdf = NULL): Figure(_brdf), m_center(_c), m_radius(r) { } virtual ~Sphere() { } diff --git a/whitted_tracer.cpp b/whitted_tracer.cpp index bae60bf..666cb11 100644 --- a/whitted_tracer.cpp +++ b/whitted_tracer.cpp @@ -35,7 +35,7 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector
& v_figures, vectornormal_at_int(r, t); // Check if the material is not reflective/refractive. - if (!_f->m_mat.m_refract) { + if (!_f->m_mat->m_refract) { // Calculate the direct lighting. for (size_t l = 0; l < v_lights.size(); l++) { // For every light source @@ -51,22 +51,22 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector
& v_figures, vectordiffuse(n, r, i_pos, _f->m_mat) : vec3(0.0f); - dir_spec_color += vis ? v_lights[l]->specular(n, r, i_pos, _f->m_mat) : vec3(0.0f); + dir_diff_color += vis ? v_lights[l]->diffuse(n, r, i_pos, *_f->m_mat) : vec3(0.0f); + dir_spec_color += vis ? v_lights[l]->specular(n, r, i_pos, *_f->m_mat) : vec3(0.0f); } - color += (dir_diff_color * (_f->m_mat.m_diffuse / pi())) + (_f->m_mat.m_specular * dir_spec_color); + color += (dir_diff_color * (_f->m_mat->m_diffuse / pi())) + (_f->m_mat->m_specular * dir_spec_color); // Determine the specular reflection color. - if (_f->m_mat.m_rho > 0.0f && rec_level < m_max_depth) { + if (_f->m_mat->m_rho > 0.0f && rec_level < m_max_depth) { rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS); - color += _f->m_mat.m_rho * trace_ray(rr, v_figures, v_lights, rec_level + 1); - } else if (_f->m_mat.m_rho > 0.0f && rec_level >= m_max_depth) + color += _f->m_mat->m_rho * trace_ray(rr, v_figures, v_lights, rec_level + 1); + } else if (_f->m_mat->m_rho > 0.0f && rec_level >= m_max_depth) return vec3(0.0f); } else { // If the material has transmission enabled, calculate the Fresnel term. - kr = fresnel(r.m_direction, n, r.m_ref_index, _f->m_mat.m_ref_index); + kr = fresnel(r.m_direction, n, r.m_ref_index, _f->m_mat->m_ref_index); // Determine the specular reflection color. if (kr > 0.0f && rec_level < m_max_depth) { @@ -76,8 +76,8 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector
& v_figures, vectorm_mat.m_refract && kr < 1.0f && rec_level < m_max_depth) { - rr = Ray(normalize(refract(r.m_direction, n, r.m_ref_index / _f->m_mat.m_ref_index)), i_pos - n * BIAS, _f->m_mat.m_ref_index); + if (_f->m_mat->m_refract && kr < 1.0f && rec_level < m_max_depth) { + rr = Ray(normalize(refract(r.m_direction, n, r.m_ref_index / _f->m_mat->m_ref_index)), i_pos - n * BIAS, _f->m_mat->m_ref_index); color += (1.0f - kr) * trace_ray(rr, v_figures, v_lights, rec_level + 1); } else if (rec_level >= m_max_depth) return vec3(0.0f);