New way of handling lights and materials.

This commit is contained in:
2017-01-01 20:57:35 -04:00
parent 2b1a9ed819
commit c78a8d284f
13 changed files with 141 additions and 108 deletions

View File

@@ -1,6 +1,6 @@
TARGET = ray TARGET = ray
HEADERS = ray.hpp figure.hpp sphere.hpp plane.hpp disk.hpp material.hpp light.hpp tracer.hpp 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 tracer.o OBJECTS = main.o sphere.o plane.o disk.o directional_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 = -lm LDLIBS = -lm
@@ -21,6 +21,8 @@ disk.o: disk.cpp $(HEADERS)
tracer.o: tracer.cpp $(HEADERS) tracer.o: tracer.cpp $(HEADERS)
directional_light.o: directional_light.cpp $(HEADERS)
.PHONY: clean .PHONY: clean
clean: clean:
$(RM) $(TARGET) $(OBJECTS) $(RM) $(TARGET) $(OBJECTS)

26
directional_light.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include <cmath>
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
#include "directional_light.hpp"
using glm::pi;
using glm::reflect;
using glm::dot;
vec3 DirectionalLight::shade(vec3 normal, Ray & r, Material & m) const {
float n_dot_l, r_dot_l;
vec3 color, ref;
//color = m.m_ambient * m_ambient;
n_dot_l = max(dot(normal, m_position), 0.0);
color += (m.m_diffuse / pi<float>()) * m_diffuse * n_dot_l;
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;
}

26
directional_light.hpp Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#ifndef DIRECTIONAL_LIGHT_HPP
#define DIRECTIONAL_LIGHT_HPP
#include "light.hpp"
class DirectionalLight: public Light {
public:
DirectionalLight() {
m_position = vec3(0.0f);
m_diffuse = vec3(1.0f);
m_specular = vec3(1.0f);
m_ambient = vec3(0.05f);
}
DirectionalLight(vec3 _p, vec3 _d, vec3 _s, vec3 _a) {
m_position = _p;
m_diffuse = _d;
m_specular = _s;
m_ambient = _a;
}
virtual vec3 shade(vec3 normal, Ray & r, Material & m) const;
};
#endif

View File

@@ -14,19 +14,16 @@ public:
float m_radius; float m_radius;
Disk(): m_radius(1.0f) { Disk(): m_radius(1.0f) {
rho = 0.0f;
m_point = vec3(0.0f); m_point = vec3(0.0f);
m_normal = vec3(0.0f, 1.0f, 0.0f); m_normal = vec3(0.0f, 1.0f, 0.0f);
} }
Disk(float x, float y, float z, float nx, float ny, float nz, float _r): m_radius(_r) { Disk(float x, float y, float z, float nx, float ny, float nz, float _r): m_radius(_r) {
rho = 0.0f;
m_point = vec3(x, y, z); m_point = vec3(x, y, z);
m_normal = normalize(vec3(nx, ny, nz)); m_normal = normalize(vec3(nx, ny, nz));
} }
Disk(vec3 _p, vec3 _n, float _r): m_radius(_r) { Disk(vec3 _p, vec3 _n, float _r): m_radius(_r) {
rho = 0.0f;
m_point = _p; m_point = _p;
m_normal = normalize(_n); m_normal = normalize(_n);
} }

View File

@@ -11,23 +11,12 @@ using glm::vec3;
class Figure { class Figure {
public: public:
vec3 color;
Material m_mat; Material m_mat;
float rho;
virtual ~Figure() { } virtual ~Figure() { }
virtual bool intersect(Ray & r, float & t) const = 0; virtual bool intersect(Ray & r, float & t) const = 0;
virtual vec3 normal_at_int(Ray & r, float & t) const = 0; virtual vec3 normal_at_int(Ray & r, float & t) const = 0;
virtual void set_color(float r, float g, float b) {
color = vec3(r, g, b);
}
virtual void set_color(vec3 rgb) {
color = vec3(rgb);
}
}; };
#endif #endif

View File

