This is my first question, so I hope I do it right. I am currently writing a simple raytracer in C for a school project. The program seems to be functioning as intended as it displays the basic shapes (planes, spheres and cylinders) using a library provided by the school to display the pixels on a window.
I do have an odd issue, which after several days I still cannot figure out.
Here is a simple scene which displays properly with one light (always only one light), one sphere and one plane:
But then things get a little funky.
When I add a cylinder to the scene, I have the projected shadow of the cylinder, but not the one of the sphere anymore:
Here again, we have the cylinders' shadows, but not the spheres:
And finally here, the light is past the plane on the right and therefore all the shapes SHOULD be in the shades:
I have a hard time wrapping my head around this one. I am still a beginner with C and especially 3D programming.
Once I've created a ray from the camera, I check if I find an intersection with any shape in my scene:
bool shapes_intersect(t_shape *shapes, t_inter *inter)
{
bool hit;
int i;
hit = false;
i = 0;
while (i < shapes->plane_nb)
{
if (hit_pl(inter, &shapes->planes[i]))
hit = true;
i++;
}
i = 0;
while (i < shapes->sphere_nb)
{
if (hit_sp(inter, &shapes->spheres[i]))
hit = true;
i++;
}
i = 0;
while (i < shapes->cyl_nb)
{
if (hit_cy(inter, &shapes->cylindres[i]))
hit = true;
i++;
}
return (hit);
}
And once an intersection is found, we trace another ray from that intersection to the point of light and go through the same function (shapes_intersect) in order to determine if that intersection is lit or not:
static bool in_shadow(t_data *d, t_inter inter, t_vec light)
{
t_inter shadow;
shadow.ray.pos = vecs_multf(inter.normal, 0.0001);
shadow.ray.pos = vecs_add(inter.pos, shadow.ray.pos);
shadow.ray.axe = normalized(vecs_sus(light, shadow.ray.pos));
shadow.ray.tMAX = RAY_T_MAX;
return (shapes_intersect(&d->shapes, &shadow));
}
void ray_trace(t_data *d)
{
int x;
int y;
t_ray ray;
t_inter inter;
uint32_t curr_pixel;
bool visible;
x = 0;
y = 0;
while ((uint32_t)x < d->img->width)
{
while ((uint32_t)y < d->img->height)
{
ray = make_ray(&d->cam, vec2_init(((2.0f * x) / d->img->width) - 1.0f, ((-2.0f * y) / d->img->height) + 1.0f));
inter = inter_cpy_ray(&ray);
if (shapes_intersect(&d->shapes, &inter))
{
curr_pixel = color_prod(inter.rgb, color_scale(d->amb.rgb, d->amb.ratio));
visible = !in_shadow(d, inter, d->lum.pos);
curr_pixel = color_add(curr_pixel, visible * color_comp(&d->lum, inter));
mlx_put_pixel(d->img, x, y, curr_pixel);
}
else
{
curr_pixel = 255;
mlx_put_pixel(d->img, x, y, curr_pixel);
}
y++;
}
y = 0;
x++;
}
Which is the main reason I cannot wrap my head around this problem. The intersections are properly found, we can see the shapes and even some of the shadows, but for some reason the planes and the spheres shadows are not detected when there's a cylinder in the scene.
Would anybody have an idea of what is going on here?
Thank you for your time.