Added point lights.

This commit is contained in:
2017-01-02 04:23:48 -04:00
parent a0381b4fff
commit fb887ae0f0
9 changed files with 59031 additions and 10218 deletions

View File

@@ -1,6 +1,6 @@
TARGET = ray
HEADERS = ray.hpp figure.hpp sphere.hpp plane.hpp disk.hpp material.hpp light.hpp directional_light.hpp tracer.hpp
OBJECTS = main.o sphere.o plane.o disk.o directional_light.o tracer.o
HEADERS = ray.hpp figure.hpp sphere.hpp plane.hpp disk.hpp material.hpp light.hpp directional_light.hpp point_light.hpp tracer.hpp
OBJECTS = main.o sphere.o plane.o disk.o directional_light.o point_light.o tracer.o
CXX = g++
CXXFLAGS = -ansi -pedantic -Wall -g -DGLM_FORCE_RADIANS -fopenmp
LDLIBS =
@@ -23,6 +23,8 @@ tracer.o: tracer.cpp $(HEADERS)
directional_light.o: directional_light.cpp $(HEADERS)
point_light.o: point_light.cpp $(HEADERS)
.PHONY: clean
clean:
$(RM) $(TARGET) $(OBJECTS)

View File

@@ -1,15 +1,26 @@
#include <limits>
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
#include "directional_light.hpp"
using std::numeric_limits;
using glm::pi;
using glm::reflect;
using glm::dot;
using glm::pow;
using glm::max;
vec3 DirectionalLight::shade(vec3 normal, Ray & r, Material & m) const {
inline vec3 DirectionalLight::direction(vec3 point) {
return m_position;
}
inline float DirectionalLight::distance(vec3 point) {
return numeric_limits<float>::max();
}
vec3 DirectionalLight::shade(vec3 normal, Ray & r, float t, Material & m) const {
float n_dot_l, r_dot_l;
vec3 color, ref;

View File

@@ -18,7 +18,9 @@ public:
m_specular = _s;
}
virtual vec3 shade(vec3 normal, Ray & r, Material & m) const;
virtual vec3 direction(vec3 point);
virtual float distance(vec3 point);
virtual vec3 shade(vec3 normal, Ray & r, float t, Material & m) const;
};
#endif

View File

@@ -14,11 +14,12 @@ public:
vec3 m_position;
vec3 m_diffuse;
vec3 m_specular;
vec3 m_ambient;
virtual ~Light() { }
virtual vec3 shade(vec3 normal, Ray & r, Material & m) const = 0;
virtual vec3 direction(vec3 point) = 0;
virtual float distance(vec3 point) = 0;
virtual vec3 shade(vec3 normal, Ray & r, float t, Material & m) const = 0;
};
#endif

View File

@@ -16,6 +16,7 @@
#include "disk.hpp"
#include "light.hpp"
#include "directional_light.hpp"
#include "point_light.hpp"
#include "tracer.hpp"
using namespace std;
@@ -94,7 +95,7 @@ int main(int argc, char ** argv) {
image[i] = new vec3[g_w];
}
scene_3(figures, lights, i_model_view);
scene_2(figures, lights, i_model_view);
tracer = Tracer(g_h, g_w, g_fov);
@@ -228,17 +229,25 @@ static void scene_1(vector<Figure *> & vf, vector<Light *> & vl, mat4x4 & i_mode
static void scene_2(vector<Figure *> & vf, vector<Light *> & vl, mat4x4 & i_model_view) {
Sphere * s;
Plane * p;
DirectionalLight * l;
PointLight * l;
s = new Sphere(0.2f, 0.0f, -0.75f, 0.25f);
s->m_mat.m_diffuse = vec3(0.0f);
s->m_mat.m_specular = vec3(0.0f);
s->m_mat.m_rho = 0.1f;
s->m_mat.m_refract = true;
s->m_mat.m_ref_index = 2.33f;
vf.push_back(static_cast<Figure *>(s));
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);
vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(-1.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);
vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(1.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);
vf.push_back(static_cast<Figure *>(p));
@@ -250,14 +259,18 @@ static void scene_2(vector<Figure *> & vf, vector<Light *> & vl, mat4x4 & i_mode
p->m_mat.m_diffuse = vec3(1.0f, 0.0f, 1.0f);
vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(0.0f, 0.0f, 0.1f), vec3(0.0f, 0.0f, -1.0f));
p->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f);
vf.push_back(static_cast<Figure *>(p));
s = new Sphere(-0.4f, -0.5f, -1.5f, 0.5f);
s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f);
s->m_mat.m_rho = 0.4f;
s->m_mat.m_rho = 0.9f;
vf.push_back(static_cast<Figure *>(s));
l = new DirectionalLight();
l->m_position = normalize(vec3(0.0f, 0.0f, 1.0f));
l->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
l = new PointLight();
l->m_position = vec3(0.0f, 0.9f, -1.0f);
l->m_diffuse = vec3(1.0f);
vl.push_back(static_cast<Light *>(l));
}
@@ -279,6 +292,14 @@ static void scene_3(vector<Figure *> & vf, vector<Light *> & vl, mat4x4 & i_mode
s->m_mat.m_ref_index = 1.33f;
vf.push_back(static_cast<Figure *>(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<Figure *>(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 = 0.6f;
@@ -286,6 +307,7 @@ static void scene_3(vector<Figure *> & vf, vector<Light *> & vl, mat4x4 & i_mode
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_shininess = 20.0f;
vf.push_back(static_cast<Figure *>(s));
p = new Plane(vec3(0.0f, -1.5f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
@@ -296,16 +318,24 @@ static void scene_3(vector<Figure *> & vf, vector<Light *> & vl, mat4x4 & i_mode
l = new DirectionalLight();
l->m_position = normalize(vec3(-1.0f, 1.0f, -1.0f));
l->m_diffuse = vec3(0.0f, 1.0f, 0.0f);
l->m_specular = vec3(0.0f, 1.0f, 0.0f);
vl.push_back(static_cast<Light *>(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<Light *>(l));
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<Light *>(l));
l = new DirectionalLight();
l->m_position = normalize(vec3(0.0f, 1.0f, 0.0f));
l->m_diffuse = vec3(0.5f);
vl.push_back(static_cast<Light *>(l));
i_model_view = inverse(lookAt(eye, center, up));

69113
output.ppm

File diff suppressed because one or more lines are too long

40
point_light.cpp Normal file
View File

@@ -0,0 +1,40 @@
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
#include "point_light.hpp"
using glm::pi;
using glm::reflect;
using glm::length;
using glm::normalize;
using glm::dot;
using glm::pow;
using glm::max;
inline vec3 PointLight::direction(vec3 point) {
return normalize(m_position - point);
}
inline float PointLight::distance(vec3 point) {
return length(m_position - point);
}
vec3 PointLight::shade(vec3 normal, Ray & r, float t, Material & m) const {
float d, att, n_dot_l, r_dot_l;
vec3 color, i_pos, 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.m_diffuse / pi<float>()) * m_diffuse * n_dot_l;
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;
}

30
point_light.hpp Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
#ifndef POINT_LIGHT_HPP
#define POINT_LIGHT_HPP
#include "light.hpp"
class PointLight: public Light {
public:
float m_const_att;
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(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;
}
virtual vec3 direction(vec3 point);
virtual float distance(vec3 point);
virtual vec3 shade(vec3 normal, Ray & r, float t, Material & m) const;
};
#endif

View File

@@ -77,16 +77,16 @@ vec3 Tracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> &
for (size_t l = 0; l < v_lights.size(); l++) {
vis = true;
sr = Ray(v_lights[l]->m_position, i_pos + n * BIAS);
sr = Ray(v_lights[l]->direction(i_pos), i_pos + n * BIAS);
for (size_t f = 0; f < v_figures.size(); f++) {
if (v_figures[f]->intersect(sr, _t)) {
if (v_figures[f]->intersect(sr, _t) && _t < v_lights[l]->distance(i_pos)) {
vis = false;
break;
}
}
color += (vis ? 1.0f : 0.0f) * v_lights[l]->shade(n, r, _f->m_mat);
color += (vis ? 1.0f : 0.0f) * v_lights[l]->shade(n, r, t, _f->m_mat);
}
if (_f->m_mat.m_refract)