Я реализую простую плоскую лучевую трансляцию в 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;
}
вот результат:
Как вы можете видеть, некоторые пиксели перепутаны, но если я раскомментирую блокировку и разблокировку mutex из этого кода, то результаты будут правильными, но это займет еще больше времени. вычислить, чем не используя Pragma omp
Любая идея, как я могу сделать это более потокобезопасным? когда я начинал, почти половина пикселей смешивалась, затем в своих пользовательских классах я добавил каждую переменную как приватную и создал методы получения и установки, что помогло, но все еще не полностью корректно
РЕДАКТИРОВАТЬ: обновление на основе кода на @ Jérôme Richard посоветуйте и добавили код для пересечения