I started a ray tracing project in Python. I made a CUDA kernel and a trace() function for each pixel. It works perfectly when calculating intersections, shadows and lambert shading, however when I introduce a reflection from the surface of a sphere I get a 'band' around the edge of the projected sphere disk and I cannot figure out why.
Image results: https://i.sstatic.net/XgFI5.jpg
My reflection algorithm:
- Find point P of the intersection.
- Find normal vector N at the intersection with C being the sphere center:
N = P - C
N = N / norm(N)
- Find reflection vector R using (where D is the original ray direction:
R = D - 2 * (D * N ) * N
R = R / norm(R)
- Shift point P along R a little bit (to avoid reflection acne, adding this didn't solve the problem)
P = P + 1e-4 * R
- Call the ray trace function (only one more time) again as:
color_refl = trace(ray_origin=P, ray_direction=R)
- Add the reflected color using:
color = color + color_refl * reflect_intensity
Notes:
- Between step 2 and step 3 I calculate the Lambert shading which works quite well.
- Reflections that bounce off a plane work perfectly.
- I use a CUDA kernel which does not support recursive function calls, so I made another trace function with a different name that doesn't calculate reflections. (that's why there is only one reflection call)
Here is the source code for the trace and reflection trace functions: https://github.com/Speterius/ray_tracing/blob/master/cuda_ray_tracing.py