// Optimized routine for tracing a shadow ray. // // This routine doesn't return the nearest intersection, but simply // checks if there is any intersection. int shadow_check(vec3 ray_origin, vec3 ray_direction) { intersection_point ip; num_rays_shot++; num_shadow_rays_shot++; for (int s = 0; s < scene_num_spheres; s++) { if (ray_intersects_sphere(&ip, scene_spheres[s], ray_origin, ray_direction)) return 1; } if (use_bvh) { // Use the BVH for speedy intersection testing if (find_first_intersected_bvh_triangle(&ip, ray_origin, ray_direction)) return 1; } else { // Simply iterate over all the triangles in the scene and check for intersection for (int t = 0; t < scene_num_triangles; t++) { if (ray_intersects_triangle(&ip, scene_triangles[t], ray_origin, ray_direction)) return 1; } } return 0; }
void rayIntersectionNonLightTest(ray_t ray, intersect_t *intersect) { intersect->t = -1; // Sphere intersections for (int m = 0; m < numSpheres; m++) { ray_intersects_sphere(ray, &spheres[m], intersect); } // Triangle intersections for (int m = 0; m < numTriangles; m++) { ray_intersects_triangle(ray, &triangles[m], intersect); } }
// Returns the nearest hit of the given ray with objects in the scene // (either a sphere or a triangle). // // Returns 1 and sets the intersection point values if there // is an intersection, returns 0 otherwise. int find_first_intersection(intersection_point *ip, vec3 ray_origin, vec3 ray_direction) { int have_hit; float t_nearest; intersection_point ip2; num_rays_shot++; // We have found no hit yet t_nearest = C_INFINITY; have_hit = 0; // First check against spheres in the scene for (int s = 0; s < scene_num_spheres; s++) { // We need a second set of p and n variables, as there's the // possibility that we'll overwrite a closer intersection already // found if (ray_intersects_sphere(&ip2, scene_spheres[s], ray_origin, ray_direction)) { if (ip2.t < t_nearest) { *ip = ip2; t_nearest = ip2.t; have_hit = 1; } } } // Then check against triangles in the scene if (use_bvh) { // Use the BVH to speed up intersection testing if (find_first_intersected_bvh_triangle(&ip2, ray_origin, ray_direction)) { if (ip2.t < t_nearest) { *ip = ip2; t_nearest = ip2.t; have_hit = 1; } } } else { // Simply iterate over all the triangles in the scene and check for intersection for (int t = 0; t < scene_num_triangles; t++) { if (ray_intersects_triangle(&ip2, scene_triangles[t], ray_origin, ray_direction)) { if (ip2.t < t_nearest) { *ip = ip2; t_nearest = ip2.t; have_hit = 1; } } } } return have_hit; }