Ray Tracing

~/ ../

About

Thus far, I have only played around with 2D graphics. I have become increasingly curious about how 3D images are created and wanted to better understand the math behind basic 3D rendering. A common way to do this is to build a ray tracer from scratch. It seems it’s almost a right of passage.

Wisdom from Jake the Dog

So, this has no practical value, other than learning. People were writing better ray tracers before I was born. No one needs another ray tracer. If the project inspired even one other person, I would consider that a success. Still, I wanted to have fun with the project and that starts with giving it a fun name.

I am building the project in C and had that on my mind. C-Ray, SeaRay, SeeRay, CRay, Cray, Crayola?

Starting out knowing almost nothing about ray tracing, I thought to myself: “Well, I might as well be doing this with crayons…”

I was hoping that someone else might eventually see it and wanted the name to be friendly and welcoming. Maybe the project name itself could say “hello”, or maybe “hola”? “cRayHola”, that’s it!

A Pale Blue Dot

cRayHola

Goals

  • Learn
  • Minimize External Dependencies
  • Operating System Agnostic
  • CPU Agnostic
  • Unit Tests
  • Multithreaded Ray Processing

Functionality

  • ppm/jpg Image Output
    • Address poor save performance.
  • Phong Reflection Model
  • World Containing Multiple Shapes (in progress)
    • Accept JSON/YAML input to define world and renderer config.
    • Automate multiple renders to generate animations.
  • Texture Mapping
  • Shadows
  • Constructive Solid Geometry
  • Geometric Primitives
    • Sphere
    • Plane
    • Triangle
    • Cube

Implementations

Why C?

gitlab.com/nashimus/crayhola

I have been working on other projects using C and wanted to reinforce the needed skills. Prioritizing efficiency, portability, fast compilation, and learning; it feels like a reasonable fit.

cRayHola - Clone and run Podman build.

Why C++?

gitlab.com/nashimus/crayhola_cpp

It’s been a while since I’ve done anything in C++ and I wanted to pick it back up again. Large C++ projects can be very complex. Starting my own little project limits that complexity considerably. C++ satisfies most of the same requirements I had for C, but has some comforts: function overloads, inheritance, generics, collections… However, there are times when comprehensibility and simplified debugging/profiling is worth the trade off of writing and maintaining more verbose code. Fortunately both approaches are possible in C++.

cRayHola_cpp - Clone and run Podman build.

Insights

Finding Matrix Determinants

Finding the determinant of a matrix can be labor intensive. I started out using cofactor expansion until the matrix was 2x2. I was delighted to find that using the Rule of Sarrus to find the determinant of a 3x3 matrix reduced render duration by as much as 60%.

ppm - portable pixmap file format

Prior to the project, I had not heard of the ppm image file format specification. I was pleased to find that it is very simple. Currently generating large ppm files is not multithreaded and can be quite slow, taking longer than processing the rays and lighting. It is a mild annoyance that I’d like to circle back and address later.

PTRACE and Containers

For security reasons PTRACE access for containers is disabled by default. In order to work around this, I opted to disable the undefined and address sanitizers in the container builds.

Created: