阴影并未全部显示在我用 C 编写的简单光线追踪器中

问题描述 投票:0回答:1

这是我的第一个问题,所以我希望我能做对。 我目前正在为一个学校项目用 C 语言编写一个简单的光线追踪器。 该程序似乎按预期运行,因为它使用学校提供的库在窗口上显示像素来显示基本形状(平面、球体和圆柱体)。

我确实有一个奇怪的问题,几天后我仍然无法弄清楚。

这是一个简单的场景,可以正确显示一盏灯(始终只有一盏灯)、一个球体和一个平面: img1

但是事情变得有点奇怪。

当我向场景中添加一个圆柱体时,我有圆柱体的投影阴影,但不再有球体的投影:

img2

这里我们再次看到了圆柱体的阴影,但没有球体:

img1

最后,光线穿过右侧的平面,因此所有形状都应该处于阴影中:

img1

我很难理解这个问题。我还是 C 初学者,尤其是 3D 编程。

从相机创建光线后,我会检查是否找到与场景中任何形状的交叉点:

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

一旦找到交点,我们就会追踪从该交点到光点的另一条光线,并通过相同的函数(shapes_intersect)来确定该交点是否被点亮:

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

这是我无法解决这个问题的主要原因。正确找到了交叉点,我们可以看到形状甚至一些阴影,但由于某种原因,当场景中有圆柱体时,无法检测到平面和球体阴影。

有人知道这里发生了什么吗?

感谢您的宝贵时间。

c recursion 3d geometry raytracing
1个回答
0
投票

没有深入分析或测试,但快速浏览一下:

我在您的 shapes_intersect 函数中没有看到

点击的距离排序
。您应该选择最接近的对象命中,而不是具有最大索引的对象的命中...

由于圆柱体是最后测试的,因此它们具有最高优先级,因此如果您的射线击中任何圆柱体,则忽略任何其他物体的击中...

如果你击中球体(其次进行测试),那么平面将被忽略......

因此,如果您的

hit == true
您应该仅在交点比已选择的交点更近(沿射线方向的符号距离)时更新您的
inter
...

© www.soinside.com 2019 - 2024. All rights reserved.