繁体   English   中英

如何在 C++ 中进行线程安全的光线投射?

[英]how to make thread safe raycasting in C++?

我正在用 C++ 实现简单的平面光线投射,我使用 OpenMP 进行多线程处理。
这是遍历所有像素并计算交点的函数:

 #pragma omp parallel for num_threads(std::thread::hardware_concurrency())
 for (int x = 0; x < camera_.GetWidth(); x++)
 {
    for (uint32_t y = 0; y < camera_.GetHeight(); y++)
    {
      Ray ray(camera_.GetPosition());
      ray.SetDirection(GetDirection(glm::vec2((2.0f * x) / camera_.GetWidth() - 1.0f, (2.0f * y) / camera_.GetHeight() - 1.0f)));

      cogs::Color3f temp = cogs::Color3f(0, 0, 0);

      for (uint16_t p = 0; p < models_.size(); p++)
      {
        //mutex.lock();
        if (models_.at(p)->Intersection(ray))
        {
          ray.SetParamT(models_.at(p)->GetDistanceT());
          temp = models_.at(p)->GetColor() * (camera_.GetLightEnergy() / ray.GetParamT());
        }
        //mutex.unlock();
      }
      renderer.SetPixel(x, y, temp );
    }
  }  


bool Plane::Intersection(Ray &ray)
{

  float dot = glm::dot(ray.GetDirection(), normal_);

  if (dot == 0.0f)
  {
    return false;
  }

  float t = glm::dot(reference_ - ray.GetOrigin(), normal_) / dot;

  if (t <= 0.0001 || t > ray.GetParamT())
  {
    return false;
  }

  SetDistanceT(t);

  return true;
}

结果如下:
光线投射

正如您所看到的,一些像素被混淆了,但是如果我取消注释互斥锁并从此代码解锁,则结果是正确的,但与不使用 pragma omp 相比,计算时间更长

知道如何使这个线程更安全吗? 当我开始时,几乎一半的像素被混淆了,然后在我的自定义类中,我将每个变量添加为私有并创建了 getter 和 setter,这有帮助,但仍然不完全正确

编辑:基于@Jérôme Richard 建议的更新代码并添加了交集代码

调用一个名为bool Plane::Intersect(Ray &) ,除了确定是否存在交集之外,该方法还会对Plane 对象进行变异,然后将该变异的结果从Plane对象中拉出,同时希望它在与此同时,另一个线程可能是您的问题(或至少是其中一个),而且不是很好的软件工程。

我建议完全摆脱整个SetDistanceT / GetDistanceT功能。 只需返回与直接检查相交的方法的距离,并使该方法的参数和实例均为const

(您如何处理dot为零的情况?在这种情况下您可以返回std::numeric_limits<double>::infinity() ,或者您可以让该方法返回类似std::pair<bool, double> ,或自定义结构,或...)

编辑:当您使用它时,我会在修复它后将此方法声明为float Intersect(const Ray &) const ,以便编译器强制它不会改变光线或平面。 (那里的第二个const表示该方法不会改变它被调用的实例,在这种情况下是与您相交的平面。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM