/weekendrt

A simple ray tracer made in a weekend.

Primary LanguageCMIT LicenseMIT

Ray Tracing in One Weekend

norminette License Code size in bytes Lines of code Top language Last commit

A simple ray tracer made in a weekend.


📜 Table of Contents

🧐 About

A plain C implementation of the Weekend Raytracer challenge. I just followed the instructions laid out on the online book:

Title (series): “Ray Tracing in One Weekend Series”
Title (book): “Ray Tracing in One Weekend”
Author: Peter Shirley
Editors: Steve Hollasch, Trevor David Black
Version/Edition: v3.2.3
Date: 2020-12-07
URL (series): https://github.com/RayTracing/raytracing.github.io
URL (book): https://raytracing.github.io/books/RayTracingInOneWeekend.html

🏁 Getting Started

⚙️ Prerequisites

All you need is a shell and a C compiler like gcc or clang.

🖥️ Installing

Just clone the repo and run make:

$ git clone https://github.com/librity/weekendrt.git
$ cd weekendrt
$ make example

A beautiful image should pop out of your terminal like magic.

🎨 Gallery

Rainbow gradient:

Tame Impala's next album cover:

3000+ objects:

Anti-aliasing, 100 samples per pixel:

Dynamic camera:

Defocus blur (a.k.a. Depth of field):

Multiple materials:

and much, much more...

🖼️ Rendering .bmp

ft_libbmp implementation based on:

The best way to write the header is to define a struct, set all the values and dump it straight to the file.

typedef struct {             // Total: 54 bytes
  uint16_t  type;             // Magic identifier: 0x4d42
  uint32_t  size;             // File size in bytes
  uint16_t  reserved1;        // Not used
  uint16_t  reserved2;        // Not used
  uint32_t  offset;           // Offset to image data in bytes from beginning of file (54 bytes)
  uint32_t  dib_header_size;  // DIB Header size in bytes (40 bytes)
  int32_t   width_px;         // Width of the image
  int32_t   height_px;        // Height of image
  uint16_t  num_planes;       // Number of color planes
  uint16_t  bits_per_pixel;   // Bits per pixel
  uint32_t  compression;      // Compression type
  uint32_t  image_size_bytes; // Image size in bytes
  int32_t   x_resolution_ppm; // Pixels per meter
  int32_t   y_resolution_ppm; // Pixels per meter
  uint32_t  num_colors;       // Number of colors
  uint32_t  important_colors; // Important colors
} BMPHeader;

The only values we need to worry about are width_px, height_px and size, which we calculate on the fly; the rest represent configurations and we can treat them as constants for most purposes. We then write the actual contents of the file line-by line, with some padding information.

My bitmap implementation is very lousy and doesn't handle compression. This makes for 1080p files that are over 5 mb big. I transformed all the pictures in the gallery to .png so this README would load faster, but they were all originally generated as .bmp with ft_libbmp.

🤓 Math

🤝 Conventions

  • Bold variables are Euclidean Vectors, like P and C.
  • Normal variables are scalars, like t and r.

☀️ Rays

Given a origin A, and a direction b, the linear interpolation of a line with a free variable t generates a ray P(t):

The scalar t represents the translation of the ray, or how much it need to advance to reach an arbitrary point in its path.

🔮 Spheres

An arbitrary point P is on the surface of a sphere centered in C with radius r if and only if it satisfies the equation:

An arbitrary ray P(t) of origin A and direction b intersects a sphere centered in C if and only if t is a root of:

The quadratic above combines equations (I) and (II), and we can solve for t with the quadratic formula:

🕶️ Ray Reflection

The reflection r of an incident ray v on an arbitrary point with a normal n can be calculated with:

🐌 Ray Refraction - Snell's law

Given an angle of θ of an incident ray R, and the refractive indices of the two surfaces η and η', we calculate the angle θ' of the refracted ray R' with:

The refracted ray R' has a perpendicular component R′⊥ and a parallel component R′∥, which we can calculate with:

🐙 Github Actions

Norminette Github Action by @AdrianWR

☁️ Repos

🏫 References

📚 Docs

📝 Resources

⬇️ Markdown Resources