簡體   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