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++
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)
CXXFLAGS = -ansi -pedantic -Wall -DGLM_FORCE_RADIANS -fopenmp
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();
}
vec3 DirectionalLight::diffuse(vec3 normal, Ray & r, float t, Material & m) const {
float n_dot_l;
vec3 color;
n_dot_l = max(dot(normal, m_position), 0.0f);
color += m_diffuse * n_dot_l;
return color;
vec3 DirectionalLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
return m_brdf->diffuse(m_position, normal, r, m_diffuse);
}
vec3 DirectionalLight::specular(vec3 normal, Ray & r, float t, Material & m) const {
float r_dot_l;
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;
vec3 DirectionalLight::specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
return m.m_specular * m_brdf->specular(m_position, normal, r, m_specular, m.m_shininess);
}

View File

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

View File

@@ -4,6 +4,8 @@
#include <glm/vec3.hpp>
#include "brdf.hpp"
#include "phong_brdf.hpp"
#include "ray.hpp"
#include "material.hpp"
@@ -11,16 +13,23 @@ using glm::vec3;
class Light {
public:
BRDF * m_brdf;
vec3 m_position;
vec3 m_diffuse;
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 float distance(vec3 point) = 0;
virtual vec3 diffuse(vec3 normal, Ray & r, float t, Material & m) const = 0;
virtual vec3 specular(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, vec3 i_pos, Material & m) const = 0;
};
#endif

View File

@@ -20,6 +20,8 @@
#include "point_light.hpp"
#include "tracer.hpp"
#include "path_tracer.hpp"
#include "brdf.hpp"
#include "phong_brdf.hpp"
using namespace std;
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.
dir_diff_color += vis ? v_lights[l]->diffuse(n, r, t, _f->m_mat) : vec3(0.0f);
dir_spec_color += vis ? v_lights[l]->specular(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, i_pos, _f->m_mat) : vec3(0.0f);
}
// 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);
}
vec3 PointLight::diffuse(vec3 normal, Ray & r, float t, Material & m) const {
float d, att, n_dot_l;
vec3 color, i_pos, l_dir, ref;
vec3 PointLight::diffuse(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
float d, att;
vec3 l_dir, ref;
i_pos = r.m_origin + t * r.m_direction;
l_dir = m_position - i_pos;
d = length(l_dir);
l_dir = normalize(l_dir);
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);
color += att * m_diffuse * n_dot_l;
return color;
return att * m_brdf->diffuse(l_dir, normal, r, m_diffuse);
}
vec3 PointLight::specular(vec3 normal, Ray & r, float t, Material & m) const {
float d, att, r_dot_l;
vec3 color, i_pos, l_dir, ref;
vec3 PointLight::specular(vec3 normal, Ray & r, vec3 i_pos, Material & m) const {
float d, att;
vec3 l_dir, ref;
i_pos = r.m_origin + t * r.m_direction;
l_dir = m_position - i_pos;
d = length(l_dir);
l_dir = normalize(l_dir);
att = 1.0f / (m_const_att + (m_lin_att * d) + (m_quad_att * (d * d)));
ref = reflect(l_dir, normal);
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;
return att * m.m_specular * m_brdf->specular(l_dir, normal, r, m_specular, m.m_shininess);
}

View File

@@ -10,22 +10,14 @@ public:
float m_lin_att;
float m_quad_att;
PointLight(): 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(): Light(), m_const_att(1.0f), m_lin_att(0.0f), m_quad_att(0.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) {
m_position = _p;
m_diffuse = _d;
m_specular = _s;
}
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) { }
virtual vec3 direction(vec3 point);
virtual float distance(vec3 point);
virtual vec3 diffuse(vec3 normal, Ray & r, float t, Material & m) const;
virtual vec3 specular(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, vec3 i_pos, Material & m) const;
};
#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.
dir_diff_color += vis ? v_lights[l]->diffuse(n, r, t, _f->m_mat) : vec3(0.0f);
dir_spec_color += vis ? v_lights[l]->specular(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, i_pos, _f->m_mat) : vec3(0.0f);
}
color += (dir_diff_color * (_f->m_mat.m_diffuse / pi<float>())) + dir_spec_color;