diff --git a/main.cpp b/main.cpp index 08b3a8a..5f06e21 100644 --- a/main.cpp +++ b/main.cpp @@ -35,6 +35,7 @@ static vec3 ** image; static void scene_1(vector
& vf, vector & vl, mat4x4 & i_model_view); static void scene_2(vector
& vf, vector & vl, mat4x4 & i_model_view); static void scene_3(vector
& vf, vector & vl, mat4x4 & i_model_view); +static void scene_4(vector
& vf, vector & vl, mat4x4 & i_model_view); int main(int argc, char ** argv) { FILE * out; @@ -363,3 +364,17 @@ static void scene_3(vector
& vf, vector & vl, mat4x4 & i_mode i_model_view = inverse(lookAt(eye, center, up)); } + +static void scene_4(vector
& vf, vector & vl, mat4x4 & i_model_view) { + Sphere * s; + Plane * p; + + 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
(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
(p)); +} diff --git a/path_tracer.cpp b/path_tracer.cpp index 7374db8..4fb648e 100644 --- a/path_tracer.cpp +++ b/path_tracer.cpp @@ -14,7 +14,7 @@ static const float PDF = (1.0f / (2.0f * pi())); vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vector & v_lights, unsigned int rec_level) const { float t, _t; Figure * _f; - vec3 n, color, i_pos, ref, sample, dir_diff_color, dir_spec_color, ind_color; + vec3 n, color, i_pos, ref, sample, dir_diff_color, dir_spec_color, ind_color, amb_color; Ray mv_r, sr, rr; bool vis; float kr, r1, r2; @@ -35,7 +35,7 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vectornormal_at_int(r, t); - + // Check if the material is not reflective/refractive. if( !_f->m_mat.m_refract) { // Calculate the direct lighting. @@ -53,8 +53,8 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vectordiffuse(n, r, t, _f->m_mat); - dir_spec_color += (vis ? 1.0f : 0.0f) * v_lights[l]->specular(n, r, t, _f->m_mat); + dir_diff_color += vis ? v_lights[l]->diffuse(n, r, t, _f->m_mat) : vec3(0.0f); + dir_spec_color += vis ? v_lights[l]->specular(n, r, t, _f->m_mat) : vec3(0.0f); } // If enabled, calculate indirect lighting contribution. @@ -67,14 +67,35 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vectorm_mat.m_diffuse / pi())) + dir_spec_color; + // Calculate environment light contribution + if (BCKG_COLOR.r > 0.0f || BCKG_COLOR.g > 0.0f || BCKG_COLOR.b > 0.0f) { + vis = true; + + r1 = random01(); + r2 = random01(); + sample = sample_hemisphere(r1, r2); + rotate_sample(sample, n); + rr = Ray(normalize(sample), i_pos + (sample * BIAS)); + + // Cast a shadow ray to determine visibility. + for (size_t f = 0; f < v_figures.size(); f++) { + if (v_figures[f]->intersect(rr, _t)) { + vis = false; + break; + } + } + + amb_color = vis ? BCKG_COLOR * max(dot(n, rr.m_direction), 0.0f) / PDF : vec3(0.0f); + } + + color += ((dir_diff_color + ind_color + amb_color) * (_f->m_mat.m_diffuse / pi())) + dir_spec_color; // Determine the specular reflection color. if (_f->m_mat.m_rho > 0.0f && rec_level < MAX_RECURSION) { 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, rec_level + 1); } else if (_f->m_mat.m_rho > 0.0f && rec_level >= MAX_RECURSION) - return vec3(0.0f); + return vec3(0.0f); } else { // If the material has transmission enabled, calculate the Fresnel term. @@ -92,7 +113,7 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vectorm_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, rec_level + 1); } else if (rec_level >= MAX_RECURSION) - return vec3(0.0f); + return vec3(0.0f); } @@ -100,5 +121,5 @@ vec3 PathTracer::trace_ray(Ray & r, vector
& v_figures, vector(rand()) / static_cast(RAND_MAX);