# Raytracer pseudocode

Here’s the complete version of the pseudocode developed in the raytracing chapters:

``````CanvasToViewport(x, y) {
return (x*Vw/Cw, y*Vh/Ch, d)
}

ReflectRay(R, N) {
return 2*N*dot(N, R) - R;
}

ComputeLighting(P, N, V, s) {
i = 0.0
for light in scene.Lights {
if light.type == ambient {
i += light.intensity
} else {
if light.type == point {
L = light.position - P
t_max = 1
} else {
L = light.direction
t_max = inf
}

continue

# Diffuse
n_dot_l = dot(N, L)
if n_dot_l > 0
i += light.intensity*n_dot_l/(length(N)*length(L))

# Specular
if s != -1 {
R = ReflectRay(L, N)
r_dot_v = dot(R, V)
if r_dot_v > 0
i += light.intensity*pow(r_dot_v/(length(R)*length(V)), s)
}
}
}
return i
}

ClosestIntersection(O, D, t_min, t_max) {
closest_t = inf
closest_sphere = NULL
for sphere in scene.Spheres {
t1, t2 = IntersectRaySphere(O, D, sphere)
if t1 in [t_min, t_max] and t1 < closest_t
closest_t = t1
closest_sphere = sphere
if t2 in [t_min, t_max] and t2 < closest_t
closest_t = t2
closest_sphere = sphere
}
return closest_sphere, closest_t
}

TraceRay(O, D, t_min, t_max, depth) {
closest_sphere, closest_t = ClosestIntersection(O, D, t_min, t_max)

if closest_sphere == NULL
return BACKGROUND_COLOR

# Compute local color
P = O + closest_t*D  # Compute intersection
N = P - closest_sphere.center  # Compute sphere normal at intersection
N = N / length(N)
local_color = closest_sphere.color*ComputeLighting(P, N, -D, sphere.specular)

# If we hit the recursion limit or the object is not reflective, we're done
r = closest_sphere.reflective
if depth <= 0 or r <= 0:
return local_color

# Compute the reflected color
R = ReflectRay(-D, N)
reflected_color = TraceRay(P, R, 0.001, inf, depth - 1)

return local_color*(1 - r) + reflected_color*r
}

for x in [-Cw/2, Cw/2] {
for y in [-Ch/2, Ch/2] {
D = camera.rotation * CanvasToViewport(x, y)
color = TraceRay(camera.position, D, 1, inf)
canvas.PutPixel(x, y, color)
}
}``````

And here’s the scene used to render the examples:

``````viewport_size = 1 x 1
projection_plane_d = 1

sphere {
center = (0, -1, 3)
color = (255, 0, 0)  # Red
specular = 500  # Shiny
reflective = 0.2  # A bit reflective
}
sphere {
center = (-2, 1, 3)
color = (0, 0, 255)  # Blue
specular = 500  # Shiny
reflective = 0.3  # A bit more reflective
}
sphere {
center = (2, 1, 3)
color = (0, 255, 0)  # Green
specular = 10  # Somewhat shiny
reflective = 0.4  # Even more reflective
}
sphere {
color = (255, 255, 0)  # Yellow
center = (0, -5001, 0)
specular = 1000  # Very shiny
reflective = 0.5  # Half reflective
}

light {
type = ambient
intensity = 0.2
}
light {
type = point
intensity = 0.6
position = (2, 1, 0)
}
light {
type = directional
intensity = 0.2
direction = (1, 4, 4)
}``````