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

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: sphere2

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?

Source code: https://gist.github.com/harieamjari/6297a35400460edbabbd8e39720ed0f5

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);
c = dot(sphere_normal , sphere_normal ) - sphere_radius*spheres_radius;
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) -1,0,0 light_source (0,0,-1) 0,0,-1


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.