a small path-tracing renderer written in rust. this project follows the structure of ray tracing in one weekend.
the goal of this project is to learn the fundamentals of rendering: vectors, rays, normals, intersections, light scattering, sampling, and camera math — all implemented from scratch with no graphics libraries.
raytracer/
├── cargo.toml
├── src/
│ ├── main.rs
│ ├── lib.rs
│ ├── vec3.rs
│ ├── ray.rs
│ ├── hittable.rs
│ ├── sphere.rs
│ ├── hittable_list.rs
│ ├── camera.rs
│ └── renderer.rs
└── tests/
└── vec3_tests.rs
all rendering logic lives in the library (src/lib.rs).
src/main.rs is just a tiny entrypoint calling raytracer::run().
make sure you have rust and cargo installed:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shclone the project:
git clone https://github.com/ni5arga/raytracer
cd raytracerrender an image in release mode (recommended):
cargo run --release > image.ppmthis produces a file called image.ppm in the project directory.
open image.ppmxdg-open image.ppmconvert image.ppm image.pngall render settings live in src/lib.rs inside run():
let image_width = 400;
let samples_per_pixel = 100;
let max_depth = 50;you can modify:
- image resolution
- number of samples per pixel (reduces noise)
- max recursion depth
- scene geometry (list of spheres)
- camera parameters (in
camera.rs)
to add new spheres:
world.add(Box::new(Sphere::new(Point3::new(0.0, 1.0, -1.0), 0.5)));unit tests live inside the tests/ directory.
run them with:
cargo testthey verify vector math (dot, cross, unit vector, clamp, and random sampling).
- a ray is defined as
p(t) = origin + t * direction. - each pixel fires many rays into the scene.
- for each ray, we check intersections with hittable objects.
- if a ray hits something, it scatters into a random direction.
- each bounce accumulates color while reducing intensity.
- if a ray misses, it blends into a blue sky gradient.
- final pixel color = average of all ray samples.
mit license