This is a simple ray tracer written in Rust. It can render scenes with spheres, cubes, planes, and cylinders.
To build the project, run the following command:
cargo buildTo render a scene, run the following command:
cargo run -- [SCENE_NUMBER] > output.ppmWhere [SCENE_NUMBER] is a number from 1 to 4, corresponding to the four different scenes. If no scene number is provided, scene 1 will be rendered by default.
The output will be a .ppm image file.
- Scene 1: A single sphere.
- Scene 2: A flat plane and a cube.
- Scene 3: One of each of all the objects (one cube, one sphere, one cylinder and one flat plane).
- Scene 4: The same as scene 3, but from a different camera position.
To add objects to a scene, you need to modify the scene functions in src/main.rs.
To create a sphere, you can use the Sphere::new function:
let sphere = Sphere::new(center, radius, material);center: AVec3representing the center of the sphere.radius: Af64representing the radius of the sphere.material: AMaterialstruct representing the color of the sphere.
To create a plane, you can use the Plane::new function:
let plane = Plane::new(point, normal, material);point: AVec3representing a point on the plane.normal: AVec3representing the normal of the plane.material: AMaterialstruct representing the color of the plane.
To create a cube, you can use the Cube::new function:
let cube = Cube::new(min, max, material);min: AVec3representing the minimum corner of the cube.max: AVec3representing the maximum corner of the cube.material: AMaterialstruct representing the color of the cube.
To create a cylinder, you can use the Cylinder::new function:
let cylinder = Cylinder::new(center, radius, height, material);center: AVec3representing the center of the base of the cylinder.radius: Af64representing the radius of the cylinder.height: Af64representing the height of the cylinder.material: AMaterialstruct representing the color of the cylinder.
The resolution of the output image is determined by the ASPECT_RATIO constant and the image_width variable in the main function in src/main.rs.
const ASPECT_RATIO: f64 = 4.0 / 3.0;let image_width = 800;
let image_height = (image_width as f64 / ASPECT_RATIO) as i32;To change the resolution, you can modify image_width and ASPECT_RATIO.
The brightness of the objects is determined by the color field of the Material struct. The color is a Vec3 where each component (x, y, z) corresponds to the R, G, and B values of the color, respectively. The values range from 0.0 to 1.0.
To make an object dimmer, you can reduce the values of the color vector. For example, to make a red object dimmer, you can change Vec3::new(1.0, 0.0, 0.0) to Vec3::new(0.5, 0.0, 0.0).
The position of the light source is defined in the ray_color function in src/main.rs.
let light_pos = Vec3::new(-10.0, 10.0, -10.0);To change the position of the light, you can modify the values in this Vec3.
The camera is set up in each scene function. To move the camera, you need to modify the arguments passed to the Camera::new function:
let cam = Camera::new(lookfrom, lookat, vup, vfov, aspect_ratio);lookfrom: AVec3representing the position of the camera.lookat: AVec3representing the point the camera is looking at.vup: AVec3representing the "up" direction for the camera.vfov: Af64representing the vertical field of view in degrees.aspect_ratio: Af64representing the aspect ratio of the image.