58 lines
1.6 KiB
Rust
58 lines
1.6 KiB
Rust
use alloc::vec::Vec;
|
|
use cgmath::{Matrix4, Vector3, Vector4, num_traits::Num};
|
|
|
|
pub struct Ray<T> {
|
|
pub(crate) origin: Vector3<T>,
|
|
pub(crate) direction: Vector3<T>,
|
|
}
|
|
|
|
pub fn construct_primary_rays(
|
|
(width, height): (usize, usize),
|
|
(pixel_x_coord, pixel_y_coord): (usize, usize),
|
|
cam_to_world_matrix: &Matrix4<f32>,
|
|
focal_length: f32,
|
|
rays_per_pixel: usize,
|
|
) -> Vec<Ray> {
|
|
let mut rays: Vec<Ray> = Vec::with_capacity(rays_per_pixel);
|
|
|
|
//generate all rays for this pixel and add them to the rays vector
|
|
for _ in 0..rays_per_pixel {
|
|
rays.push(generate_single_primary_ray(
|
|
(width, height),
|
|
cam_to_world_matrix,
|
|
focal_length,
|
|
pixel_x_coord,
|
|
pixel_y_coord,
|
|
//no noise
|
|
0.0f,
|
|
0.0f,
|
|
));
|
|
}
|
|
|
|
rays
|
|
}
|
|
|
|
fn generate_single_primary_ray(
|
|
(buffer_width, buffer_height): (usize, usize),
|
|
cam_to_world_transform: &Matrix4<f32>,
|
|
focal_length: f32,
|
|
u: usize,
|
|
v: usize,
|
|
u_offset: f32,
|
|
v_offset: f32,
|
|
) -> Ray {
|
|
//calculate the ray direction and translate it to world space
|
|
let direction_camera_space: Vector4<f32> = Vector4::new(
|
|
u as f32 - (buffer_width as f32 / 2.0) + u_offset,
|
|
v as f32 - (buffer_height as f32 / 2.0) + v_offset,
|
|
focal_length,
|
|
0.0,
|
|
);
|
|
|
|
let direction_world_space = cam_to_world_transform * direction_camera_space.normalize();
|
|
|
|
Ray {
|
|
origin: cam_to_world_transform.w.truncate(),
|
|
direction: direction_world_space.truncate().normalize(),
|
|
}
|
|
}
|