# Lambertian shading illuminates all the front of a sphere

I've sucessfully implemented a ray tracer from scratch in C and it's marvelous:

The surface normal on this sphere is taken by computing the intersection point, A, and treating this as a euclidean vector with origin, B, the center of the sphere. To normalize it, I first subtracted A with B, yielding C:

C = (Ax-Bx,Ay-By)

From this, it's divided by the magnitude:

N = C/|C|

The illumination is calculated by taking the dot product of N and LIGHT_SOURCE and multiplying it with 255:

if (dot_product<0.0) dot_product = 0.0;
illumination = (unsigned char)(dot_product*255.0);


When I tried setting the light source to (0.0, 0.0, -1.0), it produce something like this:

I expected the shade to be something like it's brighter on the middle and becoming more dimmer on the side.

Anyone know what's causing the problem?

This can be compiled if you already have libpng16.

I think there is a problem with your ray-sphere intersection.

It should go like this

sphere_normal = ray.origin - sphere_center;
b = dot(sphere_normal , ray.normalized_dir);
float disc = b * b - c;

float t = -1.0f;
if(disc >= 0.0f)
t = -b +- sqrt(disc);

if(t >= 0) // means ray intersects...



Check out scratchapixel to understand how I got this. https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection

It turns out, the problem was because the sphere was placed very far away and the radius is too big. This produces a normal with a high value z.

A solution for me was to place the sphere very close to the origin—about z=0.25, and set the radius of the sphere less than z— about r=0.125.

light_source (-1,0,0) light_source (0,0,-1)