@@ -4,6 +4,9 @@
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include "ray.hpp"
#include "material.hpp"
using glm::vec3; using glm::vec3;
class Light { class Light {
@@ -13,8 +16,13 @@ public:
vec3 m_specular; vec3 m_specular;
vec3 m_ambient; vec3 m_ambient;
Light(): m_position(vec3(0.0f)), m_diffuse(vec3(1.0f)), m_specular(vec3(1.0f)), m_ambient(vec3(0.05f)) { } float max(float a, float b) const {
Light(vec3 _p, vec3 _d, vec3 _s, vec3 _a): m_position(_p), m_diffuse(_d), m_specular(_s), m_ambient(_a) { } return a >= b ? a : b;
}
virtual ~Light() { }
virtual vec3 shade(vec3 normal, Ray & r, Material & m) const = 0;
}; };
#endif #endif

View File

@@ -14,6 +14,7 @@
#include "plane.hpp" #include "plane.hpp"
#include "disk.hpp" #include "disk.hpp"
#include "light.hpp" #include "light.hpp"
#include "directional_light.hpp"
#include "tracer.hpp" #include "tracer.hpp"
using namespace std; using namespace std;
@@ -147,105 +148,106 @@ static void scene_1(vector<Figure *> & vf, vector<Light *> & vl) {
Sphere * s; Sphere * s;
Plane * p; Plane * p;
Disk * d; Disk * d;
Light * l; DirectionalLight * l;
s = new Sphere(1.0f, 1.0f, -2.0f, 0.5f); s = new Sphere(1.0f, 1.0f, -2.0f, 0.5f);
s->set_color(1.0f, 0.0f, 0.0f); s->m_mat.m_diffuse = vec3(1.0f, 0.0f, 0.0f);
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-1.0f, 1.0f, -2.0f, 0.5f); s = new Sphere(-1.0f, 1.0f, -2.0f, 0.5f);
s->set_color(0.0f, 1.0f, 0.0f); s->m_mat.m_diffuse = vec3(0.0f, 1.0f, 0.0f);
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
s = new Sphere(1.0f, -1.0f, -2.0f, 0.5f); s = new Sphere(1.0f, -1.0f, -2.0f, 0.5f);
s->set_color(0.0f, 0.0f, 1.0f); s->m_mat.m_diffuse = vec3(0.0f, 0.0f, 1.0f);
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-1.0f, -1.0f, -2.0f, 0.5f); s = new Sphere(-1.0f, -1.0f, -2.0f, 0.5f);
s->set_color(1.0f, 0.0f, 1.0f); s->m_mat.m_diffuse = vec3(1.0f, 0.0f, 1.0f);
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 0.0f, -2.0f, 1.0f); s = new Sphere(0.0f, 0.0f, -2.0f, 1.0f);
s->set_color(1.0f, 1.0f, 0.0f); //s->set_color(1.0f, 1.0f, 0.0f);
s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.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));
p->set_color(1.0f, 0.5f, 0.4f); p->m_mat.m_diffuse = vec3(1.0f, 0.5f, 0.4f);
vf.push_back(static_cast<Figure *>(p)); vf.push_back(static_cast<Figure *>(p));
s = new Sphere(-1.5f, 0.0f, -2.0f, 0.5f); s = new Sphere(-1.5f, 0.0f, -2.0f, 0.5f);
s->set_color(1.0f, 1.0f, 1.0f); s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f);
s->rho = 0.3f; s->m_mat.m_rho = 0.3f;
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
s = new Sphere(1.5f, 0.0f, -2.0f, 0.5f); s = new Sphere(1.5f, 0.0f, -2.0f, 0.5f);
s->set_color(1.0f, 1.0f, 1.0f); s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f);
s->rho = 0.08f; s->m_mat.m_rho = 0.08f;
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 1.5f, -2.0f, 0.5f); s = new Sphere(0.0f, 1.5f, -2.0f, 0.5f);
s->set_color(1.0f, 1.0f, 1.0f); s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f);
s->rho = 0.5f; s->m_mat.m_rho = 0.5f;
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 0.0f, -1.0f, 0.25f); s = new Sphere(0.0f, 0.0f, -1.0f, 0.25f);
s->set_color(1.0f, 1.0f, 1.0f); s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f);
s->rho = 0.1f; s->m_mat.m_rho = 0.1f;
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
d = new Disk(vec3(0.0f, 2.0f, -2.0f), vec3(0.0f, -1.0f, 0.0f), 1.0f); d = new Disk(vec3(0.0f, 2.0f, -2.0f), vec3(0.0f, -1.0f, 0.0f), 1.0f);
d->set_color(1.0f, 1.0f, 0.0f); d->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f);
d->rho = 0.8f; d->m_mat.m_rho = 0.8f;
vf.push_back(static_cast<Figure *>(d)); vf.push_back(static_cast<Figure *>(d));
l = new Light(); 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, 1.0f); l->m_diffuse = vec3(0.0f, 1.0f, 1.0f);
vl.push_back(l); vl.push_back(static_cast<Light *>(l));
l = new Light(); 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(1.0f, 1.0f, 0.0f); l->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
vl.push_back(l); vl.push_back(static_cast<Light *>(l));
l = new Light(); 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, 1.0f); l->m_diffuse = vec3(1.0f, 0.0f, 1.0f);
vl.push_back(l); vl.push_back(static_cast<Light *>(l));
} }
static void scene_2(vector<Figure *> & vf, vector<Light *> & vl) { static void scene_2(vector<Figure *> & vf, vector<Light *> & vl) {
Sphere * s; Sphere * s;
Plane * p; Plane * p;
Light * l; DirectionalLight * l;
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->set_color(0.0f, 1.0f, 0.0f); //p->set_color(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(-1.0f, 0.0f, 0.0f), vec3(1.0f, 0.0f, 0.0f));
p->set_color(1.0f, 0.0f, 0.0f); //p->set_color(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(1.0f, 0.0f, 0.0f), vec3(-1.0f, 0.0f, 0.0f));
p->set_color(0.0f, 0.0f, 1.0f); //p->set_color(0.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, 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->set_color(1.0f, 1.0f, 1.0f); //p->set_color(1.0f, 1.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, -2.0f), vec3(0.0f, 0.0f, 1.0f)); p = new Plane(vec3(0.0f, 0.0f, -2.0f), vec3(0.0f, 0.0f, 1.0f));
p->set_color(1.0f, 0.0f, 1.0f); //p->set_color(1.0f, 0.0f, 1.0f);
vf.push_back(static_cast<Figure *>(p)); 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->set_color(1.0f, 1.0f, 0.0f); //s->set_color(1.0f, 1.0f, 0.0f);
s->rho = 0.4f; //s->rho = 0.4f;
vf.push_back(static_cast<Figure *>(s)); vf.push_back(static_cast<Figure *>(s));
l = new Light(); l = new DirectionalLight();
l->m_position = normalize(vec3(0.0f, 0.0f, 1.0f)); l->m_position = normalize(vec3(0.0f, 0.0f, 1.0f));
l->m_diffuse = vec3(1.0f, 1.0f, 1.0f); l->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
vl.push_back(l); vl.push_back(static_cast<Light *>(l));
} }

