Separated BRDF from light source.
This commit is contained in:
2
Makefile
2
Makefile
@@ -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
20
brdf.hpp
Normal 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
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
15
light.hpp
15
light.hpp
@@ -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
|
||||
|
2
main.cpp
2
main.cpp
@@ -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;
|
||||
|
BIN
output.png
BIN
output.png
Binary file not shown.
Before Width: | Height: | Size: 468 KiB After Width: | Height: | Size: 542 KiB |
@@ -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
19
phong_brdf.cpp
Normal 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
16
phong_brdf.hpp
Normal 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
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user