Photon tracing fixed.

This commit is contained in:
2017-03-27 13:48:03 -04:00
parent ab9a160cf4
commit a9da863274
4 changed files with 160 additions and 43 deletions

View File

@@ -63,6 +63,7 @@ static float g_gamma = 2.2f;
static float g_exposure = 0.0f; static float g_exposure = 0.0f;
static size_t g_photons = 15000; static size_t g_photons = 15000;
static float g_p_sample_radius = 0.01f; static float g_p_sample_radius = 0.01f;
static float g_cone_filter_k = 1.0f;
//////////////////////////////////////////// ////////////////////////////////////////////
// Main function. // Main function.
@@ -113,7 +114,7 @@ int main(int argc, char ** argv) {
} else if(g_tracer == JENSEN) { } else if(g_tracer == JENSEN) {
cout << "Using " << ANSI_BOLD_YELLOW << "Jensen's photon mapping" << ANSI_RESET_STYLE << " with ray tracing." << endl; cout << "Using " << ANSI_BOLD_YELLOW << "Jensen's photon mapping" << ANSI_RESET_STYLE << " with ray tracing." << endl;
p_tracer = new PhotonTracer(g_max_depth, g_p_sample_radius); p_tracer = new PhotonTracer(g_max_depth, g_p_sample_radius, g_cone_filter_k);
if (g_photons_file == NULL && g_caustics_file == NULL) { if (g_photons_file == NULL && g_caustics_file == NULL) {
cout << "Building global photon map with " << ANSI_BOLD_YELLOW << g_photons / 2 << ANSI_RESET_STYLE << " primary photons per light source." << endl; cout << "Building global photon map with " << ANSI_BOLD_YELLOW << g_photons / 2 << ANSI_RESET_STYLE << " primary photons per light source." << endl;
p_tracer->photon_tracing(scn, g_photons / 2); p_tracer->photon_tracing(scn, g_photons / 2);
@@ -246,10 +247,12 @@ void print_usage(char ** const argv) {
cerr << " -p\tNumber of primary photons per light source." << endl; cerr << " -p\tNumber of primary photons per light source." << endl;
cerr << " \tDefaults to 15000." << endl; cerr << " \tDefaults to 15000." << endl;
cerr << " -h\tHemisphere radius for photon map sampling (> 0)." << endl; cerr << " -h\tHemisphere radius for photon map sampling (> 0)." << endl;
cerr << " \tDefaults to 0.01f ." << endl; cerr << " \tDefaults to 0.01f." << endl;
cerr << " -k\tFile with photon definitions." << endl; cerr << " -k\tFile with photon definitions." << endl;
cerr << " \tSkips the photon tracing step using" << endl; cerr << " \tSkips the photon tracing step using" << endl;
cerr << " \tthe photons defined in the specified file." << endl; cerr << " \tthe photons defined in the specified file." << endl;
cerr << " -l\tCone filter constant." << endl;
cerr << " \tDefaults to 1.0f." << endl;
} }
void parse_args(int argc, char ** const argv) { void parse_args(int argc, char ** const argv) {
@@ -263,7 +266,7 @@ void parse_args(int argc, char ** const argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
while((opt = getopt(argc, argv, "-:t:s:w:f:o:r:g:e:p:h:k:c:")) != -1) { while((opt = getopt(argc, argv, "-:t:s:w:f:o:r:g:e:p:h:k:c:l:")) != -1) {
switch (opt) { switch (opt) {
case 1: case 1:
g_input_file = (char *)malloc((strlen(optarg) + 1) * sizeof(char)); g_input_file = (char *)malloc((strlen(optarg) + 1) * sizeof(char));
@@ -385,6 +388,15 @@ void parse_args(int argc, char ** const argv) {
strcpy(g_caustics_file, optarg); strcpy(g_caustics_file, optarg);
break; break;
case 'l':
g_cone_filter_k = atof(optarg);
if (g_cone_filter_k <= 0.0f) {
cerr << "Cone filter constant must be greater than or equal to 1.0" << endl;
print_usage(argv);
exit(EXIT_FAILURE);
}
break;
case ':': case ':':
cerr << "Option \"-" << static_cast<char>(optopt) << "\" requires an argument." << endl; cerr << "Option \"-" << static_cast<char>(optopt) << "\" requires an argument." << endl;
print_usage(argv); print_usage(argv);

View File

@@ -32,7 +32,7 @@ using namespace glm;
PhotonTracer::~PhotonTracer() { } PhotonTracer::~PhotonTracer() { }
vec3 PhotonTracer::trace_ray(Ray & r, Scene * s, unsigned int rec_level) const { vec3 PhotonTracer::trace_ray(Ray & r, Scene * s, unsigned int rec_level) const {
float t, _t, radius, red, green, blue, kr, w; float t, _t, red, green, blue, kr, radius;
Figure * _f; Figure * _f;
vec3 n, color, i_pos, ref, dir_diff_color, dir_spec_color, p_contrib; vec3 n, color, i_pos, ref, dir_diff_color, dir_spec_color, p_contrib;
Ray mv_r, sr, rr; Ray mv_r, sr, rr;
@@ -120,28 +120,31 @@ vec3 PhotonTracer::trace_ray(Ray & r, Scene * s, unsigned int rec_level) const {
// mn = Vec3(i_pos.x - radius, i_pos.y - radius, i_pos.z - 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); // mx = Vec3(i_pos.x + radius, i_pos.y + radius, i_pos.z + radius);
// } // }
radius = m_h_radius;
m_photon_map.find_by_distance(photons, i_pos, n, m_h_radius, 1000); m_photon_map.find_by_distance(photons, i_pos, n, m_h_radius, 1000);
while(photons.size() == 0 && radius < 5.0) {
radius *= 2;
m_photon_map.find_by_distance(photons, i_pos, n, m_h_radius, 1000);
}
radius = m_h_radius;
m_caustics_map.find_by_distance(caustics, i_pos, n, m_h_radius, 1000); m_caustics_map.find_by_distance(caustics, i_pos, n, m_h_radius, 1000);
while(caustics.size() == 0 && radius < 5.0) {
radius *= 2;
m_caustics_map.find_by_distance(caustics, i_pos, n, m_h_radius, 1000);
}
photons.insert(photons.end(), caustics.begin(), caustics.end()); photons.insert(photons.end(), caustics.begin(), caustics.end());
for (Photon p : photons) { for (Photon p : photons) {
w = max(0.0f, -dot(n, -p.direction.toVec3()));
w *= (1.0f - m_h_radius) / 25.0f;
p.getColor(red, green, blue); p.getColor(red, green, blue);
p_contrib += vec3(red, green, blue) * w; p_contrib += vec3(red, green, blue);
} }
// for (Photon p : photons) { p_contrib /= (1.0f - (2.0f / (3.0f * m_cone_filter_k))) * pi<float>() * (radius * radius);
// p.getColor(red, green, blue);
// p_contrib += vec3(red, green, blue); // color += (1.0f - _f->m_mat->m_rho) * ((dir_diff_color * (_f->m_mat->m_diffuse / pi<float>())) +
// } // (_f->m_mat->m_specular * dir_spec_color) + p_contrib);
// for (Photon p : caustics) {
// p.getColor(red, green, blue);
// p_contrib += vec3(red, green, blue);
// }
// p_contrib *= (1.0f / pi<float>()) / (m_h_radius * m_h_radius);
// color += (1.0f - _f->m_mat->m_rho) * (((dir_diff_color + p_contrib) * (_f->m_mat->m_diffuse / pi<float>())) +
// (_f->m_mat->m_specular * dir_spec_color));
color += (1.0f - _f->m_mat->m_rho) * p_contrib; color += (1.0f - _f->m_mat->m_rho) * p_contrib;
// Determine the specular reflection color. // Determine the specular reflection color.
@@ -337,7 +340,10 @@ void PhotonTracer::trace_photon(Photon & ph, Scene * s, const unsigned int rec_l
if (!_f->m_mat->m_refract){ if (!_f->m_mat->m_refract){
#pragma omp critical #pragma omp critical
{ {
m_photon_map.addPhoton(ph); p_pos = Vec3(i_pos.x, i_pos.y, i_pos.z);
p_dir = Vec3(-ph.direction.x, -ph.direction.y, -ph.direction.z);
photon = Photon(p_pos, p_dir, red, green, blue, ph.ref_index);
m_photon_map.addPhoton(photon);
} }
r1 = random01(); r1 = random01();
@@ -351,16 +357,16 @@ void PhotonTracer::trace_photon(Photon & ph, Scene * s, const unsigned int rec_l
photon = Photon(p_pos, p_dir, color.r, color.g, color.b, ph.ref_index); photon = Photon(p_pos, p_dir, color.r, color.g, color.b, ph.ref_index);
if (rec_level < m_max_depth) if (rec_level < m_max_depth)
trace_photon(photon, s, rec_level + 1); trace_photon(photon, s, rec_level + 1);
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) {
color = (_f->m_mat->m_rho) * vec3(red, green, blue); color = (_f->m_mat->m_rho) * vec3(red, green, blue);
i_pos += n * BIAS; i_pos += n * BIAS;
p_pos = Vec3(i_pos.x, i_pos.y, i_pos.z); p_pos = Vec3(i_pos.x, i_pos.y, i_pos.z);
ph_dir = normalize(reflect(vec3(ph.direction.x, ph.direction.y, ph.direction.z), n)); ph_dir = normalize(reflect(vec3(ph.direction.x, ph.direction.y, ph.direction.z), n));
p_dir = Vec3(ph_dir.x, ph_dir.y, ph_dir.z); p_dir = Vec3(ph_dir.x, ph_dir.y, ph_dir.z);
photon = Photon(p_pos, p_dir, color.r, color.g, color.b, ph.ref_index); photon = Photon(p_pos, p_dir, color.r, color.g, color.b, ph.ref_index);
trace_photon(photon, s, rec_level + 1); trace_photon(photon, s, rec_level + 1);
} }
} else if (_f->m_mat->m_refract && rec_level < m_max_depth) { } else if (_f->m_mat->m_refract && rec_level < m_max_depth) {
@@ -370,24 +376,24 @@ void PhotonTracer::trace_photon(Photon & ph, Scene * s, const unsigned int rec_l
// Trace the reflected photon. // Trace the reflected photon.
if (kr > 0.0f) { if (kr > 0.0f) {
color = kr * vec3(red, green, blue); color = kr * vec3(red, green, blue);
i_pos += n * BIAS; i_pos += n * BIAS;
p_pos = Vec3(i_pos.x, i_pos.y, i_pos.z); p_pos = Vec3(i_pos.x, i_pos.y, i_pos.z);
ph_dir = normalize(reflect(vec3(ph.direction.x, ph.direction.y, ph.direction.z), n)); ph_dir = normalize(reflect(vec3(ph.direction.x, ph.direction.y, ph.direction.z), n));
p_dir = Vec3(ph_dir.x, ph_dir.y, ph_dir.z); p_dir = Vec3(ph_dir.x, ph_dir.y, ph_dir.z);
photon = Photon(p_pos, p_dir, color.r, color.g, color.b, ph.ref_index); photon = Photon(p_pos, p_dir, color.r, color.g, color.b, ph.ref_index);
trace_photon(photon, s, rec_level + 1); trace_photon(photon, s, rec_level + 1);
} }
// Trace the transmitted photon. // Trace the transmitted photon.
if (kr < 1.0f) { if (kr < 1.0f) {
color = (1.0f - kr) * vec3(red, green, blue); color = (1.0f - kr) * vec3(red, green, blue);
i_pos -= n * (2 * BIAS); i_pos -= n * (2 * BIAS);
p_pos = Vec3(i_pos.x, i_pos.y, i_pos.z); p_pos = Vec3(i_pos.x, i_pos.y, i_pos.z);
ph_dir = normalize(refract(vec3(ph.direction.x, ph.direction.y, ph.direction.z), n, ph.ref_index / _f->m_mat->m_ref_index)); ph_dir = normalize(refract(vec3(ph.direction.x, ph.direction.y, ph.direction.z), n, ph.ref_index / _f->m_mat->m_ref_index));
p_dir = Vec3(ph_dir.x, ph_dir.y, ph_dir.z); p_dir = Vec3(ph_dir.x, ph_dir.y, ph_dir.z);
photon = Photon(p_pos, p_dir, color.r, color.g, color.b, _f->m_mat->m_ref_index); photon = Photon(p_pos, p_dir, color.r, color.g, color.b, _f->m_mat->m_ref_index);
trace_photon(photon, s, rec_level + 1); trace_photon(photon, s, rec_level + 1);
} }
} }
} }

View File

@@ -7,8 +7,8 @@
class PhotonTracer: public Tracer { class PhotonTracer: public Tracer {
public: public:
PhotonTracer(): Tracer(), m_h_radius(0.5f) { } PhotonTracer(): Tracer(), m_h_radius(0.5f), m_cone_filter_k(1.0f) { }
PhotonTracer(unsigned int max_depth, float _r = 0.5f): Tracer(max_depth), m_h_radius(_r) { }; PhotonTracer(unsigned int max_depth, float _r = 0.5f, float _k = 1.0f): Tracer(max_depth), m_h_radius(_r), m_cone_filter_k(_k < 1.0f ? 1.0f : _k) { };
virtual ~PhotonTracer(); virtual ~PhotonTracer();
virtual vec3 trace_ray(Ray & r, Scene * s, unsigned int rec_level) const; virtual vec3 trace_ray(Ray & r, Scene * s, unsigned int rec_level) const;
@@ -18,6 +18,7 @@ public:
void build_photon_map(const bool caustics = false); void build_photon_map(const bool caustics = false);
private: private:
float m_h_radius; float m_h_radius;
float m_cone_filter_k;
kdTree m_photon_map; kdTree m_photon_map;
kdTree m_caustics_map; kdTree m_caustics_map;
void trace_photon(Photon & ph, Scene * s, const unsigned int rec_level); void trace_photon(Photon & ph, Scene * s, const unsigned int rec_level);

98
scenes/scene10.json Normal file
View File

@@ -0,0 +1,98 @@
{
"camera": {
"eye": [0.0, 0.0, 1.0],
"look": [0.0, 0.0, -1.0],
"left": [-1.0, 0.0, 0.0]
},
"point_light": {
"position": [0.0, 0.9, -1.0]
},
"sphere": {
"position": [-0.4, -0.75, -0.65],
"radius": 0.25,
"material": {
"diffuse": [1.0, 1.0, 1.0],
"rho": 0.4
}
},
"sphere": {
"position": [-0.75, -0.5, -1.5],
"radius": 0.5,
"material": {
"diffuse": [0.0, 0.0, 0.0],
"rho": 1.0
}
},
"sphere": {
"position": [1.0, -0.5, -1.1],
"radius": 0.5,
"material": {
"diffuse": [1.0, 1.0, 0.0],
"transmissive": true,
"ref_index": 1.33
}
},
"plane": {
"position": [0.0, -1.0, 0.0],
"normal": [0.0, 1.0, 0.0],
"material": {
"diffuse": [1.0, 1.0, 1.0],
"specular": [0.0, 0.0, 0.0],
"transmissive": true
}
},
"plane": {
"position": [-2.0, 0.0, 0.0],
"normal": [1.0, 0.0, 0.0],
"material": {
"diffuse": [1.0, 0.0, 0.0],
"specular": [0.0, 0.0, 0.0]
}
},
"plane": {
"position": [2.0, 0.0, 0.0],
"normal": [-1.0, 0.0, 0.0],
"material": {
"diffuse": [0.0, 0.0, 1.0],
"transmissive": true,
"specular": [0.0, 0.0, 0.0]
}
},
"plane": {
"position": [0.0, 1.0, 0.0],
"normal": [0.0, -1.0, 0.0],
"material": {
"diffuse": [0.0, 1.0, 1.0],
"transmissive": true,
"specular": [0.0, 0.0, 0.0]
}
},
"plane": {
"position": [0.0, 0.0, -2.0],
"normal": [0.0, 0.0, 1.0],
"material": {
"diffuse": [1.0, 0.0, 1.0],
"transmissive": true,
"specular": [0.0, 0.0, 0.0]
}
},
"plane": {
"position": [0.0, 0.0, 1.1],
"normal": [0.0, 0.0, -1.0],
"material": {
"diffuse": [1.0, 1.0, 0.0],
"transmissive": true,
"specular": [0.0, 0.0, 0.0]
}
}
}