View File

@@ -13,8 +13,18 @@ public:
vec3 m_ambient; vec3 m_ambient;
float m_rho; float m_rho;
float m_shininess; float m_shininess;
float m_ref_index;
Material(): m_diffuse(vec3(1.0f)), m_specular(vec3(1.0f)), m_ambient(vec3(1.0f)), m_rho(0.0f), m_shininess(89.0f) { } Material(): m_diffuse(vec3(1.0f)), m_specular(vec3(1.0f)), m_ambient(vec3(1.0f)), m_rho(0.0f), m_shininess(89.0f), m_ref_index(1.0f) { }
Material(const Material & m) {
m_diffuse = m.m_diffuse;
m_specular = m.m_specular;
m_ambient = m.m_ambient;
m_rho = m.m_rho;
m_shininess = m.m_shininess;
m_ref_index = m.m_ref_index;
}
}; };
#endif #endif

Binary file not shown.

View File

@@ -14,17 +14,11 @@ public:
vec3 m_point; vec3 m_point;
vec3 m_normal; vec3 m_normal;
Plane(): m_point(vec3(0.0f)), m_normal(0.0f, 0.0f, 1.0f) { Plane(): m_point(vec3(0.0f)), m_normal(0.0f, 0.0f, 1.0f) { }
rho = 0.0f;
}
Plane(float x, float y, float z, float nx, float ny, float nz): m_point(vec3(x, y, z)), m_normal(normalize(vec3(nx, ny, nz))) { Plane(float x, float y, float z, float nx, float ny, float nz): m_point(vec3(x, y, z)), m_normal(normalize(vec3(nx, ny, nz))) { }
rho = 0.0f;
}
Plane(vec3 _p, vec3 _n): m_point(_p), m_normal(normalize(_n)) { Plane(vec3 _p, vec3 _n): m_point(_p), m_normal(normalize(_n)) { }
rho = 0.0f;
}
virtual ~Plane() { } virtual ~Plane() { }

