Войти
ПроектыФорумУтилиты

Dynamic GPU Occlusion Culling для Unity 2017+

Advanced: Тема повышенной сложности или важная.

#0
(Правка: 5:44) 0:15, 12 фев. 2019

Плагин для тех кого не устраивает встроенный Occlusion Culling, а минусов у него много — необходимость запекать сцены, работает только со статичными обьектами, не работает с тенями и т.д.

Видео:

Дело происходит на вот такой сцене:
Изображение

MeshRenderers: 111k
MeshFilter triangles: 670kk
Particle systems: 18000+
Point lights: 6000+ (без теней)

Ничего не запекалось, весь свет динамический.

Сравнение в редакторе:
Изображение
Изображение

Встроенный OC на такой сцене запекать очень долго, вот сравнение на маленькой сцене: https://imgur.com/a/eI3BA3N

Плагин будет продаваться на ассет сторе.
Если есть желание потестить в своей игре — пишите.

#1
5:36, 12 фев. 2019

Разница конечно разительная между хардварным куллингом и дефолтным. Но я так понимаю LOD-ы не используются вообще? Т.е. если подняться на уровень крыш зданий, то харварный куллинг точно так же соснёт?

#2
5:59, 12 фев. 2019

Исправил пост, теперь нет ощущения что в видео сравнивается с дефолтным куллингом — сравнивается с отсутствием куллинга вообще. Дефолтный запекать на такой сцене минут 20 (если он не упадет в процессе), поэтому сделал сравнение на сцене поменьше: https://imgur.com/a/eI3BA3N

Основная проблема дефолтного (в плане производительности) что он ничего не делает при рендеринге карты теней, а это времени занимает почти столько же сколько построение g-буфера. Поэтому когда есть солнце/луна с реалтайм тенями, он показывает результаты раза в 2 хуже. Также как я заметил он не особо дружит с маленькими системами частиц.

LODы не используются потому что понятно что они никак из 10 фпс не сделают 100, в лучшем случае просто сгладят разницу. Кроме того, если для систем частиц еще можно придумать как их сделать, то для точечных источников света по-моему уже никак

А насчет подняться выше крыш — щаз попробую

#3
(Правка: 7:01) 6:59, 12 фев. 2019

В общем результаты такие (сцена чуть меньше чем на видео)
FPS как он показан в Stats (т.е. c исключением EditorOverhead)
Справа внизу — скрины из RenderDoc чтобы было понятно на что время ушло

Без OC вообще (4.2 FPS):
Изображение

Встроенный OC, дефолтные настройки (6.4 FPS):
Изображение

В принципе все ожидаемо:
1. Ощутимо снизилось время построения G-буфера (исключена вся мелочь скрытая домами)
2. Также более-менее с частицами — но как я уже писал, почему-то они ему плохо даются. Он исключил дым от факелов (частично), но проигнорировал огонь и искры которые в сотню раз меньше по обьему BB. Возможно лечится настройками, не пробовал, и так долго ждать пока все запечется.
2. RenderDeferred.Lighting почти не изменилось (сюда входят точечные источники света факелов и карта теней от луны).

GDOC (63.5 FPS):
Изображение

1. Исключено еще больше мелочи из G-буфера
2. Освещение в 4 раза быстрее, в основном за счет выключения невидимых теней, в том числе теней от обьектов которые целиком находятся в тени более крупного обьекта.
3. Все невидимые частицы исключены, время рендеринга сократилось более чем в 20 раз

#4
10:05, 12 фев. 2019

Если это динамический окклюжн то полезная вещь. Из представленных на ассет  сторе все имеющиеся - мусор, особенно с рейкастами :)
Этот интересно посмотреть.

#5
(Правка: 10:11) 10:07, 12 фев. 2019

Каким образом там выключаются рендереры? Собираются в какой то dictionary и после прохода окклюжна включаются видимые?

Если оно сможет откуллить сцену после моего портального куллинга а не перекрестно, то я впринципе куплю изделие)

#6
12:10, 12 фев. 2019

Mira
> Собираются в какой то dictionary

эх... помню дивные срачи "зачем map/dictionary в игре" :)

#7
23:29, 12 фев. 2019

Идея в том что после рендеринга фрейма использовать его глубину (и карту теней) чтобы предсказать какие обьекты на следующем кадре будут видны, у каких будут видимые тени и какие будут закрыты от света другими обьектами и т.д.

