Я работаю над переписыванием raytracer, который я разработал для университета в прошлом семестре, и сталкиваюсь со следующей проблемой: Когда я компилирую и запускаю свой код в Debug, вывод будет таким, как ожидалось
![expected result](https://i.stack.imgur.com/yCRvb.png)
Но когда я включаю более высокие уровни оптимизации, например, "-O2", получается что-то совершенно другое:
![actual result](https://i.stack.imgur.com/tAuxi.png)
И я не уверен, почему это происходит. Я отследил его до кода пересечения сферы
//#pragma GCC push_options
//#pragma GCC optimize("O0")
Intersection Sphere::intersect(const Ray& ray, const float previous) const
{
const auto oc = ray.origin - center_;
const auto lhv = -dot(ray.direction, oc);
const auto discriminant = lhv * lhv - (oc.lensqr() - radius_ * radius_);
if (discriminant < 0.0F)
{
return Intersection::failure();
}
float distance;
const auto rhv = std::sqrt(discriminant);
const auto r = std::minmax(lhv + rhv, lhv - rhv);
if (r.first <= 0.0F)
{
if (r.second <= 0.0F)
{
return Intersection::failure();
}
distance = r.second;
}
else
{
distance = r.first;
}
const auto hit = ray.getPoint(distance);
const auto normal = (hit - center_).normalize();
if (0.0F <= distance && distance < previous - epsilon)
{
return {distance, ray, this, normal, hit};
}
return Intersection::failure();
}
//#pragma GCC pop_options
Если я раскомментирую прагму в режиме релиза, я снова получу ожидаемый результат. Может быть, в моем коде есть неопределенное поведение, которое приводит к этому?
Вы также можете посмотреть здесь, так как минимальный воспроизводимый пример не легко возможен. https://github.com/Yamahari/RayTracer/blob/master/rt/solid/Sphere.cpp
(Вы также можете клонировать репозиторий и построить проект с помощью cmake, в качестве зависимости вам нужен только SFML.
Использовать -DSFML_INCLUDE_DIR = "include_dir" и -DSFML_LIB_DIR = "lib_dir" с библиотекой sfml, скомпилированной с нужным компилятором)