Added point lights.
This commit is contained in:
6
Makefile
6
Makefile
@@ -1,6 +1,6 @@
|
|||||||
TARGET = ray
|
TARGET = ray
|
||||||
HEADERS = ray.hpp figure.hpp sphere.hpp plane.hpp disk.hpp material.hpp light.hpp directional_light.hpp tracer.hpp
|
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 tracer.o
|
OBJECTS = main.o sphere.o plane.o disk.o directional_light.o point_light.o tracer.o
|
||||||
CXX = g++
|
CXX = g++
|
||||||
CXXFLAGS = -ansi -pedantic -Wall -g -DGLM_FORCE_RADIANS -fopenmp
|
CXXFLAGS = -ansi -pedantic -Wall -g -DGLM_FORCE_RADIANS -fopenmp
|
||||||
LDLIBS =
|
LDLIBS =
|
||||||
@@ -23,6 +23,8 @@ tracer.o: tracer.cpp $(HEADERS)
|
|||||||
|
|
||||||
directional_light.o: directional_light.cpp $(HEADERS)
|
directional_light.o: directional_light.cpp $(HEADERS)
|
||||||
|
|
||||||
|
point_light.o: point_light.cpp $(HEADERS)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(TARGET) $(OBJECTS)
|
$(RM) $(TARGET) $(OBJECTS)
|
||||||
|
@@ -1,15 +1,26 @@
|
|||||||
|
#include <limits>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/constants.hpp>
|
#include <glm/gtc/constants.hpp>
|
||||||
|
|
||||||
#include "directional_light.hpp"
|
#include "directional_light.hpp"
|
||||||
|
|
||||||
|
using std::numeric_limits;
|
||||||
using glm::pi;
|
using glm::pi;
|
||||||
using glm::reflect;
|
using glm::reflect;
|
||||||
using glm::dot;
|
using glm::dot;
|
||||||
using glm::pow;
|
using glm::pow;
|
||||||
using glm::max;
|
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;
|
float n_dot_l, r_dot_l;
|
||||||
vec3 color, ref;
|
vec3 color, ref;
|
||||||
|
|
||||||
|
@@ -18,7 +18,9 @@ public:
|
|||||||
m_specular = _s;
|
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
|
#endif
|
||||||
|
@@ -14,11 +14,12 @@ public:
|
|||||||
vec3 m_position;
|
vec3 m_position;
|
||||||
vec3 m_diffuse;
|
vec3 m_diffuse;
|
||||||
vec3 m_specular;
|
vec3 m_specular;
|
||||||
vec3 m_ambient;
|
|
||||||
|
|
||||||
virtual ~Light() { }
|
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
|
#endif
|
||||||
|
46
main.cpp
46
main.cpp
@@ -16,6 +16,7 @@
|
|||||||
#include "disk.hpp"
|
#include "disk.hpp"
|
||||||
#include "light.hpp"
|
#include "light.hpp"
|
||||||
#include "directional_light.hpp"
|
#include "directional_light.hpp"
|
||||||
|
#include "point_light.hpp"
|
||||||
#include "tracer.hpp"
|
#include "tracer.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -94,7 +95,7 @@ int main(int argc, char ** argv) {
|
|||||||
image[i] = new vec3[g_w];
|
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);
|
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) {
|
static void scene_2(vector<Figure *> & vf, vector<Light *> & vl, mat4x4 & i_model_view) {
|
||||||
Sphere * s;
|
Sphere * s;
|
||||||
Plane * p;
|
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 = 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);
|
||||||
vf.push_back(static_cast<Figure *>(p));
|
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);
|
p->m_mat.m_diffuse = vec3(1.0f, 0.0f, 0.0f);
|
||||||
vf.push_back(static_cast<Figure *>(p));
|
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);
|
p->m_mat.m_diffuse = vec3(0.0f, 0.0f, 1.0f);
|
||||||
vf.push_back(static_cast<Figure *>(p));
|
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);
|
p->m_mat.m_diffuse = vec3(1.0f, 0.0f, 1.0f);
|
||||||
vf.push_back(static_cast<Figure *>(p));
|
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 = 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_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));
|
vf.push_back(static_cast<Figure *>(s));
|
||||||
|
|
||||||
l = new DirectionalLight();
|
l = new PointLight();
|
||||||
l->m_position = normalize(vec3(0.0f, 0.0f, 1.0f));
|
l->m_position = vec3(0.0f, 0.9f, -1.0f);
|
||||||
l->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
|
l->m_diffuse = vec3(1.0f);
|
||||||
vl.push_back(static_cast<Light *>(l));
|
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;
|
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->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 = 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_diffuse = vec3(1.0f, 0.0f, 1.0f);
|
||||||
s->m_mat.m_rho = 0.6f;
|
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 = 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;
|
||||||
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));
|
||||||
@@ -296,16 +318,24 @@ static void scene_3(vector<Figure *> & vf, vector<Light *> & vl, mat4x4 & i_mode
|
|||||||
l = new DirectionalLight();
|
l = new DirectionalLight();
|
||||||
l->m_position = normalize(vec3(-1.0f, 1.0f, -1.0f));
|
l->m_position = normalize(vec3(-1.0f, 1.0f, -1.0f));
|
||||||
l->m_diffuse = vec3(0.0f, 1.0f, 0.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));
|
vl.push_back(static_cast<Light *>(l));
|
||||||
|
|
||||||
l = new DirectionalLight();
|
l = new DirectionalLight();
|
||||||
l->m_position = normalize(vec3(0.0f, 1.0f, 1.0f));
|
l->m_position = normalize(vec3(0.0f, 1.0f, 1.0f));
|
||||||
l->m_diffuse = vec3(1.0f, 0.0f, 0.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));
|
vl.push_back(static_cast<Light *>(l));
|
||||||
|
|
||||||
l = new DirectionalLight();
|
l = new DirectionalLight();
|
||||||
l->m_position = normalize(vec3(1.0f, 1.0f, -1.0f));
|
l->m_position = normalize(vec3(1.0f, 1.0f, -1.0f));
|
||||||
l->m_diffuse = vec3(0.0f, 0.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));
|
vl.push_back(static_cast<Light *>(l));
|
||||||
|
|
||||||
i_model_view = inverse(lookAt(eye, center, up));
|
i_model_view = inverse(lookAt(eye, center, up));
|
||||||
|
69069
output.ppm
69069
output.ppm
File diff suppressed because one or more lines are too long
40
point_light.cpp
Normal file
40
point_light.cpp
Normal 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
30
point_light.hpp
Normal 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
|
@@ -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++) {
|
for (size_t l = 0; l < v_lights.size(); l++) {
|
||||||
vis = true;
|
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++) {
|
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;
|
vis = false;
|
||||||
break;
|
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)
|
if (_f->m_mat.m_refract)
|
||||||
|
Reference in New Issue
Block a user