1

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 '>' : Tree Mountains

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?

3
  • If your info is really declared as double info[2][3] in the calling code, then info[2][0] is out of bounds. Also, it seems quite strange that you store the maximum distance in the z buffer instead of the minimum. Why does a ray tracer need a Z buffer anyway? Commented May 20, 2016 at 11:17
  • interjay: Maybe my z-buffer method is wrong. Thanks for the info[2], i didn't even realized until now. Fixed this but didn't change anything for my problem. Commented May 20, 2016 at 11:23
  • btw Y+ direction down is common in computer graphics due to gfx HW architecture (remmnant from scan line manner of gfx data transfer and visualization like CRT) Commented May 20, 2016 at 13:36

1 Answer 1

2

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;
}
Sign up to request clarification or add additional context in comments.

6 Comments

What i was doing is that if my z-buffer check function return 0 thus the point is closer to my camera than the one before so I had to display it. So with your technique, i should save the distance of my last displayed pixel and check if my current one is inferior to it ?
Not your last displayed pixel, your current pixel you have to draw. You set a value (distValue) to infinite. Then you check to all intersected triangle which one is the nearest thanks to distValue and your check distance function. Once the test is complete, calculate the color with the nearest triangle intersected.
So I have to find in my linked list of triangles which one is the closest by calculating his intersection point with my ray and comparing it to my current lastdist ? Your technique seems to be time consumming as for exemple, one of my .obj as over 200000+ triangles.
Sure it does, a ray tracer is not powerful, this is why it's very long to make a picture. Software like blender or Maya use tricks to maximize speed, like AABB all objects (a must in raytracer) and/or make triangle/objects octree in space before intersection calculation(powerful technique). We cannot do real time raytracer because of that ! My best one calculate for a couple of seconds a scene containing triangles object, cubes and spheres, only by CPU with ray recursion whereas my first try tooks a couple of minutes.
I have switched to your technique. Worked great for the tree but having some weird results for the moutains. Trying others scenes and keeping you up-to-data. Thanks again !
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.