Photon tracing fixed.
This commit is contained in:
18
main.cpp
18
main.cpp
@@ -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);
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
98
scenes/scene10.json
Normal 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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user