不一致的z缓冲算法

时间:2016-05-20 11:11:16

标签: c algorithm math raytracing

我在C中编写光线跟踪器,我使用z缓冲技术进行深度计算。

但是,在我的z_buffer检查中更改一个符号时,我的结果不一致(参见下面的代码)

/!\在我使用的图书馆中,当你在屏幕上显示时,y会增加!

我的z-buffer检查:

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);                                                                    
     }

我的3D三角交叉功能:

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);
 }

当我使用&#39;&gt;&#39;在我的缓冲区检查中,这里是我在2个不同型号上获得的图片(没有灯光实现):

使用&#39;&gt;&#39; :Tree Mountains

使用&#39;&gt; =&#39; :现在树很好但山的蓝色背景抹去了一切

为什么我的z-buffer检查功能会产生如此大的差异?

1 个答案:

答案 0 :(得分:2)

Raytracer不需要Z-Buffer,因为你测试每个三角形(或其他物体)的光线(每个三角形1个像素),这与Z-Buffer算法相反,你必须测试每个三角形(当前三角形中的像素)

你需要做的是保存一个距离值(只有一个)(我们将它命名为“distLast”)然后测试是交叉点和摄像机之间的距离是最后一次距离保存的。保存三角形数据(或参考)和“distLast”中的距离。

因此,在距离测试结束时,保存的最后一个三角形是你必须计算的交点,所以得到好的颜色并把它放在缓冲区中(绘制像素颜色......)

另外:检查平方距离并且不使用pow功能,因为pow和sqrt对于光线跟踪器的功能非常慢。喜欢:

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;
}