Added point lights.
This commit is contained in:
6
Makefile
6
Makefile
@@ -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)
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
46
main.cpp
46
main.cpp
@@ -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
69113
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++) {
|
||||
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)
|
||||
|
Reference in New Issue
Block a user