光线追踪多个对象最近距离计算

Raytracing multiple objects closest distance computation

提问人:Xscreade 提问时间:5/1/2023 最后编辑:wohlstadXscreade 更新时间:5/2/2023 访问量:55

问:

我正在用 c++ 编写光线追踪器,但我无法弄清楚如何正确绘制多个对象(这里现在是球体)。我在设定的屏幕分辨率的每个像素上投射光线,并针对每条光线迭代场景中的每个对象。代码如下:

for (unsigned int y = 0; y < m_resY; y++) {
    for (unsigned int x = 0; x < m_resX; x++) {
        if (x % 2 == 0 && y % 2 == 0) {
            m_buffer[y * m_resX + x].color = Color(-1, -1, -1);
            continue;
        }
        double u = (double(x) * 2 / (m_resX - 1)) - 1;
        double v = (double(y) * 2 / (m_resY - 1)) - 1;
        RayTracer::Ray r = m_camera.ray(u, v);
        double closestDist = std::numeric_limits<double>::max();
        for (auto &obj : m_objects) {
            if (obj->hits(r)) {
                if (std::abs(r.getHit().dist) < std::abs(closestDist)) {
                    closestDist = r.getHit().dist;
                    r.setClosestObj(obj.get());
                    r.getClosestHit() = r.getHit();
                }
            } else if (m_buffer[y * m_resX + x].computed == false) {
                m_buffer[y * m_resX + x].color = Color(50, 50, 50);
            }
        }
        if (r.getClosestObj() != nullptr) {
            m_light->computeLight(r, *r.getClosestObj(), m_objects);
            m_buffer[y * m_resX + x].color = r.m_finalColor;
            m_buffer[y * m_resX + x].computed = true;
        }
    }
}

这是命中方法:

bool Sphere::hits(Ray &ray) const
{
    Math::Vector3<double> ocp = ray.m_origin - m_center;
    Math::Vector3<double> oc = Math::Vector3<double>(ocp.x, ocp.y, ocp.z);

    double a = ray.m_direction.dot(ray.m_direction);
    double b = 2.0f * oc.dot(ray.m_direction);
    double c = oc.dot(oc) - m_radius * m_radius;
    double discriminant = b * b - 4.0f * a * c;

    if (discriminant < 0)
        return false;
    ray.getHit().dist = (-b - sqrt(discriminant)) / (2.0f * a);
    ray.getHit().hitPosition = ray.m_origin + ray.m_direction * ray.getHit().dist;
    ray.getHit().normal = ray.getHit().hitPosition - m_center;
    return true;
}

和输出:

enter image description here

我试图归一化光线方向矢量,使用判别式作为比较,将 [-b - sqrt ...] 与 [-b + sqrt ...] 进行比较,但仍然是同样的问题

C++ 数学 图形 光线追踪

评论

1赞 Laurent Jospin 5/1/2023
您编写代码时缺少的一件事是检查命中是在摄像机前还是摄像机后。另外,是的,为了使您的代码正常工作,您需要确保m_direction具有规范 1,您如何确保?
0赞 Xscreade 5/2/2023
命中不能在相机后面,因为光线是从相机发射的(它的 Z 方向始终是 -1),是的,光线m_direction在创建时会归一化
0赞 Stef 5/2/2023
你好!在 stackoverflow 上提问时,如果您的问题中包含代码,强烈建议将该代码设置为最小的可重现示例。在这里,除了显示蓝球之外,显示红球似乎也存在问题。一个非常相关的信息是:红球应该在蓝球的后面还是在前面?我们不知道,因为这两个球的位置不包含在您包含在问题中的代码中。
0赞 Laurent Jospin 5/2/2023
从您的代码中,我了解到 ray.getHit().dist 可以是负数或正数,在这种情况下,命中可以在镜头前或镜头后。

答:

0赞 Xscreade 5/2/2023 #1

我发现了一些有效的东西,以某种方式反转了物体的 z(深度位置),正确计算了距离。

我的相机在 0 0 0 中,以 z = 1 拍摄光线,对象在 -1 中,现在对象在 1 中,它产生了正确的渲染。