Added Heidrich-Seidel anisotropic BRDF.

This commit is contained in:
Miguel Angel Astor Romero
2017-01-13 15:05:13 -04:00
parent b7f7ba7ee1
commit 8e2b2a8c2a
12 changed files with 111 additions and 57 deletions

View File

@@ -1,6 +1,6 @@
CXX = g++ CXX = g++
TARGET = ray 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) DEPENDS = $(OBJECTS:.o=.d)
CXXFLAGS = -ansi -pedantic -Wall -DGLM_FORCE_RADIANS -fopenmp CXXFLAGS = -ansi -pedantic -Wall -DGLM_FORCE_RADIANS -fopenmp
LDLIBS = -lfreeimage LDLIBS = -lfreeimage

View File

@@ -12,8 +12,8 @@ class BRDF {
public: public:
virtual ~BRDF() { } virtual ~BRDF() { }
virtual vec3 diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 light_diff_color) 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 light_spec_color, float shininess) 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 #endif

View File

@@ -21,9 +21,9 @@ inline float DirectionalLight::distance(vec3 point) {
} }
vec3 DirectionalLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const { 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 { 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);
} }

24
hsa_brdf.cpp Normal file
View File

@@ -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));
}

21
hsa_brdf.hpp Normal file
View File

@@ -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

View File

