I'm programming a raytracer in C and I use the z-buffering technique for the depth calculation.
However, I have inconsistent results when changing one sign in my z_buffer check (see code below)
/!\ In the library that I'm using, when you go down on your screen, y increases !
My z-buffer check :
int check_z_buffer(t_rtc *rtc,
double info[2][3], t_bunny_position pos[2])
{
double dist; /* Distance between my intersection point and my camera */
dist = sqrt(pow(info[1][0] - rtc->cam_pos[0], 2) +
pow(info[1][1] - rtc->cam_pos[1], 2) +
pow(info[1][2] - rtc->cam_pos[2], 2));
if (dist > rtc->z_buffer[pos[1].y][pos[1].x]) /* THE PROBLEM COMES FROM THE '>' */
{
rtc->z_buffer[pos[1].y][pos[1].x] = dist;
return (0);
}
return(1);
}
My 3D triangle intersection function :
int intersect(t_rtc *rtc, t_triangles *triangles,
double info[2][3])
{
/* triangle->pos contains the x,y,z of my 3 triangle points */
/* info[0] contains the x,y,z from my ray-launching function */
double all[5][3];
double values[5];
vector(all[0], triangles->pos[1], triangles->pos[0]);
vector(all[1], triangles->pos[2], triangles->pos[0]);
cross(all[2], info[0], all[1]);
values[0] = dot(all[0], all[2]);
if (values[0] > -EPSILON && values[0] < EPSILON)
return (-1);
values[1] = 1 / values[0];
info[1][0] = rtc->cam_pos[0] - (values[1] * info[0][0]);
info[1][1] = rtc->cam_pos[1] - (values[1] * info[0][1]);
info[1][2] = rtc->cam_pos[2] - (values[1] * info[0][2]);
vector(all[3], rtc->cam_pos, triangles->pos[0]);
values[2] = values[1] * dot(all[3], all[2]);
if (values[2] < 0.0 || values[2] > 1.0)
return (-1);
cross(all[4], all[3], all[0]);
values[3] = values[1] * dot(info[0], all[4]);
if (values[3] < 0.0 || values[2] + values[3] > 1.0)
return (-1);
values[4] = values[1] * dot(all[1], all[4]);
if (values[4] > EPSILON)
return (0);
return (-1);
}
When i use a '>' in my buffer check, here's a picture of what i obtain on 2 different models (no light implementation):
Using '>=' : Now the tree is good but the blue background of the mountains erase everything
Why such a big difference coming from my z-buffer check function?
Raytracer doesn't need Z-Buffer because you test a ray for every triangles(or other objects) (1 pixel for every triangles) contrary to Z-Buffer algorithm where you have to test every triangles (pixels in current triangle).
What you have to do is to save a distance value (only one)(we name it "distLast") then test is the distance between intersection and camera is INFERIOR to the last distance save. Save the triangle data (or reference) and the distance in "distLast".
Thus, at the end of the distance test, the last triangle saved is the intersection you have to calculate, so get the good color and put it in the buffer (draw pixel color...)
Also : check the squared distance and don't use pow function, because pow and sqrt are very slow function for raytracer. do like :
dist = (info[1][0] - rtc->cam_pos[0])*(info[1][0] - rtc->cam_pos[0])+
(info[1][1] - rtc->cam_pos[1])*(info[1][1] - rtc->cam_pos[1])+
(info[1][2] - rtc->cam_pos[1])*(info[1][2] - rtc->cam_pos[2]);
// If you have to get the normal distance, then root it
if (dist < distLast*distLast)
{
distLast = sqrt(dist);
}
// Otherwise
if (dist < distLast)
{
distLast = dist;
}