/********************************************************************* * Phong illumination - you need to implement this! *********************************************************************/ RGB_float phong(Point p, Vector eye_vec, Vector surf_norm, Spheres *sph) { Vector light_vec = get_vec(p, light1); float d = vec_len(get_vec(p, light1)); normalize(&light_vec); Vector reflect_vec = getReflectedRay(surf_norm, light_vec); normalize(&reflect_vec); RGB_float ambient = {0,0,0}; RGB_float diffuse = {0,0,0}; RGB_float specular = {0,0,0}; RGB_float color = {0,0,0}; float attenuation_coeff = 1/(decay_a + decay_b*d + decay_c*pow(d,2)); //global ambience globalIllumination(sph, &ambient); //local ambience localIllumination(sph, &ambient); //diffuse diffuseIllumination(sph, &color, surf_norm, light_vec, attenuation_coeff); //specular specularIllumination(sph, &color, reflect_vec, eye_vec, attenuation_coeff); //add diffuse + specular //diffuse = clr_add(diffuse, specular); //scale by attenuation coefficient //diffuse = clr_scale(diffuse, attenuation_coeff); //add ambient to diffuse+specular //color = clr_add(ambient, diffuse); Vector shadow_vec = get_vec(p, light1); if(inShadow(p, shadow_vec, scene, sph) && shadow_on) { color = ambient; } return color; }
float ShadowCalculator::softShadow(const AreaLight* light, const Point3D& pointToBeTested) const { float intersectionsWithLight = 0; //I test if the point of intersection is visible with n shadow ray generated from random points on an area light. for(std::vector<Point3D>::size_type i = 0; i != light->randomSpherePoints.size(); i++) { bool isInShadow = inShadow(pointToBeTested, light->randomSpherePoints[i]); if(isInShadow == false) { intersectionsWithLight++; } } //Last point is in shadow. return intersectionsWithLight/constant::numberOfShadowRay; }
float ShadowCalculator::visiblePercentage(const Point3D& pointToBeChecked) { //SHADOW. float shadowPercentage = 0.0f; AreaLight* light = dynamic_cast<AreaLight* >(tracer.scene->light); if(light != nullptr) { //Area light: soft shadow. shadowPercentage = softShadow(light, pointToBeChecked); } else { //Point light: standard shadow. bool isInShadow = inShadow(pointToBeChecked, tracer.scene->light->origin); if(!isInShadow) { shadowPercentage = 1.0f; } } return shadowPercentage; }
RGB_float recursive_ray_trace(Vector ray, Point p, int step) { RGB_float color = background_clr; RGB_float reflected_color = {0,0,0}; RGB_float refracted_color = {0,0,0}; Spheres *closest_sph; Point *hit = new Point; closest_sph = intersect_scene(p, ray, scene, hit); //get the point color here //intersects a sphere Point *plane_hit = new Point; color = background_clr; if(chessboard_on && intersect_plane(p, ray, N_plane, p0, plane_hit)) { Vector eye_vec = get_vec(*plane_hit, eye_pos); Vector light_vec = get_vec(*plane_hit, p); normalize(&light_vec); normalize(&eye_vec); color = colorPlane(*plane_hit); Vector shadow_vec = get_vec(*plane_hit, light1); Spheres *sph = NULL; if(inShadow(*plane_hit, shadow_vec, scene, sph) && shadow_on) { color = clr_scale(color, .5); } } if(closest_sph != NULL) { Vector eye_vec = get_vec(*hit, eye_pos); Vector surf_norm = sphere_normal(*hit, closest_sph); Vector light_vec = get_vec(*hit, p); normalize(&light_vec); normalize(&surf_norm); normalize(&eye_vec); color = phong(*hit, eye_vec, surf_norm, closest_sph); if(step < step_max && reflection_on) { Vector reflect_vec = vec_minus(vec_scale(surf_norm, vec_dot(surf_norm, light_vec)*2), light_vec); step += 1; normalize(&reflect_vec); reflected_color = recursive_ray_trace(reflect_vec, *hit, step); reflected_color = clr_scale(reflected_color, closest_sph->reflectance); color = clr_add(color, reflected_color); } if(step < step_max && refraction_on) { Vector refracted_ray = getRefractedRay(1.51, closest_sph, surf_norm, light_vec); step += 1; normalize(&refracted_ray); refracted_ray.x = hit->x + refracted_ray.x; refracted_ray.y = hit->x + refracted_ray.y; refracted_ray.z = hit->x + refracted_ray.z; refracted_color = recursive_ray_trace(refracted_ray, *hit, step); color = clr_add(color, reflected_color); } return color; } else { return color; } }