diff --git a/Makefile b/Makefile index 6181002..250efd9 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CXX = g++ TARGET = ray -OBJECTS = main.o sampling.o camera.o disk.o plane.o sphere.o directional_light.o phong_brdf.o point_light.o spot_light.o tracer.o path_tracer.o whitted_tracer.o +OBJECTS = main.o sampling.o camera.o disk.o plane.o sphere.o phong_brdf.o hsa_brdf.o directional_light.o point_light.o spot_light.o tracer.o path_tracer.o whitted_tracer.o DEPENDS = $(OBJECTS:.o=.d) CXXFLAGS = -ansi -pedantic -Wall -DGLM_FORCE_RADIANS -fopenmp LDLIBS = -lfreeimage diff --git a/brdf.hpp b/brdf.hpp index e320fd0..5b8831e 100644 --- a/brdf.hpp +++ b/brdf.hpp @@ -12,8 +12,8 @@ class BRDF { public: virtual ~BRDF() { } - virtual vec3 diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 light_diff_color) const = 0; - virtual vec3 specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 light_spec_color, float shininess) const = 0; + virtual vec3 diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_diff_color) const = 0; + virtual vec3 specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_spec_color, float shininess) const = 0; }; #endif diff --git a/directional_light.cpp b/directional_light.cpp index 26ceb41..82bebc0 100644 --- a/directional_light.cpp +++ b/directional_light.cpp @@ -21,9 +21,9 @@ inline float DirectionalLight::distance(vec3 point) { } vec3 DirectionalLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const { - return m.m_brdf->diffuse(m_position, normal, r, m_diffuse); + return m.m_brdf->diffuse(m_position, normal, r, i_pos, m_diffuse); } vec3 DirectionalLight::specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const { - return m.m_brdf->specular(m_position, normal, r, m_specular, m.m_shininess); + return m.m_brdf->specular(m_position, normal, r, i_pos, m_specular, m.m_shininess); } diff --git a/hsa_brdf.cpp b/hsa_brdf.cpp new file mode 100644 index 0000000..813975a --- /dev/null +++ b/hsa_brdf.cpp @@ -0,0 +1,24 @@ +#include "glm/glm.hpp" + +#include "hsa_brdf.hpp" + +using glm::reflect; +using glm::pow; +using glm::max; +using glm::dot; + +vec3 HeidrichSeidelAnisotropicBRDF::diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_diff_color) const { + vec3 T = normalize(thread_dir + (dot(-thread_dir, surface_normal) * surface_normal)); + float k_diff = glm::sqrt(1 - max(dot(light_dir, T), 0.0f)); + float n_dot_l = max(dot(surface_normal, light_dir), 0.0f); + return light_diff_color * k_diff * n_dot_l; +} + +vec3 HeidrichSeidelAnisotropicBRDF::specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_spec_color, float shininess) const { + vec3 T = normalize(thread_dir + (dot(-thread_dir, surface_normal) * surface_normal)); + float n_dot_l = max(dot(surface_normal, light_dir), 0.0f); + float l_dot_t = max(dot(-light_dir, T), 0.0f); + float v_dot_t = max(dot(-incident_ray.m_direction, T), 0.0f); + float k_spec = pow(glm::sqrt(1.0f - (l_dot_t * l_dot_t)) * glm::sqrt(1.0f - (v_dot_t * v_dot_t)) - (l_dot_t * v_dot_t), shininess); + return n_dot_l * ((light_spec_color * k_spec) + PhongBRDF::specular(light_dir, surface_normal, incident_ray, intersection_point, light_spec_color, shininess)); +} diff --git a/hsa_brdf.hpp b/hsa_brdf.hpp new file mode 100644 index 0000000..2de8a69 --- /dev/null +++ b/hsa_brdf.hpp @@ -0,0 +1,21 @@ +#pragma once +#ifndef HSA_BRDF_HPP +#define HSA_BRDF_HPP + +#include "phong_brdf.hpp" + +using glm::normalize; + +class HeidrichSeidelAnisotropicBRDF: public PhongBRDF { +public: + vec3 thread_dir; + + HeidrichSeidelAnisotropicBRDF(vec3 _d): PhongBRDF(), thread_dir(normalize(_d)) { } + + virtual ~HeidrichSeidelAnisotropicBRDF() { } + + virtual vec3 diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_diff_color) const; + virtual vec3 specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_spec_color, float shininess) const; +}; + +#endif diff --git a/main.cpp b/main.cpp index 978e9b3..8e52a36 100644 --- a/main.cpp +++ b/main.cpp @@ -26,6 +26,7 @@ #include "whitted_tracer.hpp" #include "brdf.hpp" #include "phong_brdf.hpp" +#include "hsa_brdf.hpp" using namespace std; using namespace glm; @@ -95,7 +96,7 @@ int main(int argc, char ** argv) { image[i] = new vec3[g_w]; } - scene_2(figures, lights, cam); + scene_3(figures, lights, cam); // Create the tracer object. cout << "Rendering the input file: " << ANSI_BOLD_YELLOW << g_input_file << ANSI_RESET_STYLE << endl; @@ -409,26 +410,32 @@ void scene_2(vector
& vf, vector & vl, Camera * c) { 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_specular = vec3(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_specular = vec3(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_specular = vec3(0.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_specular = vec3(0.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_specular = vec3(0.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_specular = vec3(0.0f); vf.push_back(static_cast
(p)); s = new Sphere(-0.5f, -0.5f, -1.5f, 0.5f); @@ -467,7 +474,8 @@ void scene_2(vector
& vf, vector & vl, Camera * c) { void scene_3(vector
& vf, vector & vl, Camera * c) { Sphere * s; Plane * p; - DirectionalLight * l; + SpotLight * l; + DirectionalLight * l2; vec3 eye = vec3(0.0f, 1.5f, 0.0f); vec3 center = vec3(0.0f, 0.0f, -2.0f); vec3 left = vec3(-1.0f, 0.0f, 0.0f); @@ -476,33 +484,33 @@ void scene_3(vector
& vf, vector & vl, Camera * c) { c->m_look = center; c->m_up = cross(normalize(center - eye), left); c->translate(vec3(1.0f, 0.0f, 0.0f)); - c->roll(15.0f); + //c->roll(15.0f); - 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; - vf.push_back(static_cast
(s)); + // 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; + // 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; - 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; + // 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; - vf.push_back(static_cast
(s)); - - s = new Sphere(-1.0f, 0.25f, -3.25f, 1.0f); + s = new Sphere(2.0f, 0.0f, -2.0f, 1.0f, new HeidrichSeidelAnisotropicBRDF(vec3(0.0f, 1.0f, 0.0f))); s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f); - s->m_mat->m_shininess = 20.0f; + s->m_mat->m_shininess = 128.0f; + vf.push_back(static_cast
(s)); + + s = new Sphere(-1.0f, 0.0f, -3.25f, 1.0f); + s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f); + s->m_mat->m_rho = 0.4f; vf.push_back(static_cast
(s)); p = new Plane(vec3(0.0f, -1.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); @@ -510,28 +518,29 @@ void scene_3(vector
& vf, vector & vl, Camera * c) { p->m_mat->m_specular = vec3(0.0f); vf.push_back(static_cast
(p)); - l = new DirectionalLight(); - l->m_position = normalize(vec3(-1.0f, 1.0f, -1.0f)); - l->m_diffuse = vec3(1.0f, 1.0f, 1.0f); - l->m_specular = vec3(0.0f, 1.0f, 0.0f); + l = new SpotLight(); + l->m_position = normalize(vec3(-2.0f, 1.5f, -1.0f)); + l->m_diffuse = vec3(1.0f, 1.0f, 0.0f); + l->m_spot_dir = normalize(vec3(0.5f, 0.0f, -2.5f) - vec3(-2.0f, 1.5f, -1.0f)); + l->m_spot_cutoff = 89.0f; + l->m_spot_exponent = 10.0f; vl.push_back(static_cast(l)); - l = new DirectionalLight(); - l->m_position = normalize(vec3(0.0f, 1.0f, 1.0f)); - l->m_diffuse = vec3(1.0f, 0.0f, 0.0f); - l->m_specular = vec3(1.0f, 0.0f, 0.0f); - vl.push_back(static_cast(l)); + l2 = new DirectionalLight(); + l2->m_position = normalize(vec3(-1.0f, 0.7f, 1.0f)); + l2->m_diffuse = vec3(1.0f, 1.0f, 1.0f); + vl.push_back(static_cast(l2)); - l = new DirectionalLight(); - l->m_position = normalize(vec3(1.0f, 1.0f, -1.0f)); - l->m_diffuse = vec3(0.0f, 0.0f, 1.0f); - l->m_specular = vec3(0.0f, 0.0f, 1.0f); - vl.push_back(static_cast(l)); + l2 = new DirectionalLight(); + l2->m_position = normalize(vec3(-0.5f, 0.7f, 1.0f)); + l2->m_diffuse = vec3(0.0f, 0.0f, 1.0f); + l2->m_specular = vec3(0.0f, 0.0f, 1.0f); + vl.push_back(static_cast(l2)); - l = new DirectionalLight(); - l->m_position = normalize(vec3(1.0f, 0.0f, 1.0f)); - l->m_diffuse = vec3(0.5f); - vl.push_back(static_cast(l)); + // l = new DirectionalLight(); + // l->m_position = normalize(vec3(1.0f, 0.0f, 1.0f)); + // l->m_diffuse = vec3(0.5f); + // vl.push_back(static_cast(l)); } void scene_4(vector
& vf, vector & vl, Camera * c) { diff --git a/output.png b/output.png index 1a0ec99..87bbc6e 100644 Binary files a/output.png and b/output.png differ diff --git a/phong_brdf.cpp b/phong_brdf.cpp index a64678e..e71096d 100644 --- a/phong_brdf.cpp +++ b/phong_brdf.cpp @@ -7,12 +7,12 @@ using glm::pow; using glm::max; using glm::dot; -vec3 PhongBRDF::diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 light_diff_color) const { +vec3 PhongBRDF::diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_diff_color) const { float n_dot_l = max(dot(surface_normal, light_dir), 0.0f); return light_diff_color * n_dot_l; } -vec3 PhongBRDF::specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 light_spec_color, float shininess) const { +vec3 PhongBRDF::specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_spec_color, float shininess) const { vec3 ref = reflect(light_dir, surface_normal); float r_dot_l = pow(max(dot(ref, incident_ray.m_direction), 0.0f), shininess); return light_spec_color * r_dot_l; diff --git a/phong_brdf.hpp b/phong_brdf.hpp index 8e0d833..510d41b 100644 --- a/phong_brdf.hpp +++ b/phong_brdf.hpp @@ -9,8 +9,8 @@ public: PhongBRDF() { } virtual ~PhongBRDF() { } - virtual vec3 diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 light_diff_color) const; - virtual vec3 specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 light_spec_color, float shininess) const; + virtual vec3 diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_diff_color) const; + virtual vec3 specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_spec_color, float shininess) const; }; #endif diff --git a/point_light.cpp b/point_light.cpp index aabe96e..7fd05ed 100644 --- a/point_light.cpp +++ b/point_light.cpp @@ -28,7 +28,7 @@ vec3 PointLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const { l_dir = normalize(l_dir); att = 1.0f / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d))); - return att * m.m_brdf->diffuse(l_dir, normal, r, m_diffuse); + return att * m.m_brdf->diffuse(l_dir, normal, r, i_pos, m_diffuse); } vec3 PointLight::specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const { @@ -40,5 +40,5 @@ vec3 PointLight::specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const l_dir = normalize(l_dir); att = 1.0f / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d))); - return att * m.m_brdf->specular(l_dir, normal, r, m_specular, m.m_shininess); + return att * m.m_brdf->specular(l_dir, normal, r, i_pos, m_specular, m.m_shininess); } diff --git a/spot_light.cpp b/spot_light.cpp index 3e9175b..c6487e1 100644 --- a/spot_light.cpp +++ b/spot_light.cpp @@ -25,7 +25,7 @@ vec3 SpotLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const { if (acos(spot_effect) < radians(m_spot_cutoff)) { spot_effect = pow(spot_effect, m_spot_exponent); att = spot_effect / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d))); - return att * m.m_brdf->diffuse(l_dir, normal, r, m_diffuse); + return att * m.m_brdf->diffuse(l_dir, normal, r, i_pos, m_diffuse); } else return vec3(0.0f); @@ -43,7 +43,7 @@ vec3 SpotLight::specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const { if (acos(spot_effect) < radians(m_spot_cutoff)) { spot_effect = pow(spot_effect, m_spot_exponent); att = spot_effect / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d))); - return att * m.m_brdf->specular(l_dir, normal, r, m_specular, m.m_shininess); + return att * m.m_brdf->specular(l_dir, normal, r, i_pos, m_specular, m.m_shininess); } else return vec3(0.0f); } diff --git a/tracer.cpp b/tracer.cpp index bb97ced..56465c0 100644 --- a/tracer.cpp +++ b/tracer.cpp @@ -6,7 +6,7 @@ using glm::refract; const float BIAS = 0.000001f; -const vec3 BCKG_COLOR = vec3(1.0f); +const vec3 BCKG_COLOR = vec3(0.1f); float Tracer::fresnel(const vec3 & i, const vec3 & n, const float ir1, const float ir2) const { float cos_t1 = dot(i, n);