From eb9f107feb779e0098e6763bef9023d4730f13f3 Mon Sep 17 00:00:00 2001 From: Miguel Angel Astor Romero Date: Fri, 3 Mar 2017 14:24:05 -0400 Subject: [PATCH] Some photon testing with the book. --- kd_tree.cpp | 42 +++++++++++++++++++++++++----------------- kd_tree.hpp | 4 +++- photon_tracer.cpp | 27 +++++++++++++++------------ rgbe.cpp | 2 +- rgbe.hpp | 2 +- sampling.cpp | 16 ++++++++++++++-- scenes/scene7.json | 2 +- 7 files changed, 60 insertions(+), 35 deletions(-) diff --git a/kd_tree.cpp b/kd_tree.cpp index e733d14..23121a5 100644 --- a/kd_tree.cpp +++ b/kd_tree.cpp @@ -1,18 +1,14 @@ #include -#ifndef NDEBUG #include -#endif #include #include +#include #include "kd_tree.hpp" -#ifndef NDEBUG using std::ofstream; using std::ios; -#endif - using std::cout; using std::endl; @@ -334,21 +330,10 @@ bool kdTree::buildKdTree() } cout << "Adding photons to the tree." << endl; - createNodeKdTree(&root, Photons , xyz, yzx, zxy, XYZ, 0, size, xyz_aux, yzx_aux, zxy_aux); + //createNodeKdTree(&root, Photons , xyz, yzx, zxy, XYZ, 0, size, xyz_aux, yzx_aux, zxy_aux); //printTree(); -#ifndef NDEBUG - cout << "Writing photons to \x1b[1;33mphotons.txt\x1b[m" << endl; - ofstream ofs("photons.txt", ios::out); - float r, g, b; - for (std::vector::iterator it = Photons.begin(); it != Photons.end(); it++) { - rgbe2float(r, g, b, (*it).radiance); - ofs << (*it).position.x << " " << (*it).position.y << " " << (*it).position.z << " " << r << " " << g << " " << b << endl; - } - ofs.close(); -#endif - // delete[] xyz; // delete[] yzx; // delete[] zxy; @@ -414,3 +399,26 @@ void kdTree::findInRange (Vec3 min, Vec3 max, std::vector &photons, tree size_t kdTree::getNumPhotons() { return Photons.size(); } + +void kdTree::save_photon_list() const { + cout << "Writing photons to \x1b[1;33mphotons.txt\x1b[m" << endl; + ofstream ofs("photons.txt", ios::out); + float r, g, b; + for (std::vector::const_iterator it = Photons.begin(); it != Photons.end(); it++) { + rgbe2float(r, g, b, (*it).radiance); + ofs << (*it).position.x << " " << (*it).position.y << " " << (*it).position.z << " " << r << " " << g << " " << b << endl; + } + ofs.close(); +} + +void kdTree::find_by_distance(std::vector & found, const glm::vec3 & point, const glm::vec3 & normal, const float distance, const unsigned int max) const { + glm::vec3 p_pos; + found.clear(); + for (std::vector::const_iterator it = Photons.begin(); it != Photons.end(); it++) { + p_pos = glm::vec3((*it).position.x, (*it).position.y, (*it).position.z); + if (glm::distance(p_pos, point) < distance && glm::dot(glm::normalize(p_pos - point), normal) < glm::pi() / 2.0f) + found.push_back((*it)); + if (found.size() >= max) + break; + } +} diff --git a/kd_tree.hpp b/kd_tree.hpp index d75fc14..7a15579 100644 --- a/kd_tree.hpp +++ b/kd_tree.hpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "rgbe.hpp" @@ -153,7 +154,8 @@ public: bool buildKdTree(); void printTree(); std::vector findInRange (Vec3 min, Vec3 max) const; - + void find_by_distance(std::vector & found, const glm::vec3 & point, const glm::vec3 & normal, const float distance, const unsigned int max) const; + void save_photon_list() const; size_t getNumPhotons(); private: diff --git a/photon_tracer.cpp b/photon_tracer.cpp index 69bf75d..9072bec 100644 --- a/photon_tracer.cpp +++ b/photon_tracer.cpp @@ -101,23 +101,25 @@ vec3 PhotonTracer::trace_ray(Ray & r, Scene * s, unsigned int rec_level) const { } // TODO: Change photon map search method for hemisphere search. - radius = m_h_radius; - mn = Vec3(i_pos.x - radius, i_pos.y - radius, i_pos.z - radius); - mx = Vec3(i_pos.x + radius, i_pos.y + radius, i_pos.z + radius); + // radius = m_h_radius; + // mn = Vec3(i_pos.x - radius, i_pos.y - radius, i_pos.z - radius); + // mx = Vec3(i_pos.x + radius, i_pos.y + radius, i_pos.z + radius); - while((photons = m_photon_map.findInRange(mn, mx)).size() == 0 && radius < 5.0) { - radius *= 2; - mn = Vec3(i_pos.x - radius, i_pos.y - radius, i_pos.z - radius); - mx = Vec3(i_pos.x + radius, i_pos.y + radius, i_pos.z + radius); - } + // while((photons = m_photon_map.findInRange(mn, mx)).size() == 0 && radius < 5.0) { + // radius *= 2; + // mn = Vec3(i_pos.x - radius, i_pos.y - radius, i_pos.z - radius); + // mx = Vec3(i_pos.x + radius, i_pos.y + radius, i_pos.z + radius); + // } + m_photon_map.find_by_distance(photons, i_pos, n, m_h_radius, 1000); for (vector::iterator it = photons.begin(); it != photons.end(); it++) { (*it).getColor(red, green, blue); - p_contrib += ((_f->m_mat->m_diffuse / pi()) * vec3(red, green, blue)) / (pi() * (radius * radius)); + p_contrib += (_f->m_mat->m_diffuse / pi()) * vec3(red, green, blue); } - - color += (1.0f - _f->m_mat->m_rho) * (((dir_diff_color) * (_f->m_mat->m_diffuse / pi())) + - (_f->m_mat->m_specular * dir_spec_color) + p_contrib); + p_contrib /= (1.0f / pi()) / (m_h_radius * m_h_radius); + // color += (1.0f - _f->m_mat->m_rho) * (((dir_diff_color) * (_f->m_mat->m_diffuse / pi())) + + // (_f->m_mat->m_specular * dir_spec_color) + p_contrib); + color += p_contrib; // Determine the specular reflection color. if (_f->m_mat->m_rho > 0.0f && rec_level < m_max_depth) { @@ -213,6 +215,7 @@ void PhotonTracer::build_photon_map(Scene * s, const size_t n_photons_per_ligth, cout << endl; cout << "Generated " << ANSI_BOLD_YELLOW << m_photon_map.getNumPhotons() << ANSI_RESET_STYLE << " total photons." << endl; + m_photon_map.save_photon_list(); cout << "Building photon map Kd-tree." << endl; m_photon_map.buildKdTree(); } diff --git a/rgbe.cpp b/rgbe.cpp index 538c2cb..f4bb07b 100644 --- a/rgbe.cpp +++ b/rgbe.cpp @@ -48,7 +48,7 @@ void float2rgbe(unsigned char rgbe[4], float red, float green, float blue) { /* standard conversion from rgbe to float pixels */ /* note: Ward uses ldexp(col+0.5,exp-(128+8)). However we wanted pixels */ /* in the range [0,1] to map back into the range [0,1]. */ -void rgbe2float(float & red, float & green, float & blue, unsigned char rgbe[4]) { +void rgbe2float(float & red, float & green, float & blue, const unsigned char rgbe[4]) { float f; if (rgbe[3]) { /*nonzero pixel*/ diff --git a/rgbe.hpp b/rgbe.hpp index 5262b20..93f330e 100644 --- a/rgbe.hpp +++ b/rgbe.hpp @@ -22,6 +22,6 @@ #define RGBE_HPP extern void float2rgbe(unsigned char rgbe[4], float red, float green, float blue); -extern void rgbe2float(float & red, float & green, float & blue, unsigned char rgbe[4]); +extern void rgbe2float(float & red, float & green, float & blue, const unsigned char rgbe[4]); #endif diff --git a/sampling.cpp b/sampling.cpp index b698569..2be6a39 100644 --- a/sampling.cpp +++ b/sampling.cpp @@ -1,10 +1,15 @@ -#include +#include +#include +#include #include #include #include "sampling.hpp" +using std::uniform_real_distribution; +using std::mt19937; +using std::bind; using glm::mat3; using glm::abs; using glm::normalize; @@ -14,8 +19,15 @@ using glm::pi; const float PDF = (1.0f / (2.0f * pi())); +static bool seeded = false; +static uniform_real_distribution dist(0, 1); +static mt19937 engine; +static auto generator = bind(dist, engine); + float random01() { - return static_cast(rand() % 1024) / 1025.0f; + if (!seeded) + engine.seed(std::chrono::system_clock::now().time_since_epoch().count()); + return generator(); } vec2 sample_pixel(int i, int j, float w, float h, float a_ratio, float fov) { diff --git a/scenes/scene7.json b/scenes/scene7.json index 79bf593..97132c1 100644 --- a/scenes/scene7.json +++ b/scenes/scene7.json @@ -6,7 +6,7 @@ }, "sphere_area_light": { - "position": [0.0, 1.0, -1.0], + "position": [0.0, 0.7, -1.0], "radius": 0.15, "material": { "emission": [1.0, 1.0, 1.0]