void FillArrayWithPoints(void) { int i, j, k; int idx; idx = 0; for (k = 0; k < nz; k++) { for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { if (abs(volume[idx]-isovalue) <= epsilon) { AddVertexToArray( v3_create((i+0.5)*sizex, (j+0.5)*sizey, (k+0.5)*sizez), v3_create(0, 0, 0) ); } idx++; } } } }
// Create a bounding box (initialized to be empty, i.e. min > max) boundingbox bbox_create(void) { boundingbox bbox; bbox.min = v3_create(C_INFINITY, C_INFINITY, C_INFINITY); bbox.max = v3_create(-C_INFINITY, -C_INFINITY, -C_INFINITY); return bbox; }
void ray_trace(void) { vec3 forward_vector, right_vector, up_vector; int i, j; float image_plane_width, image_plane_height; vec3 color; char buf[128]; struct timeval t0, t1; float time_taken; fprintf(stderr, "Ray tracing ..."); gettimeofday(&t0, NULL); num_rays_shot = num_shadow_rays_shot = num_triangles_tested = num_bboxes_tested = 0; // Compute camera coordinate system from camera position // and look-at point up_vector = v3_create(0, 0, 1); forward_vector = v3_normalize(v3_subtract(scene_camera_lookat, scene_camera_position)); right_vector = v3_normalize(v3_crossprod(forward_vector, up_vector)); up_vector = v3_crossprod(right_vector, forward_vector); // Compute size of image plane from the chosen field-of-view // and image aspect ratio. This is the size of the plane at distance // of one unit from the camera position. image_plane_height = 2.0 * tan(0.5*VFOV/180*M_PI); image_plane_width = image_plane_height * (1.0 * framebuffer_width / framebuffer_height); vec3 d, e, u, v, w, ud, vd; float l, r, b, t, nx, ny; // direction d, origin e // ONB u, v, w // image plane edges l, r, b, t // window size nx, ny e = scene_camera_position; u = right_vector, v = up_vector, w = v3_negate(forward_vector); l = -0.5 * image_plane_width, r = 0.5 * image_plane_width; b = 0.5 * image_plane_height, t = -0.5 * image_plane_height; nx = framebuffer_width, ny = framebuffer_height; // Loop over all pixels in the framebuffer for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { ud = v3_multiply(u, (l + (r - l) * ((i + 0.5) / nx))); vd = v3_multiply(v, (b + (t - b) * ((j + 0.5) / ny))); d = v3_add(v3_add(ud, vd), v3_negate(w)); color = ray_color(0, e, d); put_pixel(i, j, color.x, color.y, color.z); } sprintf(buf, "Ray-tracing ::: %.0f%% done", 100.0*j/framebuffer_height); glutSetWindowTitle(buf); } // Done! gettimeofday(&t1, NULL); glutSetWindowTitle("Ray-tracing ::: done"); // Output some statistics time_taken = 1.0 * (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec) / 1000000.0; fprintf(stderr, " done in %.1f seconds\n", time_taken); fprintf(stderr, "... %lld total rays shot, of which %d camera rays and " "%lld shadow rays\n", num_rays_shot, do_antialiasing ? 4*framebuffer_width*framebuffer_height : framebuffer_width*framebuffer_height, num_shadow_rays_shot); fprintf(stderr, "... %lld triangles intersection tested " "(avg %.1f tri/ray)\n", num_triangles_tested, 1.0*num_triangles_tested/num_rays_shot); fprintf(stderr, "... %lld bboxes intersection tested (avg %.1f bbox/ray)\n", num_bboxes_tested, 1.0*num_bboxes_tested/num_rays_shot); }
void FillArrayWithCubes(void) { int i, j, k; int idx; float minx, miny, minz; float maxx, maxy, maxz; idx = 0; for (k = 0; k < nz; k++) { for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { if (abs(volume[idx]-isovalue) <= epsilon) { minx = i*sizex; miny = j*sizey; minz = k*sizez; maxx = (i+1)*sizex; maxy = (j+1)*sizey; maxz = (k+1)*sizez; AddVertexToArray(v3_create(minx, miny, minz), v3_create(0, 0, -1)); AddVertexToArray(v3_create(maxx, miny, minz), v3_create(0, 0, -1)); AddVertexToArray(v3_create(maxx, maxy, minz), v3_create(0, 0, -1)); AddVertexToArray(v3_create(minx, maxy, minz), v3_create(0, 0, -1)); AddVertexToArray(v3_create(minx, miny, maxz), v3_create(0, 0, 1)); AddVertexToArray(v3_create(maxx, miny, maxz), v3_create(0, 0, 1)); AddVertexToArray(v3_create(maxx, maxy, maxz), v3_create(0, 0, 1)); AddVertexToArray(v3_create(minx, maxy, maxz), v3_create(0, 0, 1)); AddVertexToArray(v3_create(minx, miny, minz), v3_create(0, -1, 0)); AddVertexToArray(v3_create(maxx, miny, minz), v3_create(0, -1, 0)); AddVertexToArray(v3_create(maxx, miny, maxz), v3_create(0, -1, 0)); AddVertexToArray(v3_create(minx, miny, maxz), v3_create(0, -1, 0)); AddVertexToArray(v3_create(minx, maxy, minz), v3_create(0, 1, 0)); AddVertexToArray(v3_create(maxx, maxy, minz), v3_create(0, 1, 0)); AddVertexToArray(v3_create(maxx, maxy, maxz), v3_create(0, 1, 0)); AddVertexToArray(v3_create(minx, maxy, maxz), v3_create(0, 1, 0)); AddVertexToArray(v3_create(minx, miny, minz), v3_create(-1, 0, 0)); AddVertexToArray(v3_create(minx, maxy, minz), v3_create(-1, 0, 0)); AddVertexToArray(v3_create(minx, maxy, maxz), v3_create(-1, 0, 0)); AddVertexToArray(v3_create(minx, miny, maxz), v3_create(-1, 0, 0)); AddVertexToArray(v3_create(maxx, miny, minz), v3_create(1, 0, 0)); AddVertexToArray(v3_create(maxx, maxy, minz), v3_create(1, 0, 0)); AddVertexToArray(v3_create(maxx, maxy, maxz), v3_create(1, 0, 0)); AddVertexToArray(v3_create(maxx, miny, maxz), v3_create(1, 0, 0)); } idx++; } } } }
void ray_trace(void) { vec3 forward_vector, right_vector, up_vector; int i, j; float image_plane_width, image_plane_height; vec3 color; char buf[128]; struct timeval t0, t1; float time_taken; fprintf(stderr, "Ray tracing ..."); gettimeofday(&t0, NULL); num_rays_shot = num_shadow_rays_shot = num_triangles_tested = num_bboxes_tested = 0; // Compute camera coordinate system from camera position // and look-at point up_vector = v3_create(0, 0, 1); forward_vector = v3_normalize(v3_subtract(scene_camera_lookat, scene_camera_position)); right_vector = v3_normalize(v3_crossprod(forward_vector, up_vector)); up_vector = v3_crossprod(right_vector, forward_vector); // Compute size of image plane from the chosen field-of-view // and image aspect ratio. This is the size of the plane at distance // of one unit from the camera position. image_plane_height = 2.0 * tan(0.5*VFOV/180*M_PI); image_plane_width = image_plane_height * (1.0 * framebuffer_width / framebuffer_height); // vector points to the middle of the monitor vec3 plane_center = v3_add(scene_camera_position, forward_vector); // vector points to the left side of the monitor vec3 le_unnormalized = v3_multiply(right_vector, -(image_plane_width / 2.0)); // vector points to the up side of the monitor vec3 up_unnormalized = v3_multiply(up_vector, image_plane_height / 2.0); // vector points to the coordinates 0,0 (left up) of the monitor vec3 left_up = v3_add(plane_center, v3_add(le_unnormalized, up_unnormalized)); // vector points to right, and has length equal to width of a pixel vec3 pixel2pixel_x = v3_multiply(right_vector, (image_plane_width / framebuffer_width)); // vector points to down, and has length equal to height of a pixel vec3 pixel2pixel_y = v3_multiply(up_vector, -(image_plane_height / framebuffer_height)); // ANTI-ALIASING LOOP if (do_antialiasing) { // loop over all pixels in the framebuffer for (j = 0; j < framebuffer_height; j++) { for (i = 0; i < framebuffer_width; i++) { // for each pixel, shoot four rays vec3 ray_direction_00 = v3_add(v3_add(left_up, v3_multiply(pixel2pixel_y, j + 0.25)), v3_multiply(pixel2pixel_x, i + 0.25)); vec3 ray_direction_01 = v3_add(v3_add(left_up, v3_multiply(pixel2pixel_y, j + 0.75)), v3_multiply(pixel2pixel_x, i + 0.25)); vec3 ray_direction_10 = v3_add(v3_add(left_up, v3_multiply(pixel2pixel_y, j + 0.25)), v3_multiply(pixel2pixel_x, i + 0.75)); vec3 ray_direction_11 = v3_add(v3_add(left_up, v3_multiply(pixel2pixel_y, j + 0.75)), v3_multiply(pixel2pixel_x, i + 0.75)); // for each ray fired, get the difference ray_direction_00 = v3_subtract(ray_direction_00, scene_camera_position); ray_direction_01 = v3_subtract(ray_direction_01, scene_camera_position); ray_direction_10 = v3_subtract(ray_direction_10, scene_camera_position); ray_direction_11 = v3_subtract(ray_direction_11, scene_camera_position); // add the colors of the four rays, then divide by four color = ray_color(0, scene_camera_position, ray_direction_00); color = v3_add(color, ray_color(0, scene_camera_position, ray_direction_01)); color = v3_add(color, ray_color(0, scene_camera_position, ray_direction_10)); color = v3_add(color, ray_color(0, scene_camera_position, ray_direction_11)); color = v3_multiply(color, 0.25); // output pixel color put_pixel(i, j, color.x, color.y, color.z); } sprintf(buf, "Ray-tracing (AA enabled) ::: %.0f%% done", 100.0*j/framebuffer_height); glutSetWindowTitle(buf); } } // NON-ANTI-ALIASING LOOP else { // loop over all pixels in the framebuffer for (j = 0; j < framebuffer_height; j++) { for (i = 0; i < framebuffer_width; i++) { // select the currently relevant pixel vec3 ray_direction = v3_add(v3_add(left_up, v3_multiply(pixel2pixel_y, j + 0.5)), v3_multiply(pixel2pixel_x, i + 0.5)); // get diference between the two points ray_direction = v3_subtract(ray_direction, scene_camera_position); // set color color = ray_color(0, scene_camera_position, ray_direction); // output pixel color put_pixel(i, j, color.x, color.y, color.z); } sprintf(buf, "Ray-tracing ::: %.0f%% done", 100.0*j/framebuffer_height); glutSetWindowTitle(buf); } } // set a detailed title, useful for testing if (use_bvh && do_antialiasing) glutSetWindowTitle("Ray-tracing is done. AA=yes, BVH=yes"); else if (use_bvh && !do_antialiasing) glutSetWindowTitle("Ray-tracing is done. AA=no, BVH=yes"); else if (!use_bvh && do_antialiasing) glutSetWindowTitle("Ray-tracing is done. AA=yes, BVH=no"); else glutSetWindowTitle("Ray-tracing is done. AA=no, BVH=no"); // Done! gettimeofday(&t1, NULL); // Output some statistics time_taken = 1.0 * (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec) / 1000000.0; fprintf(stderr, " done in %.1f seconds\n", time_taken); fprintf(stderr, "... %d total rays shot, of which %d camera rays and %d shadow rays\n", num_rays_shot, do_antialiasing ? 4*framebuffer_width*framebuffer_height : framebuffer_width*framebuffer_height, num_shadow_rays_shot); fprintf(stderr, "... %d triangles intersection tested (avg %.1f tri/ray)\n", num_triangles_tested, 1.0*num_triangles_tested/num_rays_shot); fprintf(stderr, "... %d bboxes intersection tested (avg %.1f bbox/ray)\n", num_bboxes_tested, 1.0*num_bboxes_tested/num_rays_shot); }
void ray_trace(void) { vec3 forward_vector, right_vector, up_vector; int i, j; float image_plane_width, image_plane_height; vec3 color; char buf[128]; struct timeval t0, t1; float time_taken; fprintf(stderr, "Ray tracing ..."); gettimeofday(&t0, NULL); num_rays_shot = num_shadow_rays_shot = num_triangles_tested = num_bboxes_tested = 0; // Compute camera coordinate system from camera position // and look-at point up_vector = v3_create(0, 0, 1); forward_vector = v3_normalize(v3_subtract(scene_camera_lookat, scene_camera_position)); right_vector = v3_normalize(v3_crossprod(forward_vector, up_vector)); up_vector = v3_crossprod(right_vector, forward_vector); // Compute size of image plane from the chosen field-of-view // and image aspect ratio. This is the size of the plane at distance // of one unit from the camera position. image_plane_height = 2.0 * tan(0.5*VFOV/180*M_PI); image_plane_width = image_plane_height * (1.0 * framebuffer_width / framebuffer_height); printf("imageplane: (%f, %f)\n", image_plane_width, image_plane_height); // the borders of the image plane in camera coordinates float left = -(image_plane_width / 2), right = image_plane_width / 2, bottom = (image_plane_height / 2), top = -image_plane_height / 2; // rays are expressed as a location vector and direction vector vec3 ray_origin = scene_camera_position; float u, v, w; // Loop over all pixels in the framebuffer for (j = 0; j < framebuffer_height; j++) { for (i = 0; i < framebuffer_width; i++) { vec3 directions[4]; int directions_i = 0; float offsets[2]; int offsets_n; // if anti-aliasing is activated, shoot 4 rays through each pixel // slightly offset from the center if (do_antialiasing) { offsets_n = 2; offsets[0] = 0.25; offsets[1] = 0.75; } // without anti-aliasing, just send a single ray through the // pixel-center else { offsets_n = 1; offsets[0] = 0.5; } // calculate the [u, v, w] components of the pixel's location // relative to the camera for (int u_offset = 0; u_offset < offsets_n; ++u_offset) { for (int v_offset = 0; v_offset < offsets_n; ++v_offset) { w = 1; u = left + (right - left) * (i + offsets[u_offset]) / framebuffer_width; v = bottom + (top - bottom) * (j + offsets[v_offset]) / framebuffer_height; // the direction of the ray is a a linear combination of the camera // basisvectors directions[directions_i] = v3_add3(v3_multiply(forward_vector, w), v3_multiply(right_vector, u), v3_multiply(up_vector, v)); directions_i += 1; } } // Output average pixel color color = v3_create(0.0, 0.0, 0.0); int num_directions = do_antialiasing ? 2 * offsets_n : 1; for (int dir = 0; dir < num_directions; ++dir) { color = v3_add(color, ray_color(0, ray_origin, directions[dir]) ); } color = v3_multiply(color, 1.0 / num_directions); put_pixel(i, j, color.x, color.y, color.z); } sprintf(buf, "Ray-tracing ::: %.0f%% done", 100.0*j/framebuffer_height); glutSetWindowTitle(buf); } // Done! gettimeofday(&t1, NULL); glutSetWindowTitle("Ray-tracing ::: done"); // Output some statistics time_taken = 1.0 * (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec) / 1000000.0; fprintf(stderr, " done in %.1f seconds\n", time_taken); fprintf(stderr, "... %d total rays shot, of which %d camera rays and %d shadow rays\n", num_rays_shot, do_antialiasing ? 4*framebuffer_width*framebuffer_height : framebuffer_width*framebuffer_height, num_shadow_rays_shot); fprintf(stderr, "... %d triangles intersection tested (avg %.1f tri/ray)\n", num_triangles_tested, 1.0*num_triangles_tested/num_rays_shot); fprintf(stderr, "... %d bboxes intersection tested (avg %.1f bbox/ray)\n", num_bboxes_tested, 1.0*num_bboxes_tested/num_rays_shot); }
void ray_trace(void) { vec3 forward_vector, right_vector, up_vector; int i, j; float image_plane_width, image_plane_height; vec3 color; char buf[128]; struct timeval t0, t1; float time_taken; fprintf(stderr, "Ray tracing ..."); gettimeofday(&t0, NULL); num_rays_shot = num_shadow_rays_shot = num_triangles_tested = num_bboxes_tested = 0; // Compute camera coordinate system from camera position // and look-at point up_vector = v3_create(0, 0, 1); forward_vector = v3_normalize(v3_subtract(scene_camera_lookat, scene_camera_position)); right_vector = v3_normalize(v3_crossprod(forward_vector, up_vector)); up_vector = v3_crossprod(right_vector, forward_vector); // Compute size of image plane from the chosen field-of-view // and image aspect ratio. This is the size of the plane at distance // of one unit from the camera position. image_plane_height = 2.0 * tan(0.5*VFOV/180*M_PI); image_plane_width = image_plane_height * (1.0 * framebuffer_width / framebuffer_height); float bottom, left, Us, Vs; left = -image_plane_width * 0.5; bottom = image_plane_height * 0.5; fprintf(stderr, "%d %d\r\n", framebuffer_height, framebuffer_width); // Loop over all pixels in the framebuffer for (j = 0; j < framebuffer_height; j++) { for (i = 0; i < framebuffer_width; i++) { if(!do_antialiasing){ /* With the formula "b + (t−b) * ((j+ 0.5) / ny)" the vector is calculated. * (t-b) equals the negative image_plane_height */ Us = bottom + (-image_plane_height*(j+0.5)/framebuffer_height); /* using the formula: "l + (r−l) * ((i+ 0.5) / nx)" to calculate the vector * (r-l) equals the image_plane_width. */ Vs = left + (image_plane_width*(i+0.5)/framebuffer_width); /* /* Calculate the vector through the pixel (for "Ray through pixel") * Using the formula "Us * U + Vs * v + n * w" */ vec3 UV = v3_add(v3_multiply(up_vector, Us), v3_multiply(right_vector, Vs)); vec3 ray = v3_add(forward_vector, UV); /* Fills the color */ color = ray_color(0, scene_camera_position, ray); } else { float Us1 = bottom + (-image_plane_height*(j+0.25)/framebuffer_height); float Us2 = bottom + (-image_plane_height*(j+0.75)/framebuffer_height); float Vs1 = left + (image_plane_width*(i+0.25)/framebuffer_width); float Vs2 = left + (image_plane_width*(i+0.75)/framebuffer_width); vec3 UV1 = v3_add(v3_multiply(up_vector, Us1), v3_multiply(right_vector, Vs1)); vec3 UV2 = v3_add(v3_multiply(up_vector, Us2), v3_multiply(right_vector, Vs1)); vec3 UV3 = v3_add(v3_multiply(up_vector, Us1), v3_multiply(right_vector, Vs2)); vec3 UV4 = v3_add(v3_multiply(up_vector, Us2), v3_multiply(right_vector, Vs2)); vec3 color1 = ray_color(0, scene_camera_position, v3_add(forward_vector, UV1)); vec3 color2 = ray_color(0, scene_camera_position, v3_add(forward_vector, UV2)); vec3 color3 = ray_color(0, scene_camera_position, v3_add(forward_vector, UV3)); vec3 color4 = ray_color(0, scene_camera_position, v3_add(forward_vector, UV4)); color = v3_multiply( v3_add(v3_add(color1, color2), v3_add(color3, color4)), 0.25 ); } /* Output pixel color */ put_pixel(i, j, color.x, color.y, color.z); } sprintf(buf, "Ray-tracing ::: %.0f%% done", 100.0*j/framebuffer_height); glutSetWindowTitle(buf); } // Done! gettimeofday(&t1, NULL); glutSetWindowTitle("Ray-tracing ::: done"); // Output some statistics time_taken = 1.0 * (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec) / 1000000.0; fprintf(stderr, " done in %.1f seconds\n", time_taken); fprintf(stderr, "... %lld total rays shot, of which %d camera rays and " "%lld shadow rays\n", num_rays_shot, do_antialiasing ? 4*framebuffer_width*framebuffer_height : framebuffer_width*framebuffer_height, num_shadow_rays_shot); fprintf(stderr, "... %lld triangles intersection tested " "(avg %.1f tri/ray)\n", num_triangles_tested, 1.0*num_triangles_tested/num_rays_shot); fprintf(stderr, "... %lld bboxes intersection tested (avg %.1f bbox/ray)\n", num_bboxes_tested, 1.0*num_bboxes_tested/num_rays_shot); }