Scene reader reads figures now.

This commit is contained in:
2017-01-18 21:46:24 -04:00
parent 5edccd4d30
commit d0ffec8f60
14 changed files with 596 additions and 387 deletions

251
TODO.org
View File

@@ -27,3 +27,254 @@
- [ ] Texture mapping - [ ] Texture mapping
- [ ] Photon mapping - [ ] Photon mapping
* Junk
#+BEGIN_SRC c++
void scene_1(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c) {
Sphere * s;
Plane * p;
Disk * d;
DirectionalLight * l;
e = new Environment(NULL, false, vec3(0.7f, 0.4f, 0.05f));
s = new Sphere(1.0f, 1.0f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 0.0f);
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-1.0f, 1.0f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(0.0f, 1.0f, 0.0f);
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(1.0f, -1.0f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(0.0f, 0.0f, 1.0f);
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-1.0f, -1.0f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f);
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 0.0f, -2.0f, 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, 0.5f, 0.4f);
vf.push_back(static_cast<Figure *>(p));
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_rho = 0.3f;
vf.push_back(static_cast<Figure *>(s));
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_rho = 0.08f;
s->m_mat->m_refract = true;
s->m_mat->m_ref_index = 1.1f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 1.5f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
s->m_mat->m_rho = 0.5f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 0.0f, -1.0f, 0.25f);
s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
s->m_mat->m_rho = 0.1f;
vf.push_back(static_cast<Figure *>(s));
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, 0.0f, 0.0f);
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));
l = new DirectionalLight();
l->m_position = normalize(vec3(1.0f, 1.0f, 1.0f));
l->m_diffuse = vec3(0.0f, 1.0f, 1.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(1.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, 1.0f);
vl.push_back(static_cast<Light *>(l));
}
void scene_2(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c) {
Sphere * s;
Plane * p;
Disk * d;
PointLight * l;
s = new Sphere(0.2f, 0.0f, -0.75f, 0.25f);
s->m_mat->m_diffuse = vec3(1.0f);
s->m_mat->m_rho = 0.2f;
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);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
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_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
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_specular = vec3(0.0f);
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->m_mat->m_diffuse = vec3(0.0f, 1.0f, 1.0f);
p->m_mat->m_specular = vec3(0.0f);
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->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(0.0f, 0.0f, 1.1f), vec3(0.0f, 0.0f, -1.0f));
p->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
s = new Sphere(-0.5f, -0.5f, -1.5f, 0.5f);
s->m_mat->m_diffuse = vec3(0.0f);
s->m_mat->m_rho = 1.0f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-0.5f, -0.5f, 0.6f, 0.5f);
s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
s->m_mat->m_refract = true;
s->m_mat->m_ref_index = 1.33f;
vf.push_back(static_cast<Figure *>(s));
d = new Disk(vec3(-0.25f, 1.0f, -1.0f), vec3(1.0f, 0.0f, 0.0f), 0.25f);
d->m_mat->m_diffuse = vec3(1.0f);
vf.push_back(static_cast<Figure *>(d));
d = new Disk(vec3(0.25f, 1.0f, -1.0f), vec3(-1.0f, 0.0f, 0.0f), 0.25f);
d->m_mat->m_diffuse = vec3(1.0f);
vf.push_back(static_cast<Figure *>(d));
d = new Disk(vec3(0.0f, 1.0f, -1.25f), vec3(0.0f, 0.0f, 1.0f), 0.25f);
d->m_mat->m_diffuse = vec3(1.0f);
vf.push_back(static_cast<Figure *>(d));
d = new Disk(vec3(0.0f, 1.0f, -0.75f), vec3(0.0f, 0.0f, -1.0f), 0.25f);
d->m_mat->m_diffuse = vec3(1.0f);
vf.push_back(static_cast<Figure *>(d));
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));
}
void scene_3(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c) {
Sphere * s;
Disk * d;
// SpotLight * l;
// DirectionalLight * l2;
vec3 eye = vec3(0.0f, 1.5f, 1.0f);
vec3 center = vec3(0.0f, 0.0f, -2.0f);
vec3 left = vec3(-1.0f, 0.0f, 0.0f);
e = new Environment("textures/pisa.hdr");
c->m_eye = eye;
c->m_look = center;
c->m_up = cross(normalize(center - eye), left);
c->translate(vec3(1.0f, 0.0f, 0.0f));
//c->roll(15.0f);
// 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_specular = vec3(0.3f);
// s->m_mat->m_shininess = 5.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(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.5f, new HeidrichSeidelAnisotropicBRDF(vec3(0.0f, 1.0f, 0.0f)));
s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
s->m_mat->m_shininess = 128.0f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-1.0f, 0.0f, -3.25f, 1.5f);
s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f);
s->m_mat->m_rho = 0.4f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(1.0f, 0.0f, -3.25f, 1.5f);
s->m_mat->m_diffuse = vec3(1.0f);
s->m_mat->m_rho = 0.4f;
vf.push_back(static_cast<Figure *>(s));
d = new Disk(vec3(1.0f, -1.5f, -3.25f), vec3(0.0f, 1.0f, 0.0f), 3.0f);
d->m_mat->m_diffuse = vec3(0.0f, 0.5f, 0.5f);
d->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(d));
// l = new SpotLight();
// l->m_position = normalize(vec3(-2.0f, 1.5f, -1.0f));
// l->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
// l->m_spot_dir = normalize(vec3(0.5f, 0.0f, -2.5f) - vec3(-2.0f, 1.5f, -1.0f));
// l->m_spot_cutoff = 89.0f;
// l->m_spot_exponent = 10.0f;
// vl.push_back(static_cast<Light *>(l));
// l2 = new DirectionalLight();
// l2->m_position = normalize(vec3(-1.0f, 0.7f, 1.0f));
// l2->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
// vl.push_back(static_cast<Light *>(l2));
// l2 = new DirectionalLight();
// l2->m_position = normalize(vec3(-0.5f, 0.7f, 1.0f));
// l2->m_diffuse = vec3(0.0f, 0.0f, 1.0f);
// l2->m_specular = vec3(0.0f, 0.0f, 1.0f);
// vl.push_back(static_cast<Light *>(l2));
// l = new DirectionalLight();
// l->m_position = normalize(vec3(1.0f, 0.0f, 1.0f));
// l->m_diffuse = vec3(0.5f);
// vl.push_back(static_cast<Light *>(l));
}
void scene_4(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c) {
Sphere * s;
Plane * p;
e = new Environment("textures/pisa.hdr");
s = new Sphere(0.0f, 0.0f, -2.0f, 1.0f);
s->m_mat->m_diffuse = vec3(1.0f);
s->m_mat->m_rho = 0.3f;
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(1.0f);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
}
#+END_SRC

View File