Минус очевиден — задержка как минимум в 1 кадр что вынуждает быть очень консервативным и держать обьекты включенными даже если они не видны в текущем кадре но с большой вероятностью могут быть видны в следующем, плюс еще пара техник чтобы до минимума сократить ситуации когда при резком движении обьекты появляются из ниоткуда.

Худшая ситуация — когда камера проходит через стены (обычное дело если камера от 3 лица), глубина радикально меняется, данные оклюжена с прошлого кадра становятся совершенно не в тему и куча обьектов появляется из ниоткуда прямо перед камерой. Полностью решить невозможно, но можно например рендерить большие обьекты перед камерой всегда без проверок, тогда это будет не так заметно и не приведет к эффекту появления паровозика из обьектов до горизонта (из-за пустой глубины в этом месте).

Впрочем, задержка это бич любых расчетов на видюхе и простых решений пока не придумали.

Плюсов, на мой взгляд, больше:

1) Это в любом случае лучше чем без OC вообще, даже если рендерить кучу больших обьектов перед камерой (и встроенный в Unity OC в любом случае соснет за счет теней, частиц, света и т.д. на любой сцене сложнее 10 кубиков поставленных в ряд).
2) Это очень дешево - глубина (и карта теней) уже есть, осталось просто отрендерить AABB-ы (и теневые обьемы) и обработать результаты
3) Не требуется что-то менять в игре (в шейдерах или в целом в rendering pipeline), в простых случаях достаточно добавить 1 компонент на камеру и оно будет работать.

#8
(Правка: 0:08) 0:02, 13 фев. 2019

И еще немного мыслей по поводу альтернатив этого метода:

1. Umbra (именно ее использует Unity) и подобные — актуальны для небольшого количества простых статических сцен, желательно с запеченным светом.

2. Software rasterization, а именно рендеринг глубины на CPU в уменьшенном разрешении перед рендерингом кадра целиком. Хорошая технология, но требует проц от Intel последних поколений, иначе очень медленно. Тот факт что некоторые до сих пор сидят на феномах (и говорят что им норм) крайне ограничивает эффективность этого метода. В принципе использовать можно, но см. ниже про бонус.

3. Depth pre-pass + indirect рендеринг, в разных вариациях. Это то, что я бы использовал, если бы начинал делать ААА проект с нуля в большой команде. Метод всем хорош за исключением необходимости очень глубокой интеграции в проект, все обьекты должно рендериться одинаково, а именно с instancing и indirect, иначе смысла не будет. И если для простых непрозрачных обьектов это настраивается достаточно быстро, когда дело доходит до тех же частиц или точечных источников света, начинается боль.

Как бонус, они все также страдают от того факта, что нет никакого способа отрендерить встроенный террейн вручную или вообще получить какой-то доступ к его мешу.

Поскольку я делаю ассет, который должен работать в любом проекте без лишнего гемора, это все не подходит. Coverage buffer (с SR) и подобные не рассматриваю потому что фактически они обьединяют недостатки 2 и 3 и при этом никак не решают проблему задержки.

Кстати зачем и на каком этапе нужен Dictionary я так и не понял :D

#9
12:25, 13 фев. 2019

drcrack
> Кстати зачем и на каком этапе нужен Dictionary я так и не понял :D
sectr например все рендереры сцены собирает в хешлисты. после проверки их видимости включает и выключает. каким образом у вас рендереры включаются?

#10
12:41, 13 фев. 2019

Обьекты (в плагине, который на с++) хранятся в большом одномерном массиве, потому именно в таком виде они должны быть скопированы в буферы на видюхе, поэтому на стороне C# у меня точно такого же размера массив в котором хранятся ссылки на компоненты которые висят на рендерерах. Ну или просто на обьектах-контейнерах, потому что куллить можно что угодно, главное задать размер бокса.

Соответственно, когда в плагин приходят результаты оклюжена с GPU, он составляет список того, чему нужно поменять состояние, и передает его в юнити, а юнити уже из массива достает обьекты просто по индексу.

Кроме того Dictionary на 100к обьектах сильно тормозит.

#11
(Правка: 15:02) 14:59, 13 фев. 2019

drcrack
это я и хотел услышать, массив или диктионарий. ну норм делай поглядим
к слову SECTR уже при порталах 50+ начинает работать в минус выжирая весь CPU ресурс :)
правда там диктионари не играет такой роли, там боль это обилие матана на скриптах и дрочка GC. на SSE тоже почти тожке самое делал - оно летает.

ПроектыФорумУтилиты