@@ -26,6 +26,7 @@
#include "whitted_tracer.hpp" #include "whitted_tracer.hpp"
#include "brdf.hpp" #include "brdf.hpp"
#include "phong_brdf.hpp" #include "phong_brdf.hpp"
#include "hsa_brdf.hpp"
using namespace std; using namespace std;
using namespace glm; using namespace glm;
@@ -95,7 +96,7 @@ int main(int argc, char ** argv) {
image[i] = new vec3[g_w]; image[i] = new vec3[g_w];
} }
scene_2(figures, lights, cam); scene_3(figures, lights, cam);
// Create the tracer object. // Create the tracer object.
cout << "Rendering the input file: " << ANSI_BOLD_YELLOW << g_input_file << ANSI_RESET_STYLE << endl; cout << "Rendering the input file: " << ANSI_BOLD_YELLOW << g_input_file << ANSI_RESET_STYLE << endl;
@@ -409,26 +410,32 @@ void scene_2(vector<Figure *> & vf, vector<Light *> & vl, Camera * c) {
p = new Plane(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); 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);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p)); vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(-2.0f, 0.0f, 0.0f), vec3(1.0f, 0.0f, 0.0f)); 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);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p)); vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(2.0f, 0.0f, 0.0f), vec3(-1.0f, 0.0f, 0.0f)); 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);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p)); vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(0.0f, 1.0f, 0.0f), vec3(0.0f, -1.0f, 0.0f)); 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);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p)); vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(0.0f, 0.0f, -2.0f), vec3(0.0f, 0.0f, 1.0f)); 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);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p)); vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(0.0f, 0.0f, 1.1f), vec3(0.0f, 0.0f, -1.0f)); 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);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p)); vf.push_back(static_cast<Figure *>(p));
s = new Sphere(-0.5f, -0.5f, -1.5f, 0.5f); s = new Sphere(-0.5f, -0.5f, -1.5f, 0.5f);
@@ -467,7 +474,8 @@ void scene_2(vector<Figure *> & vf, vector<Light *> & vl, Camera * c) {
void scene_3(vector<Figure *> & vf, vector<Light *> & vl, Camera * c) { void scene_3(vector<Figure *> & vf, vector<Light *> & vl, Camera * c) {
Sphere * s; Sphere * s;
Plane * p; Plane * p;
DirectionalLight * l; SpotLight * l;
DirectionalLight * l2;
vec3 eye = vec3(0.0f, 1.5f, 0.0f); vec3 eye = vec3(0.0f, 1.5f, 0.0f);
vec3 center = vec3(0.0f, 0.0f, -2.0f); vec3 center = vec3(0.0f, 0.0f, -2.0f);
vec3 left = vec3(-1.0f, 0.0f, 0.0f); vec3 left = vec3(-1.0f, 0.0f, 0.0f);
@@ -476,33 +484,33 @@ void scene_3(vector<Figure *> & vf, vector<Light *> & vl, Camera * c) {
c->m_look = center; c->m_look = center;
c->m_up = cross(normalize(center - eye), left); c->m_up = cross(normalize(center - eye), left);
c->translate(vec3(1.0f, 0.0f, 0.0f)); 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 = 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_diffuse = vec3(1.0f, 0.5f, 0.0f);
s->m_mat->m_specular = vec3(0.3f); // s->m_mat->m_specular = vec3(0.3f);
s->m_mat->m_shininess = 5.0f; // s->m_mat->m_shininess = 5.0f;
s->m_mat->m_rho = 0.4f; // s->m_mat->m_rho = 0.4f;
s->m_mat->m_refract = true; // s->m_mat->m_refract = true;
s->m_mat->m_ref_index = 1.33f; // s->m_mat->m_ref_index = 1.33f;
vf.push_back(static_cast<Figure *>(s)); // vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, -0.15f, -2.0f, 0.5f); // s = new Sphere(0.0f, -0.15f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(0.0f); // s->m_mat->m_diffuse = vec3(0.0f);
s->m_mat->m_specular = vec3(0.0f); // s->m_mat->m_specular = vec3(0.0f);
s->m_mat->m_rho = 0.0f; // s->m_mat->m_rho = 0.0f;
s->m_mat->m_refract = true; // s->m_mat->m_refract = true;
s->m_mat->m_ref_index = 2.6f; // s->m_mat->m_ref_index = 2.6f;
vf.push_back(static_cast<Figure *>(s)); // vf.push_back(static_cast<Figure *>(s));
s = new Sphere(2.0f, 0.0f, -2.0f, 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, 0.0f, 1.0f);
s->m_mat->m_rho = 1.0f;
vf.push_back(static_cast<Figure *>(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_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<Figure *>(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<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
p = new Plane(vec3(0.0f, -1.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); 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<Figure *> & vf, vector<Light *> & vl, Camera * c) {
p->m_mat->m_specular = vec3(0.0f); p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p)); vf.push_back(static_cast<Figure *>(p));
l = new DirectionalLight(); l = new SpotLight();
l->m_position = normalize(vec3(-1.0f, 1.0f, -1.0f)); l->m_position = normalize(vec3(-2.0f, 1.5f, -1.0f));
l->m_diffuse = vec3(1.0f, 1.0f, 1.0f); l->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
l->m_specular = vec3(0.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<Light *>(l)); vl.push_back(static_cast<Light *>(l));
l = new DirectionalLight(); l2 = new DirectionalLight();
l->m_position = normalize(vec3(0.0f, 1.0f, 1.0f)); l2->m_position = normalize(vec3(-1.0f, 0.7f, 1.0f));
l->m_diffuse = vec3(1.0f, 0.0f, 0.0f); l2->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
l->m_specular = vec3(1.0f, 0.0f, 0.0f); vl.push_back(static_cast<Light *>(l2));
vl.push_back(static_cast<Light *>(l));
l = new DirectionalLight(); l2 = new DirectionalLight();
l->m_position = normalize(vec3(1.0f, 1.0f, -1.0f)); l2->m_position = normalize(vec3(-0.5f, 0.7f, 1.0f));
l->m_diffuse = vec3(0.0f, 0.0f, 1.0f); l2->m_diffuse = vec3(0.0f, 0.0f, 1.0f);
l->m_specular = vec3(0.0f, 0.0f, 1.0f); l2->m_specular = vec3(0.0f, 0.0f, 1.0f);
vl.push_back(static_cast<Light *>(l)); vl.push_back(static_cast<Light *>(l2));
l = new DirectionalLight(); // l = new DirectionalLight();
l->m_position = normalize(vec3(1.0f, 0.0f, 1.0f)); // l->m_position = normalize(vec3(1.0f, 0.0f, 1.0f));
l->m_diffuse = vec3(0.5f); // l->m_diffuse = vec3(0.5f);
vl.push_back(static_cast<Light *>(l)); // vl.push_back(static_cast<Light *>(l));
} }
void scene_4(vector<Figure *> & vf, vector<Light *> & vl, Camera * c) { void scene_4(vector<Figure *> & vf, vector<Light *> & vl, Camera * c) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 KiB

After

Width:  |  Height:  |  Size: 484 KiB

View File

@@ -7,12 +7,12 @@ using glm::pow;
using glm::max; using glm::max;
using glm::dot; 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); float n_dot_l = max(dot(surface_normal, light_dir), 0.0f);
return light_diff_color * n_dot_l; 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); vec3 ref = reflect(light_dir, surface_normal);
float r_dot_l = pow(max(dot(ref, incident_ray.m_direction), 0.0f), shininess); float r_dot_l = pow(max(dot(ref, incident_ray.m_direction), 0.0f), shininess);
return light_spec_color * r_dot_l; return light_spec_color * r_dot_l;

View File

@@ -9,8 +9,8 @@ public:
PhongBRDF() { } PhongBRDF() { }
virtual ~PhongBRDF() { } virtual ~PhongBRDF() { }
virtual vec3 diffuse(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 light_diff_color) 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 light_spec_color, float shininess) const; virtual vec3 specular(vec3 light_dir, vec3 surface_normal, Ray & incident_ray, vec3 intersection_point, vec3 light_spec_color, float shininess) const;
}; };
#endif #endif

View File

@@ -28,7 +28,7 @@ vec3 PointLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
l_dir = normalize(l_dir); l_dir = normalize(l_dir);
att = 1.0f / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d))); 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 { 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); l_dir = normalize(l_dir);
att = 1.0f / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d))); 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);
} }

View File

@@ -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)) { if (acos(spot_effect) < radians(m_spot_cutoff)) {
spot_effect = pow(spot_effect, m_spot_exponent); spot_effect = pow(spot_effect, m_spot_exponent);
att = spot_effect / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d))); 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 } else
return vec3(0.0f); 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)) { if (acos(spot_effect) < radians(m_spot_cutoff)) {
spot_effect = pow(spot_effect, m_spot_exponent); spot_effect = pow(spot_effect, m_spot_exponent);
att = spot_effect / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d))); 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 } else
return vec3(0.0f); return vec3(0.0f);
} }

View File

@@ -6,7 +6,7 @@ using glm::refract;
const float BIAS = 0.000001f; 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 Tracer::fresnel(const vec3 & i, const vec3 & n, const float ir1, const float ir2) const {
float cos_t1 = dot(i, n); float cos_t1 = dot(i, n);