Color PhongMaterial::shade(const Intersection& intersection, const Scene& scene) const { Color intensity; PointD3 point = intersection.hit_point; Options options = scene.options(); if(options.diffuse_illumination || options.specular_illumination) { Color i_diffuse; Color i_specular; VectorD n = intersection.normal; for(auto &light : scene.lights()) { VectorD l = -1 * light->direction_at(point); float n_dot_l = n.dot(l); Color i_light = light->intensity(point, scene); // === Diffuse reflection === if(options.diffuse_illumination) { if(n_dot_l > 0.0f) { i_diffuse = i_light * c_diffuse * n_dot_l; } } // === Specular reflection === if(options.specular_illumination) { VectorD v = -1 * intersection.incident_ray.direction; VectorD r = 2 * n_dot_l * n - l; r.normalize(); float v_dot_r = v.dot(r); if(v_dot_r > 0.0f) { i_specular = i_light * c_specular * std::pow(v_dot_r, s); } } } intensity += i_diffuse; intensity += i_specular; } // === Ambient reflection === if(options.ambient_illumination) { auto ambient_light = scene.ambient_light(); if(ambient_light) { Color i_light = scene.ambient_light()->intensity(point, scene); Color i_ambient = i_light * c_ambient; intensity += i_ambient; } } return intensity; }
Color MirrorMaterial::shade(const Intersection &intersection, const Scene &scene) const { VectorD vec_incident = -intersection.incident_ray.direction; if(intersection.incident_ray.recursion_depth >= scene.options().max_recursion) { return Color(0.0, 0.0, 0.0); } VectorD n = intersection.normal; // Reflection vector VectorD vec_r = 2 * n.dot(vec_incident) * n - vec_incident; vec_r.normalize(); // Reflection ray Ray ray_r(intersection.hit_point, vec_r); ray_r.recursion_depth = intersection.incident_ray.recursion_depth + 1; // Trace reflection ray Color reflected_color; Intersection reflection_hit = scene.trace(ray_r); if(reflection_hit.exists) { reflected_color = reflection_hit.hit_object->material()->shade(reflection_hit, scene); } else { reflected_color = scene.background(); } return reflected_color; }
Color LambertMaterial::shade(const Intersection& intersection, const Scene& scene) const { Color intensity; PointD3 point = intersection.hit_point; // === Diffuse reflection === if(scene.options().diffuse_illumination) { Color intensity_diffuse; for(auto &light : scene.lights()) { VectorD n = intersection.normal; VectorD l = -1.0 * light->direction_at(point); float dot = n.dot(l); if(dot > 0.0f) { intensity_diffuse += light->intensity(point, scene) * c_diffuse * dot; } } intensity += intensity_diffuse; } // === Ambient reflection === if(scene.options().ambient_illumination) { auto ambient_light = scene.ambient_light(); if(ambient_light) { Color ambient_intensity = scene.ambient_light()->intensity(point, scene); Color intensity_ambient = ambient_intensity * c_ambient; intensity += intensity_ambient; } } return intensity; }