Added refractions and fresnel.

This commit is contained in:
2017-01-02 00:08:22 -04:00
parent c78a8d284f
commit 806040018e
7 changed files with 93 additions and 30 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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));
}

View File

@@ -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;
} }
}; };

Binary file not shown.

View File

@@ -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

View File

@@ -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);