A sphere is given by its center (cx, cy, cz) and its radius, R.

A line segment (ray) is given by its endpoints: P0 = (x0, y0, z0) and P1 = (x1, y1, z1).

To find visible spheres, set P0 = viewer coordinates = (Vx, Vy, Vz) and let P1 run through all the points (x1, y1, 0) where (x1, y1) is in the display area.

Set dx = x1 - x0

dy = y1 - y0

dz = z1 - z0

a = dx*dx + dy*dy + dz*dz;

b = 2*dx*(x0-cx) + 2*dy*(y0-cy) + 2*dz*(z0-cz);

c = cx*cx + cy*cy + cz*cz + x0*x0 + y0*y0 + z0*z0 +

-2*(cx*x0 + cy*y0 + cz*z0) - R*R;

discriminant(a, b, c) = b^2 - 4ac

if discriminant (a, b, c) < 0 no intersection

= 0 ray is tangent to sphere

> 0 ray intersects sphere in two points

The intersection nearest P0 is
given by:

To find the coordinates of the intersection point:

x = x0 + tdx y = y0 + tdy z = z0 + tdz

For each pixel in your image

Use the Ray-Sphere Intersection formulas with

P0 = Viewer = (Vx, Vy, Vz)

P1 = pixel = (x1, y1, 0)

Intersect this ray with each sphere in your scene

If no sphere intersects set the pixel to the background color.

Otherwise set the pixel to the color of the sphere that gave the intersection with the smallest t.

If you do only this, your picture should look like a number of overlapping disks on the plane.

Do step ** 1** but replace the
"Otherwise" with this:

Otherwise

Find the coordinates of the point (x, y, z) on the sphere.

x = x0 + tdx y = y0 + tdy z = z0 + tdz

Find the unit normal vector to the sphere at (x, y, z)

N = ((x - cx)/R, (y - cy)/R, (z - cz)/R)

Find a unit vector from (x, y, z) to the light (Lx, Ly, Lz).

where L' = (Lx - x, Ly - y, Lz - z).

Compute factor = N·L = cos of the angle between N and L.

Set the pixel to (kd*factor*R, kd*factor*G, kd*factor*B).+ (ka*R, ka*G, Ka*B).

where kd is the diffuse-coefficient and ka is the ambient-coefficient. (Try kd = .9 and ka = .1)

If the pixel is background color, use the Ray-Sphere Intersection formulas with

P0 = pixel = (x0, y0, 0)

P1 = Light = (Lx, Ly, Lz)

Intersect this ray with each sphere in your scene.

If there is any intersection, the pixel is in shadow.

Use half (or less) the R, G, B of your background color.

If there is no intersection, use the full R, G, B of the background color.

If the pixel is about to be colored to show a sphere, use the Ray-Sphere Intersection formulas with

P0 = Point on sphere = (x, y, z)

P1 = Light = (Lx, Ly, Lz)

Intersect this ray with **every
other sphere** in your scene.

If there is any intersection, the point is in shadow. Use just the ambient color of the visible sphere.*

(ka*R, ka*G, Ka*B).

If there is no intersection, use the color computed in part ** 2**.

(kd*factor*R, kd*factor*G, kd*factor*B).+ (ka*R, ka*G, Ka*B).

*Though it is not as physically correct, I sometime use

(.5*kd*factor*R, .5*kd*factor*G, .5*kd*factor*B).+ (ka*R, ka*G, Ka*B)

for points on the spheres that are in shadow. The makes the sphere look more rounded.