View File

@@ -13,13 +13,9 @@ public:
vec3 m_center; vec3 m_center;
float m_radius; float m_radius;
Sphere(): m_center(vec3(0.0f)), m_radius(0.5f) { Sphere(): m_center(vec3(0.0f)), m_radius(0.5f) { }
rho = 0.0f;
}
Sphere(float x, float y, float z, float r): m_center(vec3(x, y, z)), m_radius(r) { Sphere(float x, float y, float z, float r): m_center(vec3(x, y, z)), m_radius(r) { }
rho = 0.0f;
}
Sphere(vec3 _c, float r): m_center(_c), m_radius(r) { } Sphere(vec3 _c, float r): m_center(_c), m_radius(r) { }

View File

@@ -1,14 +1,10 @@
#include <iostream>
#include <limits> #include <limits>
#include <cstdlib> #include <cstdlib>
#include <cmath>
#include <omp.h> #include <omp.h>
#include "tracer.hpp" #include "tracer.hpp"
#define PI 3.14159265358979f
#define SHININESS 89.0f
#define MAX_RECURSION 9 #define MAX_RECURSION 9
#define BIAS 0.000001f #define BIAS 0.000001f
@@ -20,23 +16,14 @@ using glm::radians;
using glm::dot; using glm::dot;
using glm::reflect; using glm::reflect;
using glm::clamp; using glm::clamp;
using glm::tan;
static const vec3 BCKG_COLOR = vec3(0.16f, 0.66f, 0.72f); static const vec3 BCKG_COLOR = vec3(0.16f, 0.66f, 0.72f);
static inline float max(float a, float b) {
return a >= b ? a : b;
}
static inline float random01() { static inline float random01() {
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX); return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
} }
Tracer::Tracer(): m_h(480), m_w(640), m_fov(90.0f), m_a_ratio(640.0f / 480.0f) {}
Tracer::Tracer(int h, int w, float fov): m_h(h), m_w(w), m_fov(fov) {
m_a_ratio = static_cast<float>(w) / static_cast<float>(h);
}
vec2 Tracer::sample_pixel(int i, int j) const { vec2 Tracer::sample_pixel(int i, int j) const {
float pxNDC; float pxNDC;
float pyNDC; float pyNDC;
@@ -51,9 +38,8 @@ vec2 Tracer::sample_pixel(int i, int j) const {
return vec2(pxS, pyS); return vec2(pxS, pyS);
} }
vec3 Tracer::trace_ray(Ray & r, vector<Figure *> & vf, vector<Light *> & vl, unsigned int rec_level) const { vec3 Tracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> & v_lights, unsigned int rec_level) const {
size_t f_index; float t, _t;
float t, _t, n_dot_l;
Figure * _f; Figure * _f;
vec3 n, color, i_pos, ref; vec3 n, color, i_pos, ref;
Ray sr, rr; Ray sr, rr;
@@ -62,11 +48,10 @@ vec3 Tracer::trace_ray(Ray & r, vector<Figure *> & vf, vector<Light *> & vl, uns
t = numeric_limits<float>::max(); t = numeric_limits<float>::max();
_f = NULL; _f = NULL;
for (size_t f = 0; f < vf.size(); f++) { for (size_t f = 0; f < v_figures.size(); f++) {
if (vf[f]->intersect(r, _t) && _t < t) { if (v_figures[f]->intersect(r, _t) && _t < t) {
t = _t; t = _t;
_f = vf[f]; _f = v_figures[f];
f_index = f;
} }
} }
@@ -74,33 +59,29 @@ vec3 Tracer::trace_ray(Ray & r, vector<Figure *> & vf, vector<Light *> & vl, uns
i_pos = r.m_origin + (t * r.m_direction); i_pos = r.m_origin + (t * r.m_direction);
n = _f->normal_at_int(r, t); n = _f->normal_at_int(r, t);
if (_f->rho > 0.0f && rec_level < MAX_RECURSION) { for (size_t l = 0; l < v_lights.size(); l++) {
rr = Ray(reflect(r.m_direction, n), i_pos + n * BIAS);
color = _f->rho * trace_ray(rr, vf, vl, rec_level + 1);
} else if (rec_level >= MAX_RECURSION)
return vec3(BCKG_COLOR);
for (size_t l = 0; l < vl.size(); l++) {
vis = true; vis = true;
sr = Ray(vl[l]->m_position, i_pos + n * BIAS); sr = Ray(v_lights[l]->m_position, i_pos + n * BIAS);
for (size_t f = 0; f < vf.size(); f++) { for (size_t f = 0; f < v_figures.size(); f++) {
if (vf[f]->intersect(sr, _t)) { if (v_figures[f]->intersect(sr, _t)) {
vis = false; vis = false;
break; break;
} }
} }
color += 0.08f * BCKG_COLOR; color += (vis ? 1.0f : 0.0f) * v_lights[l]->shade(n, r, _f->m_mat);
n_dot_l = max(dot(n, vl[l]->m_position), 0.0);
color += (vis ? 1.0f : 0.0f) * (_f->color / PI) * vl[l]->m_diffuse * n_dot_l;
ref = reflect(vl[l]->m_position, n);
color += (vis ? 1.0f : 0.0f) * vl[l]->m_specular * pow(max(dot(ref, r.m_direction), 0.0f), SHININESS);
} }
if (_f->m_mat.m_rho > 0.0f && rec_level < MAX_RECURSION) {
rr = Ray(reflect(r.m_direction, n), i_pos + n * BIAS);
color += _f->m_mat.m_rho * trace_ray(rr, v_figures, v_lights, rec_level + 1);
} else if (rec_level >= MAX_RECURSION)
return vec3(BCKG_COLOR);
return clamp(color, 0.0f, 1.0f); return clamp(color, 0.0f, 1.0f);
} else } else
return vec3(BCKG_COLOR); return vec3(BCKG_COLOR);
} }

View File

@@ -21,12 +21,14 @@ public:
float m_fov; float m_fov;
float m_a_ratio; float m_a_ratio;
Tracer(); Tracer(): m_h(480), m_w(640), m_fov(90.0f), m_a_ratio(640.0f / 480.0f) { }
Tracer(int h, int w, float fov); Tracer(int h, int w, float fov): m_h(h), m_w(w), m_fov(fov) {
m_a_ratio = static_cast<float>(w) / static_cast<float>(h);
};
vec2 sample_pixel(int i, int j) const; vec2 sample_pixel(int i, int j) const;
vec3 trace_ray(Ray & r, vector<Figure *> & f, vector<Light *> & l, unsigned int rec_level) const; vec3 trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> & v_lights, unsigned int rec_level) const;
}; };
#endif #endif