int find_closest(t_data *data, const int get_normal) { data->closest[1] = -1; if (get_normal == 1) { find_closest_sphere(data, data->viewray, &(data->t)); find_closest_plane(data, data->viewray, &(data->t)); find_closest_cone(data, data->viewray, &(data->t)); find_closest_cylinder(data, data->viewray, &(data->t)); if (data->closest[1] == -1) return (0); if (data->closest[0] == SPHERE) return (sphere_normal(data)); else if (data->closest[0] == PLANE) return (plane_normal(data)); else if (data->closest[0] == CYLINDER) return (cylinder_normal(data)); else if (data->closest[0] == CONE) return (cone_normal(data)); return (1); } return (hit_any_sphere(data, data->lightray, data->t) || hit_any_plane(data, data->lightray, data->t) || hit_any_cone(data, data->lightray, data->t) || hit_any_cylinder(data, data->lightray, data->t)); }
// computation of the input point/dir and output point/dir of the refractor light bool refraction(vec3 inpoint, vec3 invector, void* obj, int isplane, bool inobj, vec3* outlightvector) { // printf("*****"); if(isplane) return false; // printf("not plane\n"); Spheres * sph = (Spheres *)obj; //intermediate light vec3 in_normal = sphere_normal(inpoint, sph); float ratio; if(!inobj) ratio = 1.0/sph->refractivity; else ratio = sph->refractivity; if(!refract_light(in_normal, invector, ratio, outlightvector)) return false; return true; }
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; } }
/************************************************************************ * This is the recursive ray tracer - you need to implement this! * You should decide what arguments to use. ************************************************************************/ vec3 recursive_ray_trace(vec3 eye, vec3 ray, int num, bool inobj) { // // do your thing here // if(num>step_max) return null_clr; vec3 hit; int isplane; void *sph = intersect_scene(eye, ray, scene, &hit, &isplane); vec3 color = null_clr; if(sph==NULL) { return background_clr; } vec3 lightvec = light1 - hit; vec3 lightvec_normal = normalize(lightvec); vec3 lighthit; int lightisplane; void * light_sph = intersect_scene(hit, lightvec_normal, scene, &lighthit, &lightisplane); vec3 surf_normal = isplane?vec3(0,1,0):sphere_normal(hit, (Spheres*)sph); if(light_sph==NULL) { color += phong(-1*ray, lightvec, surf_normal, sph, hit, isplane); } else { if(!shadow_on) { color += phong(-1*ray, lightvec, surf_normal, sph, hit, isplane); } else { color += get_shadow(-1*ray, lightvec, surf_normal, sph, hit, isplane); } } if(reflect_on) { vec3 reflect_vector = 2*dot(-1*ray, surf_normal)*surf_normal + ray; reflect_vector = normalize(reflect_vector); if(isplane) { color += ((struct plane*)sph)->reflectance * recursive_ray_trace(hit, reflect_vector,num+1, inobj); } else if(!isplane) color += ((Spheres *)sph)->reflectance * recursive_ray_trace(hit, reflect_vector, num+1, inobj); } if(refract_on) { vec3 outlightvector; if(refraction(hit, -1*ray, sph, isplane, inobj, &outlightvector)) { if(!isplane) { // printf("refraction point\n"); Spheres * refractsph = (Spheres *)sph; color += refractsph->refr*recursive_ray_trace(hit, outlightvector, num+1, !inobj); } } } if(diffuse_reflection_on && num<2) { int i; for (i=0;i<DIFFUSE_REFLECTION;i++) { float xtheta = 2.0 * static_cast <float> (rand()) / static_cast <float> (RAND_MAX) - 1.0; float ytheta = 2.0 * static_cast <float> (rand()) / static_cast <float> (RAND_MAX) - 1.0; float ztheta = 2.0 * static_cast <float> (rand()) / static_cast <float> (RAND_MAX) - 1.0; vec3 dfray; dfray = rotateX(xtheta*M_PI,surf_normal); dfray = rotateY(ytheta*M_PI,dfray); dfray = rotateZ(ztheta*M_PI,dfray); color += (0.1/DIFFUSE_REFLECTION)*recursive_ray_trace(hit, dfray, num+1, inobj); } } return color; }