Сетчатая конструкция с DDA трансверслом не работает должным образом в Ray TracerC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Сетчатая конструкция с DDA трансверслом не работает должным образом в Ray Tracer

Сообщение Anonymous »

К настоящему времени я реализовал небольшую оптимизацию, внедряющую ограничивающие ящики для сетчатого объекта (если луч не нажимает на Bbox, он не будет проверять треугольники внутри Bbox). Чтобы оптимизировать его дальше, я хотел бы также поместить сетчатые объекты в сетку, которая еще больше снизила бы не необходимые тесты Ray-TRI. Я реализовал структуру сетки, используя алгоритм цифрового дифференциального анализатора, который я обнаружил в литературе очень популярной и легко реализовать. src = "https://i.sstatic.net/cloxtark.png"/>
Код для сетки-
#include
#include

#include "grid.h"

bool Cell::hit(const Ray& r_in, const Interval& ray_t, HitRecord& hitrec, Grid& g) const {
HitRecord temp_rec;
bool hit_anything{ false };
float closest_so_far{ ray_t.max() };
for (const auto& tri : _triangles) {
g._logger->add_ray_tri_int();
if (tri.hit(r_in, temp_rec) && temp_rec.get_t() < closest_so_far) {
g._logger->add_true_ray_tri_int();
hit_anything = true;
closest_so_far = temp_rec.get_t();
hitrec = temp_rec;
temp_rec = HitRecord();
}
}

return hit_anything;
}

bool Grid::_dda(const Ray& r_in, const Interval& ray_t, HitRecord& hitrec) {
/**
* @brief: digital differential analyser algorithm to compute
* ray path and intersections through the grid
*/
Vec3f ray_dir{ r_in.direction() };
Vec3f ray_inv_dir{ r_in.inv_dir() };
Vec3f ray_origin{ r_in.origin() };
Vec3f Ocell_Oray{ (ray_origin + ray_dir * hitrec.get_t()) - _bbox.bounds()[0] };
uint32_t cell[3];
// compute ray path through the grid
for (uint32_t i = 0; i < 3; ++i) {
cell = std::clamp(Ocell_Oray / _cellsize, 0, _n - 1);
if (ray_dir < 0) {
_dt = -_cellsize * ray_inv_dir;
_t = hitrec.get_t() + (cell * _cellsize[i] - Ocell_Oray[i]) * ray_inv_dir[i];
} else {;
_dt[i] = _cellsize[i] * ray_inv_dir[i];
_t[i] = hitrec.get_t() + ((cell[i] + 1) * _cellsize[i] - Ocell_Oray[i]) * ray_inv_dir[i];
}
}

// get first hitted cell
for (uint32_t i = 0; i < 3; ++i) {
float id = (r_in.origin()[i] + ray_dir[i] * hitrec.get_t() - _bbox.bounds()[0][i]) / _cellsize[i];
auto idx = std::clamp(id, 0, _n[i] - 1);
_cell_index[i] = idx;
}

// check if the ray hits a triangle in the cells traversed by the ray
float t{};
bool hit{ false };
while(!_check_boundary()) {
auto min_idx{ std::distance(_t, std::min_element(_t, _t + 3)) };
uint32_t cell_idx{ std::clamp(_cell_index[0] + _cell_index[1] * _n[0] + _cell_index[2] * _n[0] * _n[1], 0, _cells.size() - 1) };

hit = _cells[cell_idx].hit(r_in, ray_t, hitrec, *this);
t = _t[min_idx];
if (ray_dir[min_idx] < 0) {
--_cell_index[min_idx];
} else {
++_cell_index[min_idx];
}

if (hit && hitrec.get_t() < t) {
break;
}
_t[min_idx] += _dt[min_idx];
}

return hit;
}

bool Grid::_check_boundary() const {
/**
* @brief: checks if a ray exited the grid. Since
* the indexes are uint32_t, if the ray exits backwards (negative indices),
* the check is still working since the index will overflow
*/
bool out_of_bounds_x{ _cell_index[0] >= _n[0] };
bool out_of_bounds_y{ _cell_index[1] >= _n[1] };
bool out_of_bounds_z{ _cell_index[2] >= _n[2] };

return out_of_bounds_x || out_of_bounds_y || out_of_bounds_z;
}

void Grid::_insert_triangles() {
for (const auto& tri : _triangles) {
// convert to cells coordinates
Vec3f min = (tri.get_bbox().bounds()[0] - _bbox.bounds()[0]) / _cellsize;
Vec3f max = (tri.get_bbox().bounds()[1] - _bbox.bounds()[0]) / _cellsize;

auto x_min = std::clamp(min.x(), 0, _n[0] - 1);
auto x_max = std::clamp(max.x(), 0, _n[0] - 1);
auto y_min = std::clamp(min.y(), 0, _n[1] - 1);
auto y_max = std::clamp(max.y(), 0, _n[1] - 1);
auto z_min = std::clamp(min.z(), 0, _n[2] - 1);
auto z_max = std::clamp(max.z(), 0, _n[2] - 1);

for (uint32_t z = z_min; z
Создайте сетку для сетчатого объекта Bbox, следующей за эвристикой, предложенной в этой статье для разрешения сетки (то есть в зависимости от некоторого дополнительного параметра лямбда, которая делает разрешение больше или меньше, и, действительно, изменяя это, я вижу некоторые различия в конечном результате, хотя все еще неправильно). и в соответствии с какими клетками он перекрывается, треугольник вставляется в ячейку.>

Подробнее здесь: https://stackoverflow.com/questions/795 ... ray-tracer
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»