Ray Tracing 006Surface Normals


  • Added a surface normal to shade the sphere.
  • Updated to visualize the normals with a color (normal) map.
  • Updated to return the ray-sphere intersection point and map the normal unit vector to the RGB color components.

The sphere I added last time was rendered as a flat red circle. Here I'm going to add a surface normal to shade the sphere.

Surface normals are used for several purposes in graphics, primarily for lighting. A surface normal is a vector that is perpendicular to the surface at a given point. This vector can either point outward or inward. They usually point outward by convention, but inward pointing normals can be useful, for example, to distinguish between solid spheres and spherical bubbles.

The surface normal for a sphere is in the direction from the center through the hitpoint, minus the center.


The scene has no lights yet, but we can visualize the normals with a color map (see also Normal mapping. Assume N is a unit length vector so that each component is between -1 and 1. Map each component to the range from 0 to 1, and then map x,y,z to r,g,b.

Click to view C++ source code

The hit_sphere() function is no longer just returning whether or not the sphere was hit by the ray. Now it's returning the hitpoint needed to compute the normal. That is, the parameter t where p(t)=A+tBp(t)=A+tB intersects with the sphere. The return value changes from bool to a float.

If the ray misses the sphere (discriminant < 0) we return -1. This value for t won't affect the visible area because it lies behind the camera.

If the ray hits the sphere, we'll return the smallest t, the closest hitpoint.

The color() function needs to be updated to calculate and visualize the normal:

Click to view C++ source code

Javascript and Canvas

Here's the example in Javascript.


Figure RT006: Simple canvas image with surface normals

Click to view Javascript source code