A shadow is a visibility test
A diffuse term answers how a surface faces a light. It does not answer whether another object blocks that light. At a surface hit, construct a secondary ray toward the light and ask whether an accepted blocker lies in its interval. Keep this visibility decision separate from the material’s color.
The reference has a directional light, so its shadow ray extends toward an effectively distant source. A point light would need a finite upper distance: an object beyond the lamp must not block it. That is a change to the ray interval contract, not just a different light vector.
The current CPU renderer tests spheres as occluders and retains its ambient contribution in shadow. The plane is not a general shadow caster. Reproduce one sphere shadow before adding another lighting model, then change one object position and predict where the shadow moves.
Use the existing directional-light scene to save an occluded and unoccluded comparison. Sketch the finite interval you would need for a later point-light extension.
