Bave
AABB юзайте, будет в разы быстрее. Отрендерить пару тройку false-positives будет дешевле
OBB у меня тоже медленный (~в 10 раз медленнее сфер): >10 ms без оптимизаций, с SSE - 4.63 ms, с многопоточностью в 4х потоках - 2 ms. Но это для 100к объектов цифры.
как минимум - можно по расстоянию выбирать алгоритм попроще.
>1.3 ms - это у меня получается на GTX 750-ой
И это только для камеры я так понимаю. Еще тени и отражения.
И это только для камеры я так понимаю.
Да, только основная камера.
Я как появится время сделаю тесты, чтобы выполнялся только frustum culling посмотрю на результат....
Bave
>Как то прифигел от цифр:
100k Spheres, SSE, Multithreaded = 0.1 ms !
если сделать BVH tree - то еще интересней станет
_Wizard_
Неплохо бы в статье отразить такой факт http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm, ведь многие имплементации фрустум куллинга не учитывают это.
dmikos
хороший момент да
но - это редкий случай, обрабатывать который дорого
проще отрисовать эти пару объектов
у нас в Гайдзине используется AABB вместо OBB, как раз по этой причине - кулинг дорогой, дешевле отрисовать пару лишних объектов
_Wizard_
> у нас в Гайдзине используется AABB вместо OBB, как раз по этой причине - кулинг
> дорогой, дешевле отрисовать пару лишних объектов
Э... а можно подробнее в цифрах, цена frustum culling и цена отрисовки пары лишних объектов?
innuendo
Он наверное имеет ввиду то, что aabb более грубый и может неоткуллить некоторые обьекты. Но в целом, более точное отсечение будет дороже, чем не использование oobb
Я тоже попробовал потестить отдельно frustum culling, убрал все лишнее и оставил только его.
Примечание: Я вчера немного ошибся: на 10к объектов вся вычислительная часть у меня выполняется за 0.75 ms, а не за 1.3 ms (но понятно, что это все равно весьма плохо по сравнению с результатами в статье)
Так вот чисто по frustum culling-у (OBB) у меня получилось:
1) 10к объектов - 0.35 ms
2) 15к объектов - 0.5 ms
3) 30к объектов - 0.78 ms
-——————-
100k Spheres, SSE, Multithreaded = 0.1 ms !
Я много чего сегодня проверил и уже был готов ударится в дискуссию каким же образом можно получить результат в 0.1 ms на compute shader-ах, но потом как-то удержался выдать огромный пост отчаяния :)
Вообщем если коротко о проблемах:
1. само по себе чтение \ запись SSBO-шек в compute shader-е обходится чуть ли не дороже чем самом вычисление (например вместо чтения world-матриц из SSBO, я для теста в расчтах просто единичную матрицу использовал и уже получал хороший профит).
2. у нас параллельно с frustum culling-ом идет формирование буферов indirect команд для отрисовки, в самом шейдере кулинга число инстансов подсчитывается например, а это уже атомарный инкримент, т.е. получаем overhead от atoimc операций.
3. получить точно время выполнения командного буфера это уже проблема большая (как минимум синхронизация с хостом дает большую погрешность в большую сторону и есть ещё куча других ньюансов).
Вообщем, если кому-то интересно - я мог быть попробовать описать подробней :)
innuendo
Mira
>Он наверное имеет ввиду то, что aabb более грубый и может неоткуллить некоторые обьекты. Но в целом, более точное отсечение будет дороже, чем не использование oobb
да
Bave
>Так вот чисто по frustum culling-у (OBB) у меня получилось:
>1) 10к объектов - 0.35 ms
>2) 15к объектов - 0.5 ms
>3) 30к объектов - 0.78 ms
странноватые немного цифры - не пропорционально время увеличивается
но выглядит нормально, учитывая что это OBB
у меня правда 1 ms... на 100к OBB, SSE, Multithreaded в 4 потока - это если только кулинг мерить
данные еще переслать нужно на гпу
надо учитывать что у меня синтетические тесты: только кулинг, данные плотно упакованы, не надо ни лоды какие то считать, ни параметры инстансов пересчитывать, анимаций нет, дипы примитивнейшие
>получаем overhead от atoimc операций
а я в своем варианте получаю overhead от геометрических шейдеров
ну кстати тема гпу не раскрыта особо - по хорошему нужно написать OBB тест, компут vs геометрические шейдера, как пересылка данных сказывается
в статье больше про цпу, оптимизации... и они неплохо работают, в 9 раз соптимайзил. Что интересно - одинаково по скорости с ГПУ получилось. Думал ЦПУ будет сильно хуже.
_Wizard_
это примерно как я с нейросетями игрался.
на GPU считается шустрее, но из-за передачи данных туда-сюда выходит тоже самое или даже медленнее.
а вот обучение на GPU выигрывает, так как туда отправляется разово потом долгая катка и возврат.
кстати как вы решаете проблему трансформации AABB ?
с OOB понятно - достаточно трансформировать углы матрицей. с AABB (min max) так делать нельзя - бокс будет инвалидным. трансформация через AABB >> OBB * matrix >> AABB слишком накладно.
не помню уже как решел эту проблему в двигле, но чето парился долго
Mira
Трансформации куда? Не надо никуда трансформировать.. С каждой плоскостью по очереди же проверяют..
Mira
> через AABB >> OBB * matrix >> AABB слишком накладно.
Да ладно, что накладоного то? Там все оптимизируется до двух умножений на матрицу, и сбоки нового AABB.
Вот смотри, обычное умножение вектора на матрицу (я рассмотрю 3*3 случай, 4*4 по аналогии):
vNew.x = v.x*a00 + v.y*a01 + v.z*a02; vNew.y = v.x*a10 + v.y*a11 + v.z*a12; vNew.z = v.x*a20 + v.y*a21 + v.z*a22;
Т.к. в AABB у нас есть min max значения, то вместо полей v у нас может быть только min либо только max.
Мы можем получить 6 столбцов:
vminX = vec3(aabb.min.x*a00, aabb.min.x*a10, aabb.min.x*a20); vminY = vec3( aabb.min.y*a01, aabb.min.y*a11, aabb.min.y*a21); vminZ = vec3( aabb.min.z*a02, aabb.min.z*a12, aabb.min.z*a22); vmaxX = vec3( aabb.max.x*a00, aabb.max.x*a10, aabb.max.x*a20); vmaxY = vec3( aabb.max.y*a01, aabb.max.y*a11, aabb.max.y*a21); vmaxZ = vec3( aabb.max.z*a02, aabb.max.z*a12, aabb.max.z*a22);
И из этих столбцов формировать новый AABB.
Mira
про ААББ я про статическую геометрию говорил
большая часть объектов в игре - статика
для статики предрассчитывается очевидно
динамика - вроде OBB, они жирные, ну и пересчитывать AABB не удобно
_Wizard_
> вроде OBB, они жирные
OOB не такие уж и жирные. Хранят их обычно в духе:
struct {
vec3 center;
vec3 size;
mat3 Transform;
}
Что посути и есть AABB:
aabb.min = center-size*0.5 aabb.max = center+size*0.5
И пересчитывается он достаточно быстро (я вон выше написал как). Ну будет там где-то 2x от проверки AABB.