Added refractions and fresnel.
This commit is contained in:
@@ -13,8 +13,6 @@ vec3 DirectionalLight::shade(vec3 normal, Ray & r, Material & m) const {
|
|||||||
float n_dot_l, r_dot_l;
|
float n_dot_l, r_dot_l;
|
||||||
vec3 color, ref;
|
vec3 color, ref;
|
||||||
|
|
||||||
//color = m.m_ambient * m_ambient;
|
|
||||||
|
|
||||||
n_dot_l = max(dot(normal, m_position), 0.0);
|
n_dot_l = max(dot(normal, m_position), 0.0);
|
||||||
color += (m.m_diffuse / pi<float>()) * m_diffuse * n_dot_l;
|
color += (m.m_diffuse / pi<float>()) * m_diffuse * n_dot_l;
|
||||||
|
|
||||||
|
@@ -10,14 +10,12 @@ public:
|
|||||||
m_position = vec3(0.0f);
|
m_position = vec3(0.0f);
|
||||||
m_diffuse = vec3(1.0f);
|
m_diffuse = vec3(1.0f);
|
||||||
m_specular = vec3(1.0f);
|
m_specular = vec3(1.0f);
|
||||||
m_ambient = vec3(0.05f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectionalLight(vec3 _p, vec3 _d, vec3 _s, vec3 _a) {
|
DirectionalLight(vec3 _p, vec3 _d, vec3 _s) {
|
||||||
m_position = _p;
|
m_position = _p;
|
||||||
m_diffuse = _d;
|
m_diffuse = _d;
|
||||||
m_specular = _s;
|
m_specular = _s;
|
||||||
m_ambient = _a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual vec3 shade(vec3 normal, Ray & r, Material & m) const;
|
virtual vec3 shade(vec3 normal, Ray & r, Material & m) const;
|
||||||
|
60
main.cpp
60
main.cpp
@@ -31,6 +31,7 @@ static vec3 ** image;
|
|||||||
|
|
||||||
static void scene_1(vector<Figure *> & vf, vector<Light *> & vl);
|
static void scene_1(vector<Figure *> & vf, vector<Light *> & vl);
|
||||||
static void scene_2(vector<Figure *> & vf, vector<Light *> & vl);
|
static void scene_2(vector<Figure *> & vf, vector<Light *> & vl);
|
||||||
|
static void scene_3(vector<Figure *> & vf, vector<Light *> & vl);
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
FILE * out;
|
FILE * out;
|
||||||
@@ -90,7 +91,7 @@ int main(int argc, char ** argv) {
|
|||||||
image[i] = new vec3[g_w];
|
image[i] = new vec3[g_w];
|
||||||
}
|
}
|
||||||
|
|
||||||
scene_1(figures, lights);
|
scene_3(figures, lights);
|
||||||
|
|
||||||
tracer = Tracer(g_h, g_w, g_fov);
|
tracer = Tracer(g_h, g_w, g_fov);
|
||||||
|
|
||||||
@@ -167,7 +168,6 @@ static void scene_1(vector<Figure *> & vf, vector<Light *> & vl) {
|
|||||||
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->m_mat.m_diffuse = vec3(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));
|
||||||
|
|
||||||
@@ -183,6 +183,8 @@ static void scene_1(vector<Figure *> & vf, vector<Light *> & vl) {
|
|||||||
s = new Sphere(1.5f, 0.0f, -2.0f, 0.5f);
|
s = new Sphere(1.5f, 0.0f, -2.0f, 0.5f);
|
||||||
s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f);
|
s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f);
|
||||||
s->m_mat.m_rho = 0.08f;
|
s->m_mat.m_rho = 0.08f;
|
||||||
|
s->m_mat.m_refract = true;
|
||||||
|
s->m_mat.m_ref_index = 1.1f;
|
||||||
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);
|
||||||
@@ -195,9 +197,11 @@ static void scene_1(vector<Figure *> & vf, vector<Light *> & vl) {
|
|||||||
s->m_mat.m_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, -0.0f, -0.5f), vec3(0.0f, 0.0f, 0.1f), 0.25f);
|
||||||
d->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f);
|
d->m_mat.m_diffuse = vec3(1.0f, 0.0f, 0.0f);
|
||||||
d->m_mat.m_rho = 0.8f;
|
d->m_mat.m_rho = 0.3f;
|
||||||
|
d->m_mat.m_refract = true;
|
||||||
|
d->m_mat.m_ref_index = 1.33f;
|
||||||
vf.push_back(static_cast<Figure *>(d));
|
vf.push_back(static_cast<Figure *>(d));
|
||||||
|
|
||||||
l = new DirectionalLight();
|
l = new DirectionalLight();
|
||||||
@@ -222,28 +226,28 @@ static void scene_2(vector<Figure *> & vf, vector<Light *> & vl) {
|
|||||||
DirectionalLight * 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->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(-1.0f, 0.0f, 0.0f), vec3(1.0f, 0.0f, 0.0f));
|
||||||
//p->set_color(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(1.0f, 0.0f, 0.0f), vec3(-1.0f, 0.0f, 0.0f));
|
||||||
//p->set_color(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));
|
||||||
|
|
||||||
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->m_mat.m_diffuse = vec3(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->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));
|
||||||
|
|
||||||
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->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.0f);
|
||||||
//s->rho = 0.4f;
|
s->m_mat.m_rho = 0.4f;
|
||||||
vf.push_back(static_cast<Figure *>(s));
|
vf.push_back(static_cast<Figure *>(s));
|
||||||
|
|
||||||
l = new DirectionalLight();
|
l = new DirectionalLight();
|
||||||
@@ -251,3 +255,35 @@ static void scene_2(vector<Figure *> & vf, vector<Light *> & vl) {
|
|||||||
l->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
|
l->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
|
||||||
vl.push_back(static_cast<Light *>(l));
|
vl.push_back(static_cast<Light *>(l));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void scene_3(vector<Figure *> & vf, vector<Light *> & vl) {
|
||||||
|
Sphere * s;
|
||||||
|
Plane * p;
|
||||||
|
DirectionalLight * l;
|
||||||
|
|
||||||
|
s = new Sphere(0.0f, -0.15f, -2.0f, 1.0f);
|
||||||
|
s->m_mat.m_diffuse = vec3(1.0f, 0.5f, 0.0f);
|
||||||
|
s->m_mat.m_rho = 0.4f;
|
||||||
|
s->m_mat.m_refract = true;
|
||||||
|
s->m_mat.m_ref_index = 1.33f;
|
||||||
|
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;
|
||||||
|
vf.push_back(static_cast<Figure *>(s));
|
||||||
|
|
||||||
|
s = new Sphere(-1.0f, 0.25f, -3.25f, 1.0f);
|
||||||
|
s->m_mat.m_diffuse = vec3(1.0f, 1.0f, 0.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));
|
||||||
|
p->m_mat.m_diffuse = vec3(1.0f, 1.0f, 1.0f);
|
||||||
|
p->m_mat.m_specular = vec3(0.0f);
|
||||||
|
vf.push_back(static_cast<Figure *>(p));
|
||||||
|
|
||||||
|
l = new DirectionalLight();
|
||||||
|
l->m_position = normalize(vec3(-1.0f, 1.0f, 1.0f));
|
||||||
|
l->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
|
||||||
|
vl.push_back(static_cast<Light *>(l));
|
||||||
|
}
|
||||||
|
@@ -10,20 +10,20 @@ class Material {
|
|||||||
public:
|
public:
|
||||||
vec3 m_diffuse;
|
vec3 m_diffuse;
|
||||||
vec3 m_specular;
|
vec3 m_specular;
|
||||||
vec3 m_ambient;
|
|
||||||
float m_rho;
|
float m_rho;
|
||||||
float m_shininess;
|
float m_shininess;
|
||||||
float m_ref_index;
|
float m_ref_index;
|
||||||
|
bool m_refract;
|
||||||
|
|
||||||
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(): m_diffuse(vec3(1.0f)), m_specular(vec3(1.0f)), m_rho(0.0f), m_shininess(89.0f), m_ref_index(1.0f), m_refract(false) { }
|
||||||
|
|
||||||
Material(const Material & m) {
|
Material(const Material & m) {
|
||||||
m_diffuse = m.m_diffuse;
|
m_diffuse = m.m_diffuse;
|
||||||
m_specular = m.m_specular;
|
m_specular = m.m_specular;
|
||||||
m_ambient = m.m_ambient;
|
|
||||||
m_rho = m.m_rho;
|
m_rho = m.m_rho;
|
||||||
m_shininess = m.m_shininess;
|
m_shininess = m.m_shininess;
|
||||||
m_ref_index = m.m_ref_index;
|
m_ref_index = m.m_ref_index;
|
||||||
|
m_refract = m.m_refract;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BIN
output.ppm
BIN
output.ppm
Binary file not shown.
9
ray.hpp
9
ray.hpp
@@ -10,10 +10,13 @@ class Ray {
|
|||||||
public:
|
public:
|
||||||
vec3 m_direction;
|
vec3 m_direction;
|
||||||
vec3 m_origin;
|
vec3 m_origin;
|
||||||
|
float m_ref_index;
|
||||||
|
|
||||||
Ray(): m_direction(vec3(0.0f, 0.0f, -1.0f)), m_origin(vec3(0.0f)) { }
|
Ray(): m_direction(vec3(0.0f, 0.0f, -1.0f)), m_origin(vec3(0.0f)), m_ref_index(1.0f) { }
|
||||||
Ray(float dx, float dy, float dz, float ox, float oy, float oz): m_direction(vec3(dx, dy, dz)), m_origin(vec3(ox, oy, oz)) {}
|
Ray(float dx, float dy, float dz, float ox, float oy, float oz, float _r = 1.0f): m_direction(vec3(dx, dy, dz)),
|
||||||
Ray(vec3 _d, vec3 _o): m_direction(_d), m_origin(_o) { }
|
m_origin(vec3(ox, oy, oz)),
|
||||||
|
m_ref_index(_r) { }
|
||||||
|
Ray(vec3 _d, vec3 _o, float _r = 1.0f): m_direction(_d), m_origin(_o), m_ref_index(_r) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
42
tracer.cpp
42
tracer.cpp
@@ -1,8 +1,7 @@
|
|||||||
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <omp.h>
|
|
||||||
|
|
||||||
#include "tracer.hpp"
|
#include "tracer.hpp"
|
||||||
|
|
||||||
#define MAX_RECURSION 9
|
#define MAX_RECURSION 9
|
||||||
@@ -15,8 +14,10 @@ using glm::normalize;
|
|||||||
using glm::radians;
|
using glm::radians;
|
||||||
using glm::dot;
|
using glm::dot;
|
||||||
using glm::reflect;
|
using glm::reflect;
|
||||||
|
using glm::refract;
|
||||||
using glm::clamp;
|
using glm::clamp;
|
||||||
using glm::tan;
|
using glm::tan;
|
||||||
|
using glm::cos;
|
||||||
|
|
||||||
static const vec3 BCKG_COLOR = vec3(0.16f, 0.66f, 0.72f);
|
static const vec3 BCKG_COLOR = vec3(0.16f, 0.66f, 0.72f);
|
||||||
|
|
||||||
@@ -24,16 +25,30 @@ static inline float random01() {
|
|||||||
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float fresnel(const vec3 & i, const vec3 & n, const float ir1, const float ir2) {
|
||||||
|
float cos_t1 = dot(i, n);
|
||||||
|
float cos_t2 = dot(normalize(refract(i, n, ir1 / ir2)), n);
|
||||||
|
float sin_t2 = (ir1 / ir2) * sqrt(1.0f - (cos_t2 * cos_t2));
|
||||||
|
|
||||||
|
if (sin_t2 >= 1.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
float fr_par = ((ir2 * cos_t1) - (ir1 * cos_t2)) / ((ir2 * cos_t1) + (ir1 * cos_t2));
|
||||||
|
float fr_per = ((ir1 * cos_t2) - (ir2 * cos_t1)) / ((ir1 * cos_t2) + (ir2 * cos_t1));
|
||||||
|
|
||||||
|
return ((fr_par * fr_par) + (fr_per * fr_per)) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
float pxS;
|
float pxS;
|
||||||
float pyS;
|
float pyS;
|
||||||
pyNDC = (static_cast<float>(i) + random01()) / m_h;
|
pyNDC = (static_cast<float>(i) + random01()) / m_h;
|
||||||
pyS = (1.0f - (2.0f * pyNDC)) * tan(radians(m_fov) / 2);
|
pyS = (1.0f - (2.0f * pyNDC)) * tan(radians(m_fov / 2));
|
||||||
pxNDC = (static_cast<float>(j) + random01()) / m_w;
|
pxNDC = (static_cast<float>(j) + random01()) / m_w;
|
||||||
pxS = (2.0f * pxNDC) - 1.0f;
|
pxS = (2.0f * pxNDC) - 1.0f;
|
||||||
pxS *= m_a_ratio * tan(radians(m_fov) / 2);
|
pxS *= m_a_ratio * tan(radians(m_fov / 2));
|
||||||
|
|
||||||
return vec2(pxS, pyS);
|
return vec2(pxS, pyS);
|
||||||
}
|
}
|
||||||
@@ -44,6 +59,7 @@ vec3 Tracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> &
|
|||||||
vec3 n, color, i_pos, ref;
|
vec3 n, color, i_pos, ref;
|
||||||
Ray sr, rr;
|
Ray sr, rr;
|
||||||
bool vis;
|
bool vis;
|
||||||
|
float kr;
|
||||||
|
|
||||||
t = numeric_limits<float>::max();
|
t = numeric_limits<float>::max();
|
||||||
_f = NULL;
|
_f = NULL;
|
||||||
@@ -73,9 +89,21 @@ vec3 Tracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> &
|
|||||||
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, _f->m_mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_f->m_mat.m_rho > 0.0f && rec_level < MAX_RECURSION) {
|
if (_f->m_mat.m_refract)
|
||||||
rr = Ray(reflect(r.m_direction, n), i_pos + n * BIAS);
|
kr = fresnel(r.m_direction, n, r.m_ref_index, _f->m_mat.m_ref_index);
|
||||||
color += _f->m_mat.m_rho * trace_ray(rr, v_figures, v_lights, rec_level + 1);
|
else
|
||||||
|
kr = _f->m_mat.m_rho;
|
||||||
|
|
||||||
|
if (kr > 0.0f && rec_level < MAX_RECURSION) {
|
||||||
|
rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS);
|
||||||
|
color += _f->m_mat.m_rho * kr * trace_ray(rr, v_figures, v_lights, rec_level + 1);
|
||||||
|
|
||||||
|
} else if (rec_level >= MAX_RECURSION)
|
||||||
|
return vec3(BCKG_COLOR);
|
||||||
|
|
||||||
|
if (_f->m_mat.m_refract && kr < 1.0f && rec_level < MAX_RECURSION) {
|
||||||
|
rr = Ray(normalize(refract(r.m_direction, n, r.m_ref_index / _f->m_mat.m_ref_index)), i_pos - n * BIAS, _f->m_mat.m_ref_index);
|
||||||
|
color += (1.0f - _f->m_mat.m_rho) * (1.0f - kr) * trace_ray(rr, v_figures, v_lights, rec_level + 1);
|
||||||
|
|
||||||
} else if (rec_level >= MAX_RECURSION)
|
} else if (rec_level >= MAX_RECURSION)
|
||||||
return vec3(BCKG_COLOR);
|
return vec3(BCKG_COLOR);
|
||||||
|
Reference in New Issue
Block a user