Skip to content

librity/weekendrt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

77 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

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