Chapter 32: Reflection and Refraction

Now that we have shading & shadows in our scene, what else is there other than geometric complexity?

We started with a purely local approximation of shading. By adding shadows, we begin the process of adding global constraints to our system.


What else does light do? Well, for mirror-like surfaces, very shiny surfaces, other part’s of the scene’s geometry is reflected onto those shiny surfaces.

We can model this type of surface reflection for reflective surfaces (e.g. any object with a reflective finish property greater than 0 in our .pov files) by adding color from any geometry intersected by reflected rays.

For some incident ray and normal , the reflection vector is:


You will need to do a recursive ray cast in order to gather reflected color.

Multiply the returned color by the reflection material property.

r // reflection vector
pt // intersection point

reflection_color := raytrace(pt + r * epsilon, r)
total_color := local_color + finish.reflection * reflection_color


When light rays travel between materials they are sometimes bent. This occurs because light travels at different velocities in different media. The velocity of light in some medium is often represented by the index of refraction which is the ratio between the speed of light in that media over the speed of light in a vacuum, c.

Thus if a material has an index of refraction (commonly, “ior”) of 2.0, then light travels at half of c in that media.

The border between two different media with different ior is called an interface. When a light ray passes through an interface between media with different ior, it is bent. This effect is called refraction.

Snell’s Law

Snell’s Law tells us how much light will be bent, given the ior of each media at the interface and the incoming ray angle.

Where is the ior of the first media (where the ray starts), is the ior of the media the ray is entering, and and are the angles of incidence and refraction, respectively. Those angles are between the given vector and the normal of the interface.

In our ray tracers we are going to know , , and . We can find since we know the incident vector (it’s , the direction of our ray). We’ll know and because we know where our ray is coming from and is a material property of the object we are shading.

That leaves as the unknown. Let’s solve for it.


sin is nice, but cos is better - we can write a cosine as a dot product. So let’s use trigonometric identities to change this to something-something cosine!

We have but want so let’s just square our equation and apply the identity.

Great, but we actually want to be able to solve for the transmitted vector itself, not just the angle . The angle would be annoying to use.

Let’s solve for the vector which is the transmitted, or refracted, vector.

Where do we start? Well, since we have an equation for let’s try to right something in terms of that. Since is a normalized vector we can write it simply in terms of two orthonormal basis vectors.

This is a very general form that works for any angle and related basis vectors. We want to use , but then we need to figure out what and are. Well, is the opposite of the normal but we will need to solve for .

Where can we get more information about ? Well, we still know , so let’s write it in terms of the same basis vectors!

Now solve for

And plug that into our equation for

Let’s get rid of that using Snell’s Law:

We can also cancel out the s!

And now plug in the equation for that we found before:

This is commonly written the other way around so let’s just switch things up, it’ll make it easier to read:

Finally, an equation in terms of s, and we know the angle ! It’s the angle of incidence, so some simple geometry tells us that:

Swap out minus signs or remove them where they don’t matter:


With transparent objects you will intersect the surface both when entering and exiting. For exit refractions, make sure to:

There are two material values that relate to refraction: refraction and filter. filter tell us how transparent the material is (e.g. a value of 1.0 means the object is totally transparent, 0.0 means opaque). refraction is redundant (any transparent material with an index of refraction is refractive) so we will ignore it.