Separated BRDF from light source.

This commit is contained in:
Miguel Angel Astor Romero
2017-01-11 14:51:21 -04:00
parent a9670e93f0
commit f150f8f24c
13 changed files with 94 additions and 66 deletions

View File

@@ -1,6 +1,6 @@
CXX = g++ CXX = g++
TARGET = ray TARGET = ray
OBJECTS = main.o disk.o plane.o sphere.o directional_light.o point_light.o tracer.o path_tracer.o whitted_tracer.o OBJECTS = main.o disk.o plane.o sphere.o directional_light.o point_light.o tracer.o path_tracer.o whitted_tracer.o phong_brdf.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

20
brdf.hpp Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#ifndef BRDF_HPP
#define BRDF_HPP
#include <glm/vec3.hpp>
#include "ray.hpp"
#include "material.hpp"
using glm::vec3;
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;
};
#endif

View File

@@ -20,23 +20,10 @@ inline float DirectionalLight::distance(vec3 point) {
return numeric_limits<float>::max(); return numeric_limits<float>::max();
} }
vec3 DirectionalLight::diffuse(vec3 normal, Ray & r, float t, Material & m) const { vec3 DirectionalLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
float n_dot_l; return m_brdf->diffuse(m_position, normal, r, m_diffuse);
vec3 color;
n_dot_l = max(dot(normal, m_position), 0.0f);
color += m_diffuse * n_dot_l;
return color;
} }
vec3 DirectionalLight::specular(vec3 normal, Ray & r, float t, Material & m) const { vec3 DirectionalLight::specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
float r_dot_l; return m.m_specular * m_brdf->specular(m_position, normal, r, m_specular, m.m_shininess);
vec3 color, ref;
ref = reflect(m_position, normal);
r_dot_l = pow(max(dot(ref, r.m_direction), 0.0f), m.m_shininess);
color += m.m_specular * m_specular * r_dot_l;
return color;
} }

View File

@@ -6,22 +6,14 @@
class DirectionalLight: public Light { class DirectionalLight: public Light {
public: public:
DirectionalLight() { DirectionalLight(): Light() { }
m_position = vec3(0.0f);
m_diffuse = vec3(1.0f);
m_specular = vec3(1.0f);
}
DirectionalLight(vec3 _p, vec3 _d, vec3 _s) { DirectionalLight(BRDF * _brdf, vec3 _p, vec3 _d, vec3 _s): Light(_brdf, _p, _d, _s) { }
m_position = _p;
m_diffuse = _d;
m_specular = _s;
}
virtual vec3 direction(vec3 point); virtual vec3 direction(vec3 point);
virtual float distance(vec3 point); virtual float distance(vec3 point);
virtual vec3 diffuse(vec3 normal, Ray & r, float t, Material & m) const; virtual vec3 diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const;
virtual vec3 specular(vec3 normal, Ray & r, float t, Material & m) const; virtual vec3 specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const;
}; };
#endif #endif

View File

@@ -4,6 +4,8 @@
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include "brdf.hpp"
#include "phong_brdf.hpp"
#include "ray.hpp" #include "ray.hpp"
#include "material.hpp" #include "material.hpp"
@@ -11,16 +13,23 @@ using glm::vec3;
class Light { class Light {
public: public:
BRDF * m_brdf;
vec3 m_position; vec3 m_position;
vec3 m_diffuse; vec3 m_diffuse;
vec3 m_specular; vec3 m_specular;
virtual ~Light() { } Light(): m_brdf(static_cast<BRDF *>(new PhongBRDF())), m_position(vec3(0.0f)), m_diffuse(vec3(1.0f)), m_specular(vec3(1.0f)) { }
Light(BRDF * _brdf, vec3 _p, vec3 _d, vec3 _s): m_brdf(_brdf), m_position(_p), m_diffuse(_d), m_specular(_s) { }
virtual ~Light() {
delete m_brdf;
}
virtual vec3 direction(vec3 point) = 0; virtual vec3 direction(vec3 point) = 0;
virtual float distance(vec3 point) = 0; virtual float distance(vec3 point) = 0;
virtual vec3 diffuse(vec3 normal, Ray & r, float t, Material & m) const = 0; virtual vec3 diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const = 0;
virtual vec3 specular(vec3 normal, Ray & r, float t, Material & m) const = 0; virtual vec3 specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const = 0;
}; };
#endif #endif

View File

@@ -20,6 +20,8 @@
#include "point_light.hpp" #include "point_light.hpp"
#include "tracer.hpp" #include "tracer.hpp"
#include "path_tracer.hpp" #include "path_tracer.hpp"
#include "brdf.hpp"
#include "phong_brdf.hpp"
using namespace std; using namespace std;
using namespace glm; using namespace glm;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 KiB

After

Width:  |  Height:  |  Size: 542 KiB

View File

@@ -53,8 +53,8 @@ vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *
} }
// Evaluate the shading model accounting for visibility. // Evaluate the shading model accounting for visibility.
dir_diff_color += vis ? v_lights[l]->diffuse(n, r, t, _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, t, _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. // Calculate indirect lighting contribution.

19
phong_brdf.cpp Normal file
View File

@@ -0,0 +1,19 @@
#include "glm/glm.hpp"
#include "phong_brdf.hpp"
using glm::reflect;
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 {
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 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;
}

16
phong_brdf.hpp Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#ifndef PHONG_BRDF_HPP
#define PHONG_BRDF_HPP
#include "brdf.hpp"
class PhongBRDF: public BRDF{
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;
};
#endif

View File

@@ -19,35 +19,26 @@ inline float PointLight::distance(vec3 point) {
return length(m_position - point); return length(m_position - point);
} }
vec3 PointLight::diffuse(vec3 normal, Ray & r, float t, Material & m) const { vec3 PointLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
float d, att, n_dot_l; float d, att;
vec3 color, i_pos, l_dir, ref; vec3 l_dir, ref;
i_pos = r.m_origin + t * r.m_direction;
l_dir = m_position - i_pos; l_dir = m_position - i_pos;
d = length(l_dir); d = length(l_dir);
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)));
n_dot_l = max(dot(normal, l_dir), 0.0f); return att * m_brdf->diffuse(l_dir, normal, r, m_diffuse);
color += att * m_diffuse * n_dot_l;
return color;
} }
vec3 PointLight::specular(vec3 normal, Ray & r, float t, Material & m) const { vec3 PointLight::specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
float d, att, r_dot_l; float d, att;
vec3 color, i_pos, l_dir, ref; vec3 l_dir, ref;
i_pos = r.m_origin + t * r.m_direction;
l_dir = m_position - i_pos; l_dir = m_position - i_pos;
d = length(l_dir); d = length(l_dir);
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)));
ref = reflect(l_dir, normal); return att * m.m_specular * m_brdf->specular(l_dir, normal, r, m_specular, m.m_shininess);
r_dot_l = pow(max(dot(ref, r.m_direction), 0.0f), m.m_shininess);
color += att * m.m_specular * m_specular * r_dot_l;
return color;
} }

View File

@@ -10,22 +10,14 @@ public:
float m_lin_att; float m_lin_att;
float m_quad_att; float m_quad_att;
PointLight(): m_const_att(1.0f), m_lin_att(0.0f), m_quad_att(0.0f) { PointLight(): Light(), m_const_att(1.0f), m_lin_att(0.0f), m_quad_att(0.0f) { }
m_position = vec3(0.0f);
m_diffuse = vec3(1.0f);
m_specular = vec3(1.0f);
}
PointLight(vec3 _p, vec3 _d, vec3 _s, float _c, float _l, float _q): m_const_att(_c), m_lin_att(_l), m_quad_att(_q) { PointLight(BRDF * _brdf, vec3 _p, vec3 _d, vec3 _s, float _c, float _l, float _q): Light(_brdf, _p, _d, _s), m_const_att(_c), m_lin_att(_l), m_quad_att(_q) { }
m_position = _p;
m_diffuse = _d;
m_specular = _s;
}
virtual vec3 direction(vec3 point); virtual vec3 direction(vec3 point);
virtual float distance(vec3 point); virtual float distance(vec3 point);
virtual vec3 diffuse(vec3 normal, Ray & r, float t, Material & m) const; virtual vec3 diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const;
virtual vec3 specular(vec3 normal, Ray & r, float t, Material & m) const; virtual vec3 specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const;
}; };
#endif #endif

View File

@@ -51,8 +51,8 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Ligh
} }
// Evaluate the shading model accounting for visibility. // Evaluate the shading model accounting for visibility.
dir_diff_color += vis ? v_lights[l]->diffuse(n, r, t, _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, t, _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<float>())) + dir_spec_color; color += (dir_diff_color * (_f->m_mat.m_diffuse / pi<float>())) + dir_spec_color;