WARNING
Content Under Development
See release page for latest official PDF version.
**Chapter 3: Rays, a simple camera, and background**
The one thing that all ray tracers have is a ray class, and a computation of what color is seen
along a ray. Let’s think of a ray as a function $p(t) = A + t*B$. Here $p$ is a 3D position along a
line in 3D. $A$ is the ray origin and $B$ is the ray direction. The ray parameter $t$ is a real
number (float in the code). Plug in a different $t$ and $p(t)$ moves the point along the ray. Add in
negative $t$ and you can go anywhere on the 3D line. For positive $t$, you get only the parts in
front of $A$, and this is what is often called a half-line or ray. The example $C = p(2)$ is shown
here:

The function $p(t)$ in more verbose code form I call “point_at_parameter(t)”:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
#ifndef RAYH
#define RAYH
#include "vec3.h"
class ray
{
public:
ray() {}
ray(const vec3& a, const vec3& b) { A = a; B = b; }
vec3 origin() const { return A; }
vec3 direction() const { return B; }
vec3 point_at_parameter(float t) const { return A + t*B; }
vec3 A;
vec3 B;
};
#endif
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now we are ready to turn the corner and make a ray tracer. At the core of a ray tracer is to send
rays through pixels and compute what color is seen in the direction of those rays. This is of the
form calculate which ray goes from the eye to a pixel, compute what that ray intersects, and compute
a color for that intersection point. When first developing a ray tracer, I always do a simple camera
for getting the code up and running. I also make a simple `color(ray)` function that returns the
color of the background (a simple gradient).
I’ve often gotten into trouble using square images for debugging because I transpose $x$ and $y$ too
often, so I’ll stick with a 200×100 image. I’ll put the “eye” (or camera center if you think of a
camera) at $(0,0,0)$. I will have the y-axis go up, and the x-axis to the right. In order to respect
the convention of a right handed coordinate system, into the screen is the negative z-axis. I will
traverse the screen from the lower left hand corner and use two offset vectors along the screen
sides to move the ray endpoint across the screen. Note that I do not make the ray direction a unit
length vector because I think not doing that makes for simpler and slightly faster code.

Below in code, the ray $r$ goes to approximately the pixel centers (I won’t worry about exactness
for now because we’ll add antialiasing later):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
#include