Для примера возьмём сцену с BVH, где корень имеет несколько дочерних узлов-боксов. Или, например, модель юнита описана сферами вокруг головы, тела и конечностей, в которых в свою очередь подсферами или боксами описываются кластеры треугольников. В этом случае может быть быстрее искать пересечение с чётвёрками узлов за раз и избавиться от скалярных операций.
Я написал две тестовые HLSL функции для сферы и прямоугольника: ray_intersects_vectorized. Промерив кол-во dxasm инструкций на выхлопе, получаем 3 для сферы и ~6 для прямоугольника, или 12 и 25 для их чётвёрок.
Рис. 1. Vectorized ray-sphere test
Рис. 2. Vectorized ray-box test
Недостатком оптимизации является то, что у нас в BVH или любой другой структуре не всегда под рукой может быть 4 ограничивающих объёма - их может быть 3, или 5, и тогда придётся "подбивать" структуры пустыми данными и тратить на них вычислительные ресурсы. Если же иерархическая структура настроена на поставку четвёрок объёмов за раз, то данный подход представляется оптимальным.
Если взглянуть на функцию пересечения с прямоугольником, можно отметить что выражения
(lo-o)*inv_dir
(hi-o)*inv_dir
ложатся на dxadm как add+mul, при этом превратить их в mad не представляется возможным из-за порядка операторов. Однако, если мы делаем трассировку лучей в ортографической проекции или от направленного источника света (Солнца), мы можем переписать это в виде
lo*inv_dir-o*inv_dir
hi*inv_dir-o*inv_dir
Рис. 3. Пересечение луча с 4-мя прямоугольниками в ортографической проекции, приблизительно 19 dxasm инструкций.
Комментариев нет:
Отправить комментарий