不一致的 z 缓冲区算法
Inconsistent z-buffer algorithm
我正在用 C 语言编写光线追踪器,我使用 z 缓冲技术进行深度计算。
但是,在我的 z_buffer 检查中更改一个符号时,我的结果不一致(见下面的代码)
/!\ 在我使用的库中,当你在屏幕上向下时,y 会增加!
我的 z 缓冲区检查:
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);
}
当我在缓冲区检查中使用“>”时,这是我在 2 个不同模型上获得的图片(无灯光实现):
使用'>=':现在这棵树很好,但是山脉的蓝色背景抹去了一切
为什么我的 z-buffer 检查功能会有这么大的不同?
Raytracer 不需要 Z-Buffer,因为您为每个三角形(或其他对象)测试一条光线(每个三角形 1 个像素),这与 Z-Buffer 算法相反,在 Z-Buffer 算法中您必须测试每个三角形(当前像素)三角形)。
你要做的是保存一个距离值(只有一个)(我们将其命名为"distLast")然后测试十字路口和相机之间的距离是否低于最后一次保存的距离。在 "distLast" 中保存三角形数据(或参考)和距离。
因此,在距离测试结束时,最后保存的三角形就是你要计算的交点,所以得到好的颜色并将其放入缓冲区(绘制像素颜色...)
另外:检查平方距离并且不要使用 pow 函数,因为 pow 和 sqrt 对于 raytracer 来说是非常慢的函数。喜欢:
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;
}
我正在用 C 语言编写光线追踪器,我使用 z 缓冲技术进行深度计算。
但是,在我的 z_buffer 检查中更改一个符号时,我的结果不一致(见下面的代码)
/!\ 在我使用的库中,当你在屏幕上向下时,y 会增加!
我的 z 缓冲区检查:
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);
}
当我在缓冲区检查中使用“>”时,这是我在 2 个不同模型上获得的图片(无灯光实现):
使用'>=':现在这棵树很好,但是山脉的蓝色背景抹去了一切
为什么我的 z-buffer 检查功能会有这么大的不同?
Raytracer 不需要 Z-Buffer,因为您为每个三角形(或其他对象)测试一条光线(每个三角形 1 个像素),这与 Z-Buffer 算法相反,在 Z-Buffer 算法中您必须测试每个三角形(当前像素)三角形)。
你要做的是保存一个距离值(只有一个)(我们将其命名为"distLast")然后测试十字路口和相机之间的距离是否低于最后一次保存的距离。在 "distLast" 中保存三角形数据(或参考)和距离。
因此,在距离测试结束时,最后保存的三角形就是你要计算的交点,所以得到好的颜色并将其放入缓冲区(绘制像素颜色...)
另外:检查平方距离并且不要使用 pow 函数,因为 pow 和 sqrt 对于 raytracer 来说是非常慢的函数。喜欢:
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;
}