@@ -13,11 +13,11 @@ class Disk : public Plane {
public: public:
float m_radius; float m_radius;
Disk(BRDF * _brdf = NULL): Plane(_brdf), m_radius(1.0f) { } Disk(Material * mat = NULL): Plane(mat), m_radius(1.0f) { }
Disk(float x, float y, float z, float nx, float ny, float nz, float _r, BRDF * _brdf = NULL): Plane(x, y, z, nx, ny, nz, _brdf), m_radius(_r) { } Disk(float x, float y, float z, float nx, float ny, float nz, float _r, Material * mat = NULL): Plane(x, y, z, nx, ny, nz, mat), m_radius(_r) { }
Disk(vec3 _p, vec3 _n, float _r, BRDF * _brdf = NULL): Plane(_p, _n, _brdf), m_radius(_r) { } Disk(vec3 _p, vec3 _n, float _r, Material * mat = NULL): Plane(_p, _n, mat), m_radius(_r) { }
virtual ~Disk() { } virtual ~Disk() { }

View File

@@ -13,8 +13,8 @@ class Figure {
public: public:
Material * m_mat; Material * m_mat;
Figure(BRDF * brdf = NULL) { Figure(Material * mat = NULL) {
m_mat = new Material(brdf); m_mat = mat == NULL ? new Material() : mat;
} }
virtual ~Figure() { virtual ~Figure() {

294
main.cpp
View File

@@ -43,10 +43,10 @@ using namespace glm;
//////////////////////////////////////////// ////////////////////////////////////////////
// Function prototypes. // Function prototypes.
//////////////////////////////////////////// ////////////////////////////////////////////
static void scene_1(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c); // static void scene_1(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c);
static void scene_2(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c); // static void scene_2(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c);
static void scene_3(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c); // static void scene_3(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c);
static void scene_4(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c); // static void scene_4(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c);
static void print_usage(char ** const argv); static void print_usage(char ** const argv);
static void parse_args(int argc, char ** const argv); static void parse_args(int argc, char ** const argv);
@@ -79,8 +79,6 @@ static float g_exposure = 0.0f;
int main(int argc, char ** argv) { int main(int argc, char ** argv) {
Ray r; Ray r;
vec2 sample; vec2 sample;
vector<Figure *> figures;
vector<Light *> lights;
Tracer * tracer; Tracer * tracer;
size_t total; size_t total;
size_t current = 0; size_t current = 0;
@@ -90,8 +88,6 @@ int main(int argc, char ** argv) {
BYTE * bits; BYTE * bits;
FIRGBF *pixel; FIRGBF *pixel;
int pitch; int pitch;
Camera * cam;
Environment * env = NULL;
Scene * scn; Scene * scn;
parse_args(argc, argv); parse_args(argc, argv);
@@ -99,40 +95,39 @@ int main(int argc, char ** argv) {
// Initialize everything. // Initialize everything.
FreeImage_Initialise(); FreeImage_Initialise();
cam = new Camera();
image = new vec3*[g_h]; image = new vec3*[g_h];
for (int i = 0; i < g_h; i++) { for (int i = 0; i < g_h; i++) {
image[i] = new vec3[g_w]; image[i] = new vec3[g_w];
} }
try { try {
scn = new Scene("scenes/scene3.json"); scn = new Scene(g_input_file);
delete scn;
} catch (SceneError & e) { } catch (SceneError & e) {
cout << e.what() << endl; cout << e.what() << endl;
return EXIT_FAILURE;
} }
scene_3(figures, lights, env, cam);
// Create the tracer object.
cout << "Rendering the input file: " << ANSI_BOLD_YELLOW << g_input_file << ANSI_RESET_STYLE << endl; cout << "Rendering the input file: " << ANSI_BOLD_YELLOW << g_input_file << ANSI_RESET_STYLE << endl;
cout << "The scene contains: " << endl; cout << "The scene contains: " << endl;
cout << " " << ANSI_BOLD_YELLOW << figures.size() << ANSI_RESET_STYLE << (figures.size() != 1 ? " figures." : " figure.") << endl; cout << " " << ANSI_BOLD_YELLOW << scn->m_figures.size() << ANSI_RESET_STYLE << (scn->m_figures.size() != 1 ? " figures." : " figure.") << endl;
cout << " " << ANSI_BOLD_YELLOW << lights.size() << ANSI_RESET_STYLE << " light " << (lights.size() != 1 ? "sources." : "source.") << endl; cout << " " << ANSI_BOLD_YELLOW << scn->m_lights.size() << ANSI_RESET_STYLE << " light " << (scn->m_lights.size() != 1 ? "sources." : "source.") << endl;
cout << "Output image resolution is " << ANSI_BOLD_YELLOW << g_w << "x" << g_h << ANSI_RESET_STYLE << " pixels." << endl; cout << "Output image resolution is " << ANSI_BOLD_YELLOW << g_w << "x" << g_h << ANSI_RESET_STYLE << " pixels." << endl;
cout << "Using " << ANSI_BOLD_YELLOW << g_samples << ANSI_RESET_STYLE << " samples per pixel." << endl; cout << "Using " << ANSI_BOLD_YELLOW << g_samples << ANSI_RESET_STYLE << " samples per pixel." << endl;
cout << "Maximum ray tree depth is " << ANSI_BOLD_YELLOW << g_max_depth << ANSI_RESET_STYLE << "." << endl; cout << "Maximum ray tree depth is " << ANSI_BOLD_YELLOW << g_max_depth << ANSI_RESET_STYLE << "." << endl;
// Create the tracer object.
if (g_tracer == WHITTED) { if (g_tracer == WHITTED) {
cout << "Using " << ANSI_BOLD_YELLOW << "Whitted" << ANSI_RESET_STYLE << " ray tracing." << endl; cout << "Using " << ANSI_BOLD_YELLOW << "Whitted" << ANSI_RESET_STYLE << " ray tracing." << endl;
tracer = static_cast<Tracer *>(new WhittedTracer(g_max_depth)); tracer = static_cast<Tracer *>(new WhittedTracer(g_max_depth));
} else if(g_tracer == MONTE_CARLO) { } else if(g_tracer == MONTE_CARLO) {
cout << "Using " << ANSI_BOLD_YELLOW << "Monte Carlo" << ANSI_RESET_STYLE << " path tracing." << endl; cout << "Using " << ANSI_BOLD_YELLOW << "Monte Carlo" << ANSI_RESET_STYLE << " path tracing." << endl;
tracer = static_cast<Tracer *>(new PathTracer(g_max_depth)); tracer = static_cast<Tracer *>(new PathTracer(g_max_depth));
} else if(g_tracer == JENSEN) { } else if(g_tracer == JENSEN) {
cerr << "Photon mapping coming soon." << endl; cerr << "Photon mapping coming soon." << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} else { } else {
cerr << "Must specify a ray tracer with \"-t\"." << endl; cerr << "Must specify a ray tracer with \"-t\"." << endl;
print_usage(argv); print_usage(argv);
@@ -148,8 +143,8 @@ int main(int argc, char ** argv) {
for (int k = 0; k < g_samples; k++) { for (int k = 0; k < g_samples; k++) {
sample = sample_pixel(i, j, g_w, g_h, g_a_ratio, g_fov); sample = sample_pixel(i, j, g_w, g_h, g_a_ratio, g_fov);
r = Ray(normalize(vec3(sample, -0.5f) - vec3(0.0f)), vec3(0.0f)); r = Ray(normalize(vec3(sample, -0.5f) - vec3(0.0f)), vec3(0.0f));
cam->view_to_world(r); scn->m_cam->view_to_world(r);
image[i][j] += tracer->trace_ray(r, figures, lights, env, 0); image[i][j] += tracer->trace_ray(r, scn, 0);
#pragma omp atomic #pragma omp atomic
current++; current++;
} }
@@ -187,20 +182,8 @@ int main(int argc, char ** argv) {
if (g_out_file_name != NULL) if (g_out_file_name != NULL)
free(g_out_file_name); free(g_out_file_name);
delete cam; delete scn;
delete tracer; delete tracer;
if (env != NULL)
delete env;
for (size_t i = 0; i < figures.size(); i++) {
delete figures[i];
}
figures.clear();
for (size_t i = 0; i < lights.size(); i++) {
delete lights[i];
}
lights.clear();
for (int i = 0; i < g_h; i++) for (int i = 0; i < g_h; i++)
delete[] image[i]; delete[] image[i];
@@ -359,250 +342,3 @@ void parse_args(int argc, char ** const argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
void scene_1(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c) {
Sphere * s;
Plane * p;
Disk * d;
DirectionalLight * l;
e = new Environment(NULL, false, vec3(0.7f, 0.4f, 0.05f));
s = new Sphere(1.0f, 1.0f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 0.0f);
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-1.0f, 1.0f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(0.0f, 1.0f, 0.0f);
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(1.0f, -1.0f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(0.0f, 0.0f, 1.0f);
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-1.0f, -1.0f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f);
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 0.0f, -2.0f, 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, 0.5f, 0.4f);
vf.push_back(static_cast<Figure *>(p));
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_rho = 0.3f;
vf.push_back(static_cast<Figure *>(s));
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_rho = 0.08f;
s->m_mat->m_refract = true;
s->m_mat->m_ref_index = 1.1f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 1.5f, -2.0f, 0.5f);
s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
s->m_mat->m_rho = 0.5f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(0.0f, 0.0f, -1.0f, 0.25f);
s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
s->m_mat->m_rho = 0.1f;
vf.push_back(static_cast<Figure *>(s));
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, 0.0f, 0.0f);
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));
l = new DirectionalLight();
l->m_position = normalize(vec3(1.0f, 1.0f, 1.0f));
l->m_diffuse = vec3(0.0f, 1.0f, 1.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(1.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, 1.0f);
vl.push_back(static_cast<Light *>(l));
}
void scene_2(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c) {
Sphere * s;
Plane * p;
Disk * d;
PointLight * l;
s = new Sphere(0.2f, 0.0f, -0.75f, 0.25f);
s->m_mat->m_diffuse = vec3(1.0f);
s->m_mat->m_rho = 0.2f;
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);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
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_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
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_specular = vec3(0.0f);
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->m_mat->m_diffuse = vec3(0.0f, 1.0f, 1.0f);
p->m_mat->m_specular = vec3(0.0f);
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->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
p = new Plane(vec3(0.0f, 0.0f, 1.1f), vec3(0.0f, 0.0f, -1.0f));
p->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
s = new Sphere(-0.5f, -0.5f, -1.5f, 0.5f);
s->m_mat->m_diffuse = vec3(0.0f);
s->m_mat->m_rho = 1.0f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-0.5f, -0.5f, 0.6f, 0.5f);
s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
s->m_mat->m_refract = true;
s->m_mat->m_ref_index = 1.33f;
vf.push_back(static_cast<Figure *>(s));
d = new Disk(vec3(-0.25f, 1.0f, -1.0f), vec3(1.0f, 0.0f, 0.0f), 0.25f);
d->m_mat->m_diffuse = vec3(1.0f);
vf.push_back(static_cast<Figure *>(d));
d = new Disk(vec3(0.25f, 1.0f, -1.0f), vec3(-1.0f, 0.0f, 0.0f), 0.25f);
d->m_mat->m_diffuse = vec3(1.0f);
vf.push_back(static_cast<Figure *>(d));
d = new Disk(vec3(0.0f, 1.0f, -1.25f), vec3(0.0f, 0.0f, 1.0f), 0.25f);
d->m_mat->m_diffuse = vec3(1.0f);
vf.push_back(static_cast<Figure *>(d));
d = new Disk(vec3(0.0f, 1.0f, -0.75f), vec3(0.0f, 0.0f, -1.0f), 0.25f);
d->m_mat->m_diffuse = vec3(1.0f);
vf.push_back(static_cast<Figure *>(d));
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));
}
void scene_3(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c) {
Sphere * s;
Disk * d;
// SpotLight * l;
// DirectionalLight * l2;
vec3 eye = vec3(0.0f, 1.5f, 1.0f);
vec3 center = vec3(0.0f, 0.0f, -2.0f);
vec3 left = vec3(-1.0f, 0.0f, 0.0f);
e = new Environment("textures/pisa.hdr");
c->m_eye = eye;
c->m_look = center;
c->m_up = cross(normalize(center - eye), left);
c->translate(vec3(1.0f, 0.0f, 0.0f));
//c->roll(15.0f);
// 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_specular = vec3(0.3f);
// s->m_mat->m_shininess = 5.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(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.5f, new HeidrichSeidelAnisotropicBRDF(vec3(0.0f, 1.0f, 0.0f)));
s->m_mat->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
s->m_mat->m_shininess = 128.0f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(-1.0f, 0.0f, -3.25f, 1.5f);
s->m_mat->m_diffuse = vec3(1.0f, 0.0f, 1.0f);
s->m_mat->m_rho = 0.4f;
vf.push_back(static_cast<Figure *>(s));
s = new Sphere(1.0f, 0.0f, -3.25f, 1.5f);
s->m_mat->m_diffuse = vec3(1.0f);
s->m_mat->m_rho = 0.4f;
vf.push_back(static_cast<Figure *>(s));
d = new Disk(vec3(1.0f, -1.5f, -3.25f), vec3(0.0f, 1.0f, 0.0f), 3.0f);
d->m_mat->m_diffuse = vec3(0.0f, 0.5f, 0.5f);
d->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(d));
// l = new SpotLight();
// l->m_position = normalize(vec3(-2.0f, 1.5f, -1.0f));
// l->m_diffuse = vec3(1.0f, 1.0f, 0.0f);
// l->m_spot_dir = normalize(vec3(0.5f, 0.0f, -2.5f) - vec3(-2.0f, 1.5f, -1.0f));
// l->m_spot_cutoff = 89.0f;
// l->m_spot_exponent = 10.0f;
// vl.push_back(static_cast<Light *>(l));
// l2 = new DirectionalLight();
// l2->m_position = normalize(vec3(-1.0f, 0.7f, 1.0f));
// l2->m_diffuse = vec3(1.0f, 1.0f, 1.0f);
// vl.push_back(static_cast<Light *>(l2));
// l2 = new DirectionalLight();
// l2->m_position = normalize(vec3(-0.5f, 0.7f, 1.0f));
// l2->m_diffuse = vec3(0.0f, 0.0f, 1.0f);
// l2->m_specular = vec3(0.0f, 0.0f, 1.0f);
// vl.push_back(static_cast<Light *>(l2));
// l = new DirectionalLight();
// l->m_position = normalize(vec3(1.0f, 0.0f, 1.0f));
// l->m_diffuse = vec3(0.5f);
// vl.push_back(static_cast<Light *>(l));
}
void scene_4(vector<Figure *> & vf, vector<Light *> & vl, Environment * & e, Camera * c) {
Sphere * s;
Plane * p;
e = new Environment("textures/pisa.hdr");
s = new Sphere(0.0f, 0.0f, -2.0f, 1.0f);
s->m_mat->m_diffuse = vec3(1.0f);
s->m_mat->m_rho = 0.3f;
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(1.0f);
p->m_mat->m_specular = vec3(0.0f);
vf.push_back(static_cast<Figure *>(p));
}

View File

@@ -10,7 +10,7 @@ using namespace glm;
PathTracer::~PathTracer() { } PathTracer::~PathTracer() { }
vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> & v_lights, Environment * e, unsigned int rec_level) const { vec3 PathTracer::trace_ray(Ray & r, Scene * s, unsigned int rec_level) const {
float t, _t; float t, _t;
Figure * _f; Figure * _f;
vec3 n, color, i_pos, ref, sample, dir_diff_color, dir_spec_color, ind_color, amb_color; vec3 n, color, i_pos, ref, sample, dir_diff_color, dir_spec_color, ind_color, amb_color;
@@ -22,10 +22,10 @@ vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *
_f = NULL; _f = NULL;
// Find the closest intersecting surface. // Find the closest intersecting surface.
for (size_t f = 0; f < v_figures.size(); f++) { for (size_t f = 0; f < s->m_figures.size(); f++) {
if (v_figures[f]->intersect(r, _t) && _t < t) { if (s->m_figures[f]->intersect(r, _t) && _t < t) {
t = _t; t = _t;
_f = v_figures[f]; _f = s->m_figures[f];
} }
} }
@@ -38,22 +38,22 @@ vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *
// Check if the material is not reflective/refractive. // Check if the material is not reflective/refractive.
if (!_f->m_mat->m_refract) { if (!_f->m_mat->m_refract) {
// Calculate the direct lighting. // Calculate the direct lighting.
for (size_t l = 0; l < v_lights.size(); l++) { for (size_t l = 0; l < s->m_lights.size(); l++) {
// For every light source // For every light source
vis = true; vis = true;
// Cast a shadow ray to determine visibility. // Cast a shadow ray to determine visibility.
sr = Ray(v_lights[l]->direction(i_pos), i_pos + n * BIAS); sr = Ray(s->m_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 < s->m_figures.size(); f++) {
if (v_figures[f]->intersect(sr, _t) && _t < v_lights[l]->distance(i_pos)) { if (s->m_figures[f]->intersect(sr, _t) && _t < s->m_lights[l]->distance(i_pos)) {
vis = false; vis = false;
break; break;
} }
} }
// Evaluate the shading model accounting for visibility. // Evaluate the shading model accounting for visibility.
dir_diff_color += vis ? v_lights[l]->diffuse(n, r, i_pos, *_f->m_mat) : vec3(0.0f); dir_diff_color += vis ? s->m_lights[l]->diffuse(n, r, i_pos, *_f->m_mat) : vec3(0.0f);
dir_spec_color += vis ? v_lights[l]->specular(n, r, i_pos, *_f->m_mat) : vec3(0.0f); dir_spec_color += vis ? s->m_lights[l]->specular(n, r, i_pos, *_f->m_mat) : vec3(0.0f);
} }
// Calculate indirect lighting contribution. // Calculate indirect lighting contribution.
@@ -63,7 +63,7 @@ vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *
sample = sample_hemisphere(r1, r2); sample = sample_hemisphere(r1, r2);
rotate_sample(sample, n); rotate_sample(sample, n);
rr = Ray(normalize(sample), i_pos + (sample * BIAS)); rr = Ray(normalize(sample), i_pos + (sample * BIAS));
ind_color += r1 * trace_ray(rr, v_figures, v_lights, e, rec_level + 1) / PDF; ind_color += r1 * trace_ray(rr, s, rec_level + 1) / PDF;
} }
// Calculate environment light contribution // Calculate environment light contribution
@@ -76,14 +76,14 @@ vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *
rr = Ray(normalize(sample), i_pos + (sample * BIAS)); rr = Ray(normalize(sample), i_pos + (sample * BIAS));
// Cast a shadow ray to determine visibility. // Cast a shadow ray to determine visibility.
for (size_t f = 0; f < v_figures.size(); f++) { for (size_t f = 0; f < s->m_figures.size(); f++) {
if (v_figures[f]->intersect(rr, _t)) { if (s->m_figures[f]->intersect(rr, _t)) {
vis = false; vis = false;
break; break;
} }
} }
amb_color = vis ? e->get_color(rr) * max(dot(n, rr.m_direction), 0.0f) / PDF : vec3(0.0f); amb_color = vis ? s->m_env->get_color(rr) * max(dot(n, rr.m_direction), 0.0f) / PDF : vec3(0.0f);
// Add lighting. // Add lighting.
color += ((dir_diff_color + ind_color + amb_color) * (_f->m_mat->m_diffuse / pi<float>())) + (_f->m_mat->m_specular * dir_spec_color); color += ((dir_diff_color + ind_color + amb_color) * (_f->m_mat->m_diffuse / pi<float>())) + (_f->m_mat->m_specular * dir_spec_color);
@@ -91,7 +91,7 @@ vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *
// Determine the specular reflection color. // Determine the specular reflection color.
if (_f->m_mat->m_rho > 0.0f && rec_level < m_max_depth) { if (_f->m_mat->m_rho > 0.0f && rec_level < m_max_depth) {
rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS); rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS);
color += _f->m_mat->m_rho * trace_ray(rr, v_figures, v_lights, e, rec_level + 1); color += _f->m_mat->m_rho * trace_ray(rr, s, rec_level + 1);
} else if (_f->m_mat->m_rho > 0.0f && rec_level >= m_max_depth) } else if (_f->m_mat->m_rho > 0.0f && rec_level >= m_max_depth)
return vec3(0.0f); return vec3(0.0f);
@@ -102,14 +102,14 @@ vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *
// Determine the specular reflection color. // Determine the specular reflection color.
if (kr > 0.0f && rec_level < m_max_depth) { if (kr > 0.0f && rec_level < m_max_depth) {
rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS); rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS);
color += kr * trace_ray(rr, v_figures, v_lights, e, rec_level + 1); color += kr * trace_ray(rr, s, rec_level + 1);
} else if (rec_level >= m_max_depth) } else if (rec_level >= m_max_depth)
return vec3(0.0f); return vec3(0.0f);
// Determine the transmission color. // Determine the transmission color.
if (_f->m_mat->m_refract && kr < 1.0f && rec_level < m_max_depth) { if (_f->m_mat->m_refract && kr < 1.0f && rec_level < m_max_depth) {
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); 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 - kr) * trace_ray(rr, v_figures, v_lights, e, rec_level + 1); color += (1.0f - kr) * trace_ray(rr, s, rec_level + 1);
} else if (rec_level >= m_max_depth) } else if (rec_level >= m_max_depth)
return vec3(0.0f); return vec3(0.0f);
@@ -118,10 +118,6 @@ vec3 PathTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *
// Return final color. // Return final color.
return _f->m_mat->m_emission + color; return _f->m_mat->m_emission + color;
} else { } else
if (e != NULL) return s->m_env->get_color(r);
return e->get_color(r);
else
return vec3(0.0f);
}
} }

View File

@@ -12,7 +12,7 @@ public:
virtual ~PathTracer(); virtual ~PathTracer();
virtual vec3 trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> & v_lights, Environment * e, unsigned int rec_level) const; virtual vec3 trace_ray(Ray & r, Scene * s, unsigned int rec_level) const;
}; };
#endif #endif

View File

@@ -14,11 +14,11 @@ public:
vec3 m_point; vec3 m_point;
vec3 m_normal; vec3 m_normal;
Plane(BRDF * _brdf = NULL): Figure(_brdf), m_point(vec3(0.0f)), m_normal(vec3(0.0f, 0.0f, 1.0f)) { } Plane(Material * mat = NULL): Figure(mat), m_point(vec3(0.0f)), m_normal(vec3(0.0f, 0.0f, 1.0f)) { }
Plane(float x, float y, float z, float nx, float ny, float nz, BRDF * _brdf = NULL): Figure(_brdf), 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, Material * mat = NULL): Figure(mat), m_point(vec3(x, y, z)), m_normal(normalize(vec3(nx, ny, nz))) { }
Plane(vec3 _p, vec3 _n, BRDF * _brdf = NULL): Figure(_brdf), m_point(_p), m_normal(normalize(_n)) { } Plane(vec3 _p, vec3 _n, Material * mat = NULL): Figure(mat), m_point(_p), m_normal(normalize(_n)) { }
virtual ~Plane() { } virtual ~Plane() { }

277
scene.cpp
View File

@@ -3,12 +3,21 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <cstdlib> #include <cstdlib>
#include <cassert>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <json_spirit_reader.h> #include <json_spirit_reader.h>
#include <json_spirit_value.h>
#include "scene.hpp" #include "scene.hpp"
#include "brdf.hpp"
#include "phong_brdf.hpp"
#include "hsa_brdf.hpp"
#include "sphere.hpp"
#include "plane.hpp"
#include "disk.hpp"
#include "directional_light.hpp"
#include "point_light.hpp"
#include "spot_light.hpp"
using std::cerr; using std::cerr;
using std::endl; using std::endl;
@@ -21,7 +30,6 @@ using glm::vec3;
using glm::normalize; using glm::normalize;
using glm::cross; using glm::cross;
using json_spirit::read; using json_spirit::read;
using json_spirit::Value;
using json_spirit::Error_position; using json_spirit::Error_position;
using json_spirit::Object; using json_spirit::Object;
using json_spirit::Array; using json_spirit::Array;
@@ -46,6 +54,9 @@ static const string CAM_EYE_KEY = "eye";
static const string CAM_CNT_KEY = "look"; static const string CAM_CNT_KEY = "look";
static const string CAM_LFT_KEY = "left"; static const string CAM_LFT_KEY = "left";
static const string CAM_UPV_KEY = "up"; static const string CAM_UPV_KEY = "up";
static const string CAM_RLL_KEY = "roll";
static const string CAM_PTC_KEY = "pitch";
static const string CAM_YAW_KEY = "yaw";
static const string FIG_POS_KEY = "position"; static const string FIG_POS_KEY = "position";
static const string FIG_MAT_KEY = "material"; static const string FIG_MAT_KEY = "material";
@@ -63,9 +74,12 @@ static const string MLT_RFI_KEY = "ref_index";
static const string MLT_BRF_KEY = "transmissive"; static const string MLT_BRF_KEY = "transmissive";
static const string MLT_BRD_KEY = "brdf"; static const string MLT_BRD_KEY = "brdf";
static void read_vector(Value & val, vec3 & vec) throw(SceneError); static const string BRD_PHN_KEY = "phong";
static void read_environment(Value & v, Environment * & e) throw(SceneError); static const string BRD_HSA_KEY = "heidrich-seidel";
static void read_camera(Value & v, Camera * & c) throw(SceneError);
static const string GEO_TRN_KEY = "translation";
static const string GEO_SCL_KEY = "scaling";
static const string GEO_ROT_KEY = "rotation";
Scene::Scene(const char * file_name, int h, int w, float fov) throw(SceneError) { Scene::Scene(const char * file_name, int h, int w, float fov) throw(SceneError) {
ostringstream oss; ostringstream oss;
@@ -92,18 +106,21 @@ Scene::Scene(const char * file_name, int h, int w, float fov) throw(SceneError)
try { try {
for (Object::iterator it = top_level.begin(); it != top_level.end(); it++) { for (Object::iterator it = top_level.begin(); it != top_level.end(); it++) {
if ((*it).name_ == ENV_KEY) if ((*it).name_ == ENV_KEY)
read_environment((*it).value_, m_env); read_environment((*it).value_);
else if ((*it).name_ == CAM_KEY) else if ((*it).name_ == CAM_KEY)
read_camera((*it).value_, m_cam); read_camera((*it).value_);
else if ((*it).name_ == SPH_KEY) { else if ((*it).name_ == SPH_KEY)
m_figures.push_back(read_sphere((*it).value_));
} else if ((*it).name_ == PLN_KEY) { else if ((*it).name_ == PLN_KEY)
m_figures.push_back(read_plane((*it).value_));
} else if ((*it).name_ == DSK_KEY) { else if ((*it).name_ == DSK_KEY)
m_figures.push_back(read_disk((*it).value_));
} else if ((*it).name_ == DLT_KEY) { else if ((*it).name_ == DLT_KEY) {
} else if ((*it).name_ == PLT_KEY) { } else if ((*it).name_ == PLT_KEY) {
@@ -141,7 +158,7 @@ Scene::~Scene() {
m_lights.clear(); m_lights.clear();
} }
inline void read_vector(Value & val, vec3 & vec) throw(SceneError) { void Scene::read_vector(Value & val, vec3 & vec) throw(SceneError) {
Array a = val.get_value<Array>(); Array a = val.get_value<Array>();
if (a.size() < 3) if (a.size() < 3)
@@ -150,41 +167,46 @@ inline void read_vector(Value & val, vec3 & vec) throw(SceneError) {
vec = vec3(a[0].get_value<double>(), a[1].get_value<double>(), a[2].get_value<double>()); vec = vec3(a[0].get_value<double>(), a[1].get_value<double>(), a[2].get_value<double>());
} }
void read_environment(Value & v, Environment * & e) throw(SceneError) { void Scene::read_environment(Value & v) throw(SceneError) {
string t_name = ""; string t_name = "";
bool l_probe = false, has_tex = false, has_color = false; bool l_probe = false, has_tex = false, has_color = false;
vec3 color; vec3 color = vec3(1.0f);
Object env_obj = v.get_value<Object>(); Object env_obj = v.get_value<Object>();
for (Object::iterator it = env_obj.begin(); it != env_obj.end(); it++) { for (Object::iterator it = env_obj.begin(); it != env_obj.end(); it++) {
if ((*it).name_ == ENV_TEX_KEY) if ((*it).name_ == ENV_TEX_KEY) {
t_name = (*it).value_.get_value<string>(); t_name = (*it).value_.get_value<string>();
has_tex = true;
else if ((*it).name_ == ENV_LPB_KEY) } else if ((*it).name_ == ENV_LPB_KEY)
l_probe = (*it).value_.get_value<bool>(); l_probe = (*it).value_.get_value<bool>();
else if ((*it).name_ == ENV_COL_KEY) else if ((*it).name_ == ENV_COL_KEY) {
try { try {
read_vector((*it).value_, color); read_vector((*it).value_, color);
} catch (SceneError & e) { } catch (SceneError & e) {
throw e; throw e;
} }
has_color = true;
}
else else
cerr << "Unrecognized key \"" << (*it).name_ << "\" in input file." << endl; cerr << "Unrecognized key \"" << (*it).name_ << "\" in environment." << endl;
} }
if (!has_tex && !has_color) if (!has_tex && !has_color)
throw SceneError("Environment must specify either a texture or color."); throw SceneError("Environment must specify either a texture or color.");
e = new Environment(has_tex ? t_name.c_str() : NULL , l_probe, color); m_env = new Environment(has_tex ? t_name.c_str() : NULL , l_probe, color);
} }
void read_camera(Value & v, Camera * & c) throw(SceneError) { void Scene::read_camera(Value & v) throw(SceneError) {
bool has_up = false, has_left = false, has_eye = false, has_look = false; bool has_up = false, has_left = false, has_eye = false, has_look = false;
vec3 eye, look, left, up; vec3 eye, look, left, up, translation;
float pitch = 0.0f, yaw = 0.0f, roll = 0.0f;
Object cam_obj = v.get_value<Object>(); Object cam_obj = v.get_value<Object>();
try {
for (Object::iterator it = cam_obj.begin(); it != cam_obj.end(); it++) { for (Object::iterator it = cam_obj.begin(); it != cam_obj.end(); it++) {
if ((*it).name_ == CAM_EYE_KEY) { if ((*it).name_ == CAM_EYE_KEY) {
read_vector((*it).value_, eye); read_vector((*it).value_, eye);
@@ -202,21 +224,216 @@ void read_camera(Value & v, Camera * & c) throw(SceneError) {
read_vector((*it).value_, up); read_vector((*it).value_, up);
has_up = true; has_up = true;
} else } else if ((*it).name_ == GEO_TRN_KEY)
cerr << "Unrecognized key \"" << (*it).name_ << "\" in input file." << endl; read_vector((*it).value_, translation);
else if ((*it).name_ == CAM_RLL_KEY)
roll = static_cast<float>((*it).value_.get_value<double>());
else if ((*it).name_ == CAM_PTC_KEY)
pitch = static_cast<float>((*it).value_.get_value<double>());
else if ((*it).name_ == CAM_YAW_KEY)
yaw = static_cast<float>((*it).value_.get_value<double>());
else
cerr << "Unrecognized key \"" << (*it).name_ << "\" in camera." << endl;
}
} catch (SceneError & e) {
throw e;
} }
if (!has_eye) if (!has_eye || !has_look)
throw SceneError("Must specify an eye position for the camera."); throw SceneError("Must specify an eye and look positions for the camera.");
if (!has_look)
throw SceneError("Must specify a look position for the camera.");
if (has_up) if (has_up)
c = new Camera(eye, look, up); m_cam = new Camera(eye, look, up);
else if(!has_up && has_left) { else if(!has_up && has_left) {
up = cross(normalize(look - eye), left); up = cross(normalize(look - eye), left);
c = new Camera(eye, look, up); m_cam = new Camera(eye, look, up);
} else } else
throw SceneError("Must specify either an up or left vector for the camera."); throw SceneError("Must specify either an up or left vector for the camera.");
m_cam->pitch(pitch);
m_cam->yaw(yaw);
m_cam->roll(roll);
m_cam->translate(translation);
}
Material * Scene::read_material(Value & v) throw(SceneError) {
vec3 emission = vec3(0.0f), diffuse = vec3(1.0f), specular = vec3(1.0f);
bool transmissive = false;
float rho = 0.0f, ref_index = 1.0f, shininess = 89.0f;
Material * mat = NULL;
Object mat_obj = v.get_value<Object>();
try {
for (Object::iterator it = mat_obj.begin(); it != mat_obj.end(); it++) {
if ((*it).name_ == MLT_EMS_KEY) {
read_vector((*it).value_, emission);
} else if ((*it).name_ == MLT_DIF_KEY) {
read_vector((*it).value_, diffuse);
} else if ((*it).name_ == MLT_SPC_KEY) {
read_vector((*it).value_, specular);
} else if ((*it).name_ == MLT_RHO_KEY) {
rho = static_cast<float>((*it).value_.get_value<double>());
} else if ((*it).name_ == MLT_SHN_KEY) {
shininess = static_cast<float>((*it).value_.get_value<double>());
} else if ((*it).name_ == MLT_RFI_KEY) {
ref_index = static_cast<float>((*it).value_.get_value<double>());
} else if ((*it).name_ == MLT_BRF_KEY) {
transmissive = (*it).value_.get_value<bool>();
} else if ((*it).name_ == MLT_BRD_KEY) {
if ((*it).value_.get_value<string>() == BRD_PHN_KEY)
mat = new Material(new PhongBRDF());
else if ((*it).value_.get_value<string>() == BRD_HSA_KEY)
mat = new Material(new HeidrichSeidelAnisotropicBRDF(vec3(0.0f, 1.0f, 0.0f)));
} else
cerr << "Unrecognized key \"" << (*it).name_ << "\" in material." << endl;
}
} catch(SceneError & e) {
throw e;
}
if (mat == NULL)
mat = new Material();
mat->m_emission = emission;
mat->m_diffuse = diffuse;
mat->m_specular = specular;
mat->m_rho = rho;
mat->m_ref_index = ref_index;
mat->m_shininess = shininess;
mat->m_refract = transmissive;
return mat;
}
Figure * Scene::read_sphere(Value &v) throw(SceneError) {
bool has_position = false, has_radius = false;
vec3 position;
float radius = 1.0f;
Material * mat = NULL;
Object sph_obj = v.get_value<Object>();
try {
for (Object::iterator it = sph_obj.begin(); it != sph_obj.end(); it++) {
if ((*it).name_ == FIG_POS_KEY) {
read_vector((*it).value_, position);
has_position = true;
} else if ((*it).name_ == FIG_MAT_KEY) {
try {
mat = read_material((*it).value_);
} catch (SceneError & e) {
throw e;
}
} else if ((*it).name_ == FIG_RAD_KEY) {
radius = static_cast<float>((*it).value_.get_value<double>());
if (radius <= 0.0f)
throw SceneError("Sphere radius must be greater than 0.");
has_radius = true;
} else
cerr << "Unrecognized key \"" << (*it).name_ << "\" in sphere." << endl;
}
} catch (SceneError & e) {
throw e;
}
if (!has_position || !has_radius)
throw SceneError("Sphere must specify a position and radius.");
return static_cast<Figure *>(new Sphere(position, radius, mat));
}
Figure * Scene::read_plane(Value &v) throw(SceneError) {
bool has_position = false, has_normal = false;
vec3 position, normal = vec3(0.0f, 1.0f, 0.0f);
Material * mat = NULL;
Object pln_obj = v.get_value<Object>();
try {
for (Object::iterator it = pln_obj.begin(); it != pln_obj.end(); it++) {
if ((*it).name_ == FIG_POS_KEY || (*it).name_ == PLN_PNT_KEY) {
read_vector((*it).value_, position);
has_position = true;
} else if ((*it).name_ == FIG_MAT_KEY) {
try {
mat = read_material((*it).value_);
} catch (SceneError & e) {
throw e;
}
} else if ((*it).name_ == FIG_NOR_KEY) {
read_vector((*it).value_, normal);
has_normal = true;
} else
cerr << "Unrecognized key \"" << (*it).name_ << "\" in plane." << endl;
}
} catch (SceneError & e) {
throw e;
}
if (!has_position || !has_normal)
throw SceneError("Plane must specify a point and normal vector.");
return static_cast<Figure *>(new Plane(position, normal, mat));
}
Figure * Scene::read_disk(Value &v) throw(SceneError) {
bool has_position = false, has_normal = false, has_radius = false;
vec3 position, normal = vec3(0.0f, 1.0f, 0.0f);
float radius = 1.0f;
Material * mat = NULL;
Object dsk_obj = v.get_value<Object>();
try {
for (Object::iterator it = dsk_obj.begin(); it != dsk_obj.end(); it++) {
if ((*it).name_ == FIG_POS_KEY || (*it).name_ == PLN_PNT_KEY) {
read_vector((*it).value_, position);
has_position = true;
} else if ((*it).name_ == FIG_MAT_KEY) {
try {
mat = read_material((*it).value_);
} catch (SceneError & e) {
throw e;
}
} else if ((*it).name_ == FIG_NOR_KEY) {
read_vector((*it).value_, normal);
has_normal = true;
} else if ((*it).name_ == FIG_RAD_KEY) {
radius = static_cast<float>((*it).value_.get_value<double>());
if (radius <= 0.0f)
throw SceneError("Disk radius must be greater than 0.");
has_radius = true;
} else
cerr << "Unrecognized key \"" << (*it).name_ << "\" in disk." << endl;
}
} catch (SceneError & e) {
throw e;
}
if (!has_position || !has_normal || !has_radius)
throw SceneError("Disk must specify a point, a normal vector and a radius.");
return static_cast<Figure *>(new Disk(position, normal, radius, mat));
} }

View File

@@ -6,14 +6,18 @@
#include <vector> #include <vector>
#include <stdexcept> #include <stdexcept>
#include <json_spirit_value.h>
#include "camera.hpp" #include "camera.hpp"
#include "figure.hpp" #include "figure.hpp"
#include "light.hpp" #include "light.hpp"
#include "material.hpp"
#include "environment.hpp" #include "environment.hpp"
using std::string; using std::string;
using std::vector; using std::vector;
using std::runtime_error; using std::runtime_error;
using json_spirit::Value;
class SceneError: public runtime_error { class SceneError: public runtime_error {
public: public:
@@ -29,6 +33,15 @@ public:
Scene(const char * file_name, int h = 480, int w = 640, float fov = 90.0f) throw(SceneError); Scene(const char * file_name, int h = 480, int w = 640, float fov = 90.0f) throw(SceneError);
~Scene(); ~Scene();
private:
void read_vector(Value & val, vec3 & vec) throw(SceneError);
void read_environment(Value & v) throw(SceneError);
void read_camera(Value & v) throw(SceneError);
Material * read_material(Value & v) throw(SceneError);
Figure * read_sphere(Value &v) throw(SceneError);
Figure * read_plane(Value &v) throw(SceneError);
Figure * read_disk(Value &v) throw(SceneError);
}; };
#endif #endif

View File

@@ -7,15 +7,17 @@
"camera": { "camera": {
"eye": [0.0, 1.5, 1.0], "eye": [0.0, 1.5, 1.0],
"look": [0.0, 0.0, -2.0], "look": [0.0, 0.0, -2.0],
"left": [-1.0, 0.0, 0.0] "left": [-1.0, 0.0, 0.0],
"translation": [1.0, 0.0, 0.0]
}, },
"sphere": { "sphere": {
"position": [2.0, 0.0, -2.0], "position": [2.0, 0.0, -2.0],
"radius": 1.5, "radius": 1.5,
"material": { "material": {
"diffuse": [1.0f, 0.0f, 1.0f], "diffuse": [1.0, 1.0, 0.0],
"shininess": 128.0 "shininess": 128.0,
"brdf": "heidrich-seidel"
} }
}, },

View File

@@ -13,11 +13,11 @@ public:
vec3 m_center; vec3 m_center;
float m_radius; float m_radius;
Sphere(BRDF * _brdf = NULL): Figure(_brdf), m_center(vec3(0.0f)), m_radius(0.5f) { } Sphere(Material * mat = NULL): Figure(mat), m_center(vec3(0.0f)), m_radius(0.5f) { }
Sphere(float x, float y, float z, float r, BRDF * _brdf = NULL): Figure(_brdf), m_center(vec3(x, y, z)), m_radius(r) { } Sphere(float x, float y, float z, float r, Material * mat = NULL): Figure(mat), m_center(vec3(x, y, z)), m_radius(r) { }
Sphere(vec3 _c, float r, BRDF * _brdf = NULL): Figure(_brdf), m_center(_c), m_radius(r) { } Sphere(vec3 _c, float r, Material * mat = NULL): Figure(mat), m_center(_c), m_radius(r) { }
virtual ~Sphere() { } virtual ~Sphere() { }

View File

@@ -6,10 +6,8 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "figure.hpp"
#include "light.hpp"
#include "environment.hpp"
#include "ray.hpp" #include "ray.hpp"
#include "scene.hpp"
using std::vector; using std::vector;
using glm::vec2; using glm::vec2;
@@ -29,7 +27,7 @@ public:
virtual ~Tracer() { } virtual ~Tracer() { }
virtual vec3 trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> & v_lights, Environment * e, unsigned int rec_level) const = 0; virtual vec3 trace_ray(Ray & r, Scene * s, unsigned int rec_level) const = 0;
protected: protected:
float fresnel(const vec3 & i, const vec3 & n, const float ir1, const float ir2) const; float fresnel(const vec3 & i, const vec3 & n, const float ir1, const float ir2) const;

View File

@@ -9,7 +9,7 @@ using namespace glm;
WhittedTracer::~WhittedTracer() { } WhittedTracer::~WhittedTracer() { }
vec3 WhittedTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> & v_lights, Environment * e, unsigned int rec_level) const { vec3 WhittedTracer::trace_ray(Ray & r, Scene * s, unsigned int rec_level) const {
float t, _t; float t, _t;
Figure * _f; Figure * _f;
vec3 n, color, i_pos, ref, dir_diff_color, dir_spec_color; vec3 n, color, i_pos, ref, dir_diff_color, dir_spec_color;
@@ -21,10 +21,10 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Ligh
_f = NULL; _f = NULL;
// Find the closest intersecting surface. // Find the closest intersecting surface.
for (size_t f = 0; f < v_figures.size(); f++) { for (size_t f = 0; f < s->m_figures.size(); f++) {
if (v_figures[f]->intersect(r, _t) && _t < t) { if (s->m_figures[f]->intersect(r, _t) && _t < t) {
t = _t; t = _t;
_f = v_figures[f]; _f = s->m_figures[f];
} }
} }
@@ -37,22 +37,22 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Ligh
// Check if the material is not reflective/refractive. // Check if the material is not reflective/refractive.
if (!_f->m_mat->m_refract) { if (!_f->m_mat->m_refract) {
// Calculate the direct lighting. // Calculate the direct lighting.
for (size_t l = 0; l < v_lights.size(); l++) { for (size_t l = 0; l < s->m_lights.size(); l++) {
// For every light source // For every light source
vis = true; vis = true;
// Cast a shadow ray to determine visibility. // Cast a shadow ray to determine visibility.
sr = Ray(v_lights[l]->direction(i_pos), i_pos + n * BIAS); sr = Ray(s->m_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 < s->m_figures.size(); f++) {
if (v_figures[f]->intersect(sr, _t) && _t < v_lights[l]->distance(i_pos)) { if (s->m_figures[f]->intersect(sr, _t) && _t < s->m_lights[l]->distance(i_pos)) {
vis = false; vis = false;
break; break;
} }
} }
// Evaluate the shading model accounting for visibility. // Evaluate the shading model accounting for visibility.
dir_diff_color += vis ? v_lights[l]->diffuse(n, r, i_pos, *_f->m_mat) : vec3(0.0f); dir_diff_color += vis ? s->m_lights[l]->diffuse(n, r, i_pos, *_f->m_mat) : vec3(0.0f);
dir_spec_color += vis ? v_lights[l]->specular(n, r, i_pos, *_f->m_mat) : vec3(0.0f); dir_spec_color += vis ? s->m_lights[l]->specular(n, r, i_pos, *_f->m_mat) : vec3(0.0f);
} }
color += (dir_diff_color * (_f->m_mat->m_diffuse / pi<float>())) + (_f->m_mat->m_specular * dir_spec_color); color += (dir_diff_color * (_f->m_mat->m_diffuse / pi<float>())) + (_f->m_mat->m_specular * dir_spec_color);
@@ -60,7 +60,7 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Ligh
// Determine the specular reflection color. // Determine the specular reflection color.
if (_f->m_mat->m_rho > 0.0f && rec_level < m_max_depth) { if (_f->m_mat->m_rho > 0.0f && rec_level < m_max_depth) {
rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS); rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS);
color += _f->m_mat->m_rho * trace_ray(rr, v_figures, v_lights, e, rec_level + 1); color += _f->m_mat->m_rho * trace_ray(rr, s, rec_level + 1);
} else if (_f->m_mat->m_rho > 0.0f && rec_level >= m_max_depth) } else if (_f->m_mat->m_rho > 0.0f && rec_level >= m_max_depth)
return vec3(0.0f); return vec3(0.0f);
@@ -71,14 +71,14 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Ligh
// Determine the specular reflection color. // Determine the specular reflection color.
if (kr > 0.0f && rec_level < m_max_depth) { if (kr > 0.0f && rec_level < m_max_depth) {
rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS); rr = Ray(normalize(reflect(r.m_direction, n)), i_pos + n * BIAS);
color += kr * trace_ray(rr, v_figures, v_lights, e, rec_level + 1); color += kr * trace_ray(rr, s, rec_level + 1);
} else if (rec_level >= m_max_depth) } else if (rec_level >= m_max_depth)
return vec3(0.0f); return vec3(0.0f);
// Determine the transmission color. // Determine the transmission color.
if (_f->m_mat->m_refract && kr < 1.0f && rec_level < m_max_depth) { if (_f->m_mat->m_refract && kr < 1.0f && rec_level < m_max_depth) {
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); 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 - kr) * trace_ray(rr, v_figures, v_lights, e, rec_level + 1); color += (1.0f - kr) * trace_ray(rr, s, rec_level + 1);
} else if (rec_level >= m_max_depth) } else if (rec_level >= m_max_depth)
return vec3(0.0f); return vec3(0.0f);
@@ -87,10 +87,6 @@ vec3 WhittedTracer::trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Ligh
// Return final color. // Return final color.
return _f->m_mat->m_emission + color; return _f->m_mat->m_emission + color;
} else { } else
if (e != NULL) return s->m_env->get_color(r);
return e->get_color(r);
else
return vec3(0.0f);
}
} }

View File

@@ -12,7 +12,7 @@ public:
virtual ~WhittedTracer(); virtual ~WhittedTracer();
virtual vec3 trace_ray(Ray & r, vector<Figure *> & v_figures, vector<Light *> & v_lights, Environment * e, unsigned int rec_level) const; virtual vec3 trace_ray(Ray & r, Scene * s, unsigned int rec_level) const;
}; };
#endif #endif