8000 GitHub - deirdresm/RayTracer: Note: Currently on Chapter 9. Ray Tracer from Jamis Buck's TDD RayTracer Challenge book.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

deirdresm/RayTracer

Repository files navigation

RayTracer

For those who don't know about this book, it's a test-driven development approach to writing a ray tracer. Unlike most programming books, it tells you design principles and lays out what the tests should be like, but pseudocode rather than specifying a language. So language choice is personal, and I chose Swift.

Many of the various projects for Swift are largely UI based, but Swift is a general-purpose language, so I wanted to try a project that wasn't UI based to get a feel for using the language in a different way.

It's been a (ObiWan voice) long time since I've done significant geometry work. I've always had an interest in geometry ever since my mom got me Cundy and Rollett's book Mathematical Models to placate me when I had an unfortunate math teacher, but I never went as far as I could have with it.

Project Goals

  1. Use Swift to its advantage. Small example: for dot producs, I defined the unary operator • rather than naming the function something with the word "dot." Similarly, for cross products, defined unary operator × rather than a named function.
  2. Learn stuff! This isn't intended as a be-all, end-all ray tracer, but learning the principles of something I never happened to do before.
  3. Render cool things! One of my thoughts about things I'd like to render after finishing the book, would be things like this Haramis swirly volume knob or this multichrome guitar.
Volume knob Multichrome guitar

One Motivation for Doing This

In 2020, I was sick with Covid (and long Covid) most of the year. During the active phase of the illness, I would sometimes see rooms change what Platonic solid they were. While I was walking, typically. (This is called Alice in Wonderland Syndrome and has been associated with both viruses and migraines, and guess what I had both of?)

Anyhow, I thought it would be interesting to be able to visually model it because it's hard for other people to envision what I experienced, especially when I talk about walls sliding away. That was a couple of weeks of some very disorienting spacial perceptions.

Current Status

Just finished Chapter 8 (shadows).

About to start Chapter 9, Planes.

Chapter 9, Planes

In this chapter, the first step is extracting what's common about shapes into a Shape class (though, as Buck notes, use the analogous concept in the language of choice.)

I'd already made Shape a protocol, which I think fits the bill; I called a generic non-abstract instance SampleShape. That'll be used for testing aspects of how the protocol works.

Chapter 8, Shadows

Spheres with shadows, oh my!

Scene With Spheres, Shadow Edition

Chapter 7, Scenes

Let's put some spheres together, shall we? Note: these are all spheres, including the three walls.

Scene With Spheres

Chapter 6, Light and Shading

Your basic sphere with light and…less light. (Shadows are chapter 8.)

First Sphere

Chapter 5, Ray-Sphere Intersections

This book was basically easy until Chapter 5, because the visualization of the concepts got ahead of me fairly early on. What I struggled with at first was why a sphere's intersection with a ray should be a float, not a point.

Then I realized that, while I'd been thinking about it from the sphere's POV, it's really where along the ray that point is, and you only need a floating point number to represent that (given that there's already a known direction and origin).

I read the intersection calculations several times, as well as some other implementations, and finally decided to just literally transcribe the book's description into Swift. Voila!

Transformations and translations

Want to translate your sphere away from the ray? That’s just the same as translating the ray away from the sphere, in the opposite direction […].

sounds of brain matter splattering

I'm so used to thinking of spatial things being (relatively) fixed that the idea of different things being in different spaces and perceptions suddenly, just to make calculation easier, is a real mindbender.

Intersections, a set of

In reading, it seems that a lot of people have interpreted [Intersection] to be a property of the Intersection struct (or class), where I think it more properly should be attached to the ray. It's what the ray hit, right?

Also, I see no reason (at this point) not to make it a set, which can be filtered pretty easily. Though…that could break the tangent special case (where there is one hit on a sphere instead of two). For that reason, I'm going to make it an array.

So, for the tests relating to multiple intersections, I'm going to add a ray where there wasn't already one.

I'd previously called the t-value of Intersection distance, so I'm keeping that.

Notes and ToDo

  1. Rotated clock example from chapter 4 is rotated and upside-down, which I'd never have noticed if I hadn't used different colors for each hour marker. :P

Other Implementations

It was cool to have a question about a detail I wasn't certain about and see implementations in so many other languages. Here are a few:

Each of us made some different design choices, which are also interesting.

E.g., I made Tuple a class with Point and Vector inheriting from it, but @sbehnke made Tuple a struct, with no separate Point or Vector, just Point and Vector funcs within the Tuple class.

About

Note: Currently on Chapter 9. Ray Tracer from Jamis Buck's TDD RayTracer Challenge book.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

0