pub fn render(
    dimensions: (usize, usize),
    spheres: &Vec<Sphere>,
    lights: &Vec<Light>,
) -> Vec<Vector3<f32>> {
    // Hardcoded camero parameters
    let film_distance: f32 = 1.0;
    let origin = Vector3::<f32>::new(0.0, 0.0, 0.0);
    // Using the aspect ratio of the image, compute the distance between
    // pixel centers as well as the upper and lower edges of the image
    // in world coordinates.
    let inverse_aspect_ratio = dimensions.1 as f32 / dimensions.0 as f32;
    let delta_x = 2.0 / dimensions.0 as f32;
    let delta_y = 2.0 * inverse_aspect_ratio / dimensions.1 as f32;
    let upper_left = (-1.0, inverse_aspect_ratio);

    // Create indices for the pixels as well as the subpixel offsets
    // to feed into the actual ray tracing loop. We use fixed subpixel
    // offsets as randomization didn't seem to provide any benefits but
    // was slower
    let number_of_pixels = dimensions.0 * dimensions.1;
    let indices: Vec<usize> = (0..number_of_pixels).collect();
    let antialiasing_scale_factor = 1.0 / ANTIALIASING_SQRT as f32;
    let antiliasing_step_x = delta_x / ANTIALIASING_SQRT as f32;
    let antiliasing_step_y = delta_y / ANTIALIASING_SQRT as f32;
    let subpixel_offsets_x: Vec<f32> = (0..ANTIALIASING_SQRT)
        .map(|i| 0.5 * antiliasing_step_x + i as f32 * antiliasing_step_x)
        .collect();
    let subpixel_offsets_y: Vec<f32> = (0..ANTIALIASING_SQRT)
        .map(|i| 0.5 * antiliasing_step_y + i as f32 * antiliasing_step_y)
        .collect();
    
    // Compute pixels in parallel...
    indices
        .par_iter()
        .map(|i| -> Vector3<f32> {
            // ... and subpixels within a thread.
            let mut pixel = Vector3::<f32>::new(0.0, 0.0, 0.0);
            let offset_right = (i % dimensions.0) as f32 * delta_x;
            let offset_down = (i / dimensions.0) as f32 * delta_y;
            let pixel_origin_x = upper_left.0 + offset_right;
            let pixel_origin_y = upper_left.1 - offset_down;
            for x in 0..ANTIALIASING_SQRT {
                for y in 0..ANTIALIASING_SQRT {
                    let ray = Ray::from_to(
                        origin,
                        &Vector3::<f32>::new(
                            pixel_origin_x + subpixel_offsets_x[x],
                            pixel_origin_y - subpixel_offsets_y[y],
                            film_distance,
                        ),
                    );
                    pixel += trace_ray(&ray, spheres, lights, 1);
                }
            }
            pixel * antialiasing_scale_factor
        })
        .collect()
}
/// Render an image of size `dimensions` depicting the spheres and
/// lights, projecting rays from the origin of the coordinate frame
/// through an image plane at x=y=0, z=1, with the left edge being at
/// (-1, 0, 1), the right one at (1, 0, 1), and height determined by
/// the aspect ratio of `dimensions`.
/// 
/// The result is a 2-D Vec of dimension (number of pixels, 3),
/// with the first dimension being the pixels in top-left to 
/// bottom-right scanline order, and the second dimensions being
/// the colors (RGB)
Render an image of size `dimensions` depicting the spheres and
lights, projecting rays from the origin of the coordinate frame
through an image plane at x=y=0, z=1, with the left edge being at
(-1, 0, 1), the right one at (1, 0, 1), and height determined by
the aspect ratio of `dimensions`.

The result is a 2-D Vec of dimension (number of pixels, 3),
with the first dimension being the pixels in top-left to
bottom-right scanline order, and the second dimensions being
the colors (RGB)
Render an image of size ` dimensions ` depicting the spheres and lights projecting rays from the origin of the coordinate frame through an image plane at x = y = 0 z = 1 with the left edge being at ( - 1 0 1 ) the right one at ( 1 0 1 ) and height determined by the aspect ratio of ` dimensions ` . The result is a 2 - D Vec of dimension ( number of pixels 3 ) with the first dimension being the pixels in top - left to bottom - right scanline order and the second dimensions being the colors ( RGB )
pub fn render(
    dimensions: (usize, usize),
    spheres: &Vec<Sphere>,
    lights: &Vec<Light>,
) -> Vec<Vector3<f32>> {
    // Hardcoded camero parameters
    let film_distance: f32 = 1.0;
    let origin = Vector3::<f32>::new(0.0, 0.0, 0.0);
    // Using the aspect ratio of the image, compute the distance between
    // pixel centers as well as the upper and lower edges of the image
    // in world coordinates.
    let inverse_aspect_ratio = dimensions.1 as f32 / dimensions.0 as f32;
    let delta_x = 2.0 / dimensions.0 as f32;
    let delta_y = 2.0 * inverse_aspect_ratio / dimensions.1 as f32;
    let upper_left = (-1.0, inverse_aspect_ratio);
    // Create indices for the pixels as well as the subpixel offsets
    // to feed into the actual ray tracing loop. We use fixed subpixel
    // offsets as randomization didn't seem to provide any benefits but
    // was slower
    let number_of_pixels = dimensions.0 * dimensions.1;
    let indices: Vec<usize> = (0..number_of_pixels).collect();
    let antialiasing_scale_factor = 1.0 / ANTIALIASING_SQRT as f32;
    let antiliasing_step_x = delta_x / ANTIALIASING_SQRT as f32;
    let antiliasing_step_y = delta_y / ANTIALIASING_SQRT as f32;
    let subpixel_offsets_x: Vec<f32> = (0..ANTIALIASING_SQRT)
        .map(|i| 0.5 * antiliasing_step_x + i as f32 * antiliasing_step_x)
        .collect();
    let subpixel_offsets_y: Vec<f32> = (0..ANTIALIASING_SQRT)
        .map(|i| 0.5 * antiliasing_step_y + i as f32 * antiliasing_step_y)
        .collect();
    // Compute pixels in parallel...
    indices
        .par_iter()
        .map(|i| -> Vector3<f32> {
            // ... and subpixels within a thread.
            let mut pixel = Vector3::<f32>::new(0.0, 0.0, 0.0);
            let offset_right = (i % dimensions.0) as f32 * delta_x;
            let offset_down = (i / dimensions.0) as f32 * delta_y;
            let pixel_origin_x = upper_left.0 + offset_right;
            let pixel_origin_y = upper_left.1 - offset_down;
            for x in 0..ANTIALIASING_SQRT {
                for y in 0..ANTIALIASING_SQRT {
                    let ray = Ray::from_to(
                        origin,
                        &Vector3::<f32>::new(
                            pixel_origin_x + subpixel_offsets_x[x],
                            pixel_origin_y - subpixel_offsets_y[y],
                            film_distance,
                        ),
                    );
                    pixel += trace_ray(&ray, spheres, lights, 1);
                }
            }
            pixel * antialiasing_scale_factor
        })
        .collect()
}
pub fn render ( dimensions : ( usize , usize ) , spheres : & Vec < Sphere > , lights : & Vec < Light > , ) -> Vec < Vector3 < f32 > > { // Hardcoded camero parameters let film_distance : f32 = 1.0 ; let origin = Vector3 :: < f32 > :: new ( 0.0 , 0.0 , 0.0 ) ; // Using the aspect ratio of the image, compute the distance between // pixel centers as well as the upper and lower edges of the image // in world coordinates. let inverse_aspect_ratio = dimensions . 1 as f32 / dimensions . 0 as f32 ; let delta_x = 2.0 / dimensions . 0 as f32 ; let delta_y = 2.0 * inverse_aspect_ratio / dimensions . 1 as f32 ; let upper_left = ( - 1.0 , inverse_aspect_ratio ) ; // Create indices for the pixels as well as the subpixel offsets // to feed into the actual ray tracing loop. We use fixed subpixel // offsets as randomization didn't seem to provide any benefits but // was slower let number_of_pixels = dimensions . 0 * dimensions . 1 ; let indices : Vec < usize > = ( 0 .. number_of_pixels ) . collect ( ) ; let antialiasing_scale_factor = 1.0 / ANTIALIASING_SQRT as f32 ; let antiliasing_step_x = delta_x / ANTIALIASING_SQRT as f32 ; let antiliasing_step_y = delta_y / ANTIALIASING_SQRT as f32 ; let subpixel_offsets_x : Vec < f32 > = ( 0 .. ANTIALIASING_SQRT ) . map ( | i | 0.5 * antiliasing_step_x + i as f32 * antiliasing_step_x ) . collect ( ) ; let subpixel_offsets_y : Vec < f32 > = ( 0 .. ANTIALIASING_SQRT ) . map ( | i | 0.5 * antiliasing_step_y + i as f32 * antiliasing_step_y ) . collect ( ) ; // Compute pixels in parallel... indices . par_iter ( ) . map ( | i | -> Vector3 < f32 > { // ... and subpixels within a thread. let mut pixel = Vector3 :: < f32 > :: new ( 0.0 , 0.0 , 0.0 ) ; let offset_right = ( i % dimensions . 0 ) as f32 * delta_x ; let offset_down = ( i / dimensions . 0 ) as f32 * delta_y ; let pixel_origin_x = upper_left . 0 + offset_right ; let pixel_origin_y = upper_left . 1 - offset_down ; for x in 0 .. ANTIALIASING_SQRT { for y in 0 .. ANTIALIASING_SQRT { let ray = Ray :: from_to ( origin , & Vector3 :: < f32 > :: new ( pixel_origin_x + subpixel_offsets_x [ x ] , pixel_origin_y - subpixel_offsets_y [ y ] , film_distance , ) , ) ; pixel += trace_ray ( & ray , spheres , lights , 1 ) ; } } pixel * antialiasing_scale_factor } ) . collect ( ) }
Render an image of size `dimensions` depicting the spheres and
lights, projecting rays from the origin of the coordinate frame
through an image plane at x=y=0, z=1, with the left edge being at
(-1, 0, 1), the right one at (1, 0, 1), and height determined by
the aspect ratio of `dimensions`.
Render an image of size ` dimensions ` depicting the spheres and lights projecting rays from the origin of the coordinate frame through an image plane at x = y = 0 z = 1 with the left edge being at ( - 1 0 1 ) the right one at ( 1 0 1 ) and height determined by the aspect ratio of ` dimensions ` .
dimensions
(usize, usize)
spheres
&Vec<Sphere>
lights
&Vec<Light>
dimensions
(usize, usize)
spheres
&Vec<Sphere>
lights
&Vec<Light>