Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Статьи / Software Occlusion Culling

Software Occlusion Culling

Автор:

Оклюжен кулинга сейчас, наверное, нет только у ленивых. Некоторые используют HW OC, у которых есть очевидные недостатки в виде латентности и дополнительной нагрузки на GPU. Другие используют софтовую растеризацию. К примеру, мы можем растеризовать глубину близлежащих оклюдеров (специальной или прямо рендер геометрии), затем проверять баунд боксы отрисовываемых объектов относительно этой глубины. Радостей от такого подхода может быть несколько.

Во-первых, мы может рисовать это всё в уменьшенном разрешении. Во-вторых, такая отрисовка достаточно легко параллелится на несколько потоков, что в наше время непрерывного увеличения числа ядер у CPU является приятным бонусом. Для растеризации есть два основных алгоритма — сканлайны и халфспейсы. При использовании сканлайнов мы просто рисуем горизонтальные линии между ребрами треугольника. При использовании халфспейсов, строим вьюпорт спейс баунд рект треугольника, итерируемся по всем пикселям, которые в нём, и, если пиксель внутри треугольника, то рисуем его. Но в целом нам достаточно определить сам факт того, скрыта ли текстурируемая геометрия оклюдерами или нет.

softwareoccluder | Software Occlusion Culling

Тут вот на форуме, Петя предложил крутую технику оклюжен кулинга. Принцип прост: мы хотим записывать / тестировать максимальное количество пикселей треугольников за такт работы внутреннего цикла растеризатора с одной стороны. С другой стороны, нам, в общем-то, не нужна информация о глубине каждого пикселя в оклюжен буфере. Достаточно знать находится ли в этом пикселе оклюдер или нет, одного битика хватит за глаза. В традиционных софтовых оклюдерах сначала отрисовывались все оклюдеры и лишь затем проверялась тест-геометрия. Нам такой подход не подойдет по понятным причинам. Нам придётся сортировать все треугольники по Z (минимальный Z для тест геометрии и максимальный Z для оклюдер геометрии) и только потом рисовать. Зато, после сортировки, используя SSE, мы можем писать / тестировать аж 128 пикселей за итерацию внутреннего цикла растеризатора. В связи с тем, что мы можем писать фиксированное количество пикселов за шаг, имеет смысл разбить оклюжен буфер на тайлы. Ширина SSE регистров естественным образом задаёт ширину тайла, высота может быть выбрана произвольная. Моя реализация работает примерно так:

  • Трансформируем баунд боксы объектов (оклюдеров, тестируемой геометрии) в пространство вьюпорта. Определяем, необходимо ли отсекать треугольники, а также границы тайлов, в которых эти объекты лежат
  • Трансформируем вершины в пространство вьюпорта (при необходимости, клипаем).
  • Записываем трансформированный треугольник в глобальный список, а в каждом тайле, которого этот треугольник касается, сохраняем его индексы. Треугольники храним в SoA стиле, по 4. Также на этом шаге считаем маску для удаления backfacing треугольников.
  • После того, как все объекты были оттрансформированы и добавлены в тайлы, для каждого тайла производится сортировка его списка треугольников.
  • Отрисовываются отсортированные списки треугольников (OR сканлайна треугольника со сканлайном оклюжен буфера тайла для оклюдер треугольников, для тест треугольников — проверка, что хотя бы один из пикселей сканлайна виден).

В общем-то, базовую версию алгоритма несложно реализовать и проверить самим. Моя текущая имплементация может рисовать 300к+ треугольников снапшота с игровой камеры Death Track примерно за 20мсек (12 мсек трансформаци + 8 мсек растеризация) в 720п, что неплохо. И надо понимать, что это однопоточная синхронная версия. Думаю, на архитектурах с большим числом регистров, будет чуть лучше. Если прикрутить потоки, опять же, думаю, станет ощутимо лучше. Очень органично ложится на концепцию Job Manager. Интересным также выглядит попытка автоматической генерации оклюдеров и тест геометрии. Респекты и уважухи Пете за крутую идею и обсуждение деталей реализации.

Пример реализации с исходниками: Реализация Software Occlusion Culling

unoccluded_wireframe | Software Occlusion Culling unoccluded_solid | Software Occlusion Culling

occluded_wireframe | Software Occlusion Culling occluded_solid | Software Occlusion Culling

3 апреля 2011

#occlusion

2001—2017 © GameDev.ru — Разработка игр