Brandon Eleuterio


Learning Rust – Part 6: Multiple Spheres

Brandon Eleuterio

Last time we added some dimension to a sphere. In this go around, we’ll add support for multiple spheres and lay the groundwork for supporting glass spheres.

A Bigger World

So far our one-sphere world is boring. In order to spice things up, we need a way to draw multiple spheres. In order to do this, we:

  1. Create a Hittable Trait (similar to abstract classes in Rust)
  2. Create a collection the holds Hittable objects
  3. Create a Sphere object that uses the Hittable Trait

Now our world can consist of more than one object. We simply add more objects to our HittableList:

let world = HittableList {
    objects: vec![
        Rc::new(Sphere::new(Vec3::new(0.0, 0.0, -1.0), 0.5)),
        Rc::new(Sphere::new(Vec3::new(0.0, -100.5, -1.0), 100.0)),

Memory Optimization

Notice how we wrap each new instance of Sphere with Rc::new(). This creates a reference-counting pointer.

Reference-counting pointers are the Rust equivelant to C++ shared pointers. These allow multiple objects to share a common instance which is a more efficient way of using memory. This will come in handy later on as we add more objects to our drawing.

Two Spheres

And here’s our new world:

A two sphere world

Outward vs Inward

We also added support for outward and inward normals, meaning, a way to draw both the inner and outer surfaces of a three-dimensional object like a glass ball. The code that determines outward versus inward lives in the HitRecord object and is triggered by any onject that implements the Hittable trait.

pub fn set_face_normal(&mut self, ray: &Ray, outward_normal: Vec3) {
    self.front_face = Some(ray.direction().dot(outward_normal) < 0.0);
    self.normal = if self.front_face.unwrap() {
    } else {

Coming Soon

In the next post, we’ll soften the edges of each sphere by adding an anti-aliasing effect. Until then, follow my code on GitHub and follow along in the online book, Ray Tracing in One Weekend.


Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top