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 size_t g_photons = 15000;
|
||||
static float g_p_sample_radius = 0.01f;
|
||||
static float g_cone_filter_k = 1.0f;
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Main function.
|
||||
@@ -113,7 +114,7 @@ int main(int argc, char ** argv) {
|
||||
|
||||
} else if(g_tracer == JENSEN) {
|
||||
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) {
|
||||
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);
|
||||
@@ -246,10 +247,12 @@ void print_usage(char ** const argv) {
|
||||
cerr << " -p\tNumber of primary photons per light source." << endl;
|
||||
cerr << " \tDefaults to 15000." << 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 << " \tSkips the photon tracing step using" << 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) {
|
||||
@@ -263,7 +266,7 @@ void parse_args(int argc, char ** const argv) {
|
||||
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) {
|
||||
case 1:
|
||||
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);
|
||||
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 ':':
|
||||
cerr << "Option \"-" << static_cast<char>(optopt) << "\" requires an argument." << endl;
|
||||
print_usage(argv);
|
||||
|
@@ -32,7 +32,7 @@ using namespace glm;
|
||||
PhotonTracer::~PhotonTracer() { }
|
||||
|
||||
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;
|
||||
vec3 n, color, i_pos, ref, dir_diff_color, dir_spec_color, p_contrib;
|
||||
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);
|
||||
// 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);
|
||||
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);
|
||||
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());
|
||||
|
||||
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_contrib += vec3(red, green, blue) * w;
|
||||
p_contrib += vec3(red, green, blue);
|
||||
}
|
||||
|
||||
// for (Photon p : photons) {
|
||||
// p.getColor(red, green, blue);
|
||||
// p_contrib += vec3(red, green, blue);
|
||||
// }
|
||||
// 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));
|
||||
p_contrib /= (1.0f - (2.0f / (3.0f * m_cone_filter_k))) * pi<float>() * (radius * radius);
|
||||
|
||||
// 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);
|
||||
color += (1.0f - _f->m_mat->m_rho) * p_contrib;
|
||||
|
||||
// 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){
|
||||
#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();
|
||||
@@ -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);
|
||||
|
||||
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) {
|
||||
color = (_f->m_mat->m_rho) * vec3(red, green, blue);
|
||||
i_pos += n * BIAS;
|
||||
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));
|
||||
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);
|
||||
trace_photon(photon, s, rec_level + 1);
|
||||
color = (_f->m_mat->m_rho) * vec3(red, green, blue);
|
||||
i_pos += n * BIAS;
|
||||
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));
|
||||
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);
|
||||
trace_photon(photon, s, rec_level + 1);
|
||||
}
|
||||
|
||||
} 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.
|
||||
if (kr > 0.0f) {
|
||||
color = kr * vec3(red, green, blue);
|
||||
i_pos += n * BIAS;
|
||||
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));
|
||||
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);
|
||||
trace_photon(photon, s, rec_level + 1);
|
||||
color = kr * vec3(red, green, blue);
|
||||
i_pos += n * BIAS;
|
||||
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));
|
||||
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);
|
||||
trace_photon(photon, s, rec_level + 1);
|
||||
}
|
||||
|
||||
// Trace the transmitted photon.
|
||||
if (kr < 1.0f) {
|
||||
color = (1.0f - kr) * vec3(red, green, blue);
|
||||
i_pos -= n * (2 * BIAS);
|
||||
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));
|
||||
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);
|
||||
trace_photon(photon, s, rec_level + 1);
|
||||
color = (1.0f - kr) * vec3(red, green, blue);
|
||||
i_pos -= n * (2 * BIAS);
|
||||
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));
|
||||
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);
|
||||
trace_photon(photon, s, rec_level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,8 +7,8 @@
|
||||
|
||||
class PhotonTracer: public Tracer {
|
||||
public:
|
||||
PhotonTracer(): Tracer(), m_h_radius(0.5f) { }
|
||||
PhotonTracer(unsigned int max_depth, float _r = 0.5f): Tracer(max_depth), m_h_radius(_r) { };
|
||||
PhotonTracer(): Tracer(), m_h_radius(0.5f), m_cone_filter_k(1.0f) { }
|
||||
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 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);
|
||||
private:
|
||||
float m_h_radius;
|
||||
float m_cone_filter_k;
|
||||
kdTree m_photon_map;
|
||||
kdTree m_caustics_map;
|
||||
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