Raytracer in Rust
We ‘SEE’ an object when light rays from a source of light hit the object from different angles and some of the reflected light rays reach the retina of our eyes. The light rays do not care about the geometry of the object it is hitting. The universal laws of physics determine, what the angle of reflection will be after reflecting.
But in computer graphics, we don’t have such universal laws. There is no light source, no object, and no life. There is just a screen that can show a bunch of pixels that have some colors.
In ray tracing, the RAY of light that was supposed to hit the retina is TRACEd back to an object. An object whose geometry is well known, and the reflections are played in reverse order, to reach the virtual source of light in the virtual world.
In this project, I have played with the algos in Ray Tracing in One Weekend by Peter Shirley and implemented them in Rust.
fn make_image()->String{
// empty ppm image
let mut image = String::new();
// image dimensions
let width:u32 = constants::WIDTH as u32;
let height:u32 = constants::HEIGHT as u32;
// camera distance
let focal = Vec3::new(0.0, 0.0, constants::FOCAL_LENGTH);
// setting up camera
let camera = Camera::camera();
// initializing world
let mut world = HittableList::new();
// adding 2 spheres to world
let sphere = Sphere::new(-focal, 0.5);
let sphere2 = Sphere::new(Vec3::new(0.0, -100.5, -1.0), 100.0);
world.add(Box::new(sphere2));
world.add(Box::new(sphere));
image.push_str(&format!("P3\n{} {}\n255\n",width, height));
// image creator
for y in (0..height).rev(){
for x in 0..width{
let u:f32 = (x as f32) / width as f32;
let v:f32 = (y as f32) / height as f32;
// starting a ray from camera to image plane
let ray: Ray = camera.get_ray(u, v);
// calculating the color of pixel where ray hits image plane
let pixel_color = ray_color(&ray, &world, constants::MAX_DEPTH);
// writing pixel value to image
write_color(&mut image, &pixel_color);
}
}
image
}
Drawing function that sends a ray to the world to encounter objects.
-
hello world
“Hello, World!” of graphics. Green goes full on to full off top to bottom. Red goes full on to full off right to left
-
blue lerp
Blue lerping from top to bottom
-
hit_sphere
A wild sphere appears with no depth(thus a circle)
-
hit_sphere_surface_normals
Circle normalises to sphere
-
hittable_lists
More spheres
-
diffuse_material
Adding materials to spheres
-
shadow_acne
Shadows!
-
lambertian_reflection
Shadows and relection(failed attempt)
-
corrected_lambertian_reflection
meh
Will definitely visit again to improve the results.