Как стать автором
Обновить

Комментарии 26

А если дизайнеру потом немного захочется повернуть камеру по-другому — контент опять придется переделывать? Очень странное решение. Удалять можно только то, что гарантированно не будет видно при любом ракурсе камеры, все остальное — должно быть на месте во избежание.
Вы правы. Если меняются настройки камеры, нужно заново перепроверить треугольники на видимость/невидимость. Поэтому оптимизацию нужно проводить после того, как сцена полностью готова и утверждена с визуальной точки зрения.
«Удалять можно только то, что гарантированно не будет видно при любом ракурсе камеры» – именно это и позволяет сделать приведенный в статье способ. Сначала вы определяетесь с ракурсами камеры и расположением объектов, потом оптимизируете. Для наших сцен с юнитами есть ограничения на возможные положения камеры. Угол обзора, приближение и отдаление зафиксированы и меняются в определенных диапазонах. Объекты статичны, не меняют своих позиций и не вращаются. Если же камера полностью свободна, ее движение ничем не ограниченно, или же модель может поворачиваться под любым углом, то, конечно же, в кадр сможет попасть любая часть модели. И обрезать ничего нельзя.
именно это и позволяет сделать приведенный в статье способ.

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

Но разве этим стандартные механизмы culling-а движка не занимаются? Отсечение невидимых вершин — то, что базово умеют все игровые движки уже лет 10.
Интересно было бы увидеть сравнение производительности с и без Вашего механизма.
P.S. Для Unity есть гораздо более эффективный способ оптимизации — отключать скрипты невидимым игроку объектам. Когда объект не в кадре — он не рисуется, но его физика работает, коллизии считаются, скрипты действуют, и всë это бодро кушает ресурсы. Большие движки раньше умели это отключать, а вот Unity не умеет. Я написал крохотный оптимизатор, который это всë делает (можно выборочно и при определëнных условиях). В нагруженных сценах даëт прирост до 20%. Могу поделиться наработками по этому методу, если интересно :)

Вообще-то, нет. Даже OcclusionCulling в Юнити не отсекает полигоны — только целые меши. Те полигоны которые отсекли на роботе и так не отрисуются по нормали (Back Face Culling). Но дело здесь не в отрисовке, а в памяти, занимаемой вершинами. А если узкая шина памяти будет заполнена — упадет fps.

Backface culling я и имел в виду. Если модели сделаны по уму, импортированы верно, и полигоны не double-sided, то дальние заслонëнные грани объекта будут отброшены и не нарисуются. Это копеечная по трудоëмкости операция, и Юнити это делает, да.
Про память — разговор особый. По статье просто так читается, что именно отрисовка и оптимизируется. Про загрузку шины памяти — вот это надо обдумать. Велик ли импакт на рядовых мобильных моделях?

Из статьи:
Невидимые части делятся на две категории:
1 Находящиеся сзади модели.

Полагаю что это и есть полигоны для Backface culling, они отбрасываются не потому что чем-то заслонены, а просто по ориентации, т.к. рисуются только с одной стороны.

конечно же интересно, зановоо изобретать велосипед интересно, но как всегда времени не хватает

Что мешало просто отрендерить меш заливая полигоны порядковым номером вместо цвета, а потом пробежаться по результату рендеринга и собрать номера видимых полигонов?
Myzrael GCU
Обращаем ваше внимание, что не вся сцена рендерится целиком, а лишь определенный ее фрагмент, который содержит проверяемый треугольник. Ваш метод тоже интересный, но из-за более сложного алгоритма восстановления индекса треугольника из цвета и времени, затраченного на отрисовку нескольких ракурсов и так видимых частей, производительность будет сопоставима.
Предположим, треугольник на третьем из 20-ти ракурсов оказался видимым, тогда его больше проверять не нужно. А в предлагаемой вами реализации на каждом ракурсе вы все равно будете рендерить даже те треугольники, которые уже не нужно проверять.

Нет разницы, рендерить 1000 треугольников или 1. Вы больше на DIP потеряете, чем карточка это рисовать будет. Я видимо несколько не понял вашу задачу. Я предполагал, что у вас есть несколько фиксированных ракурсов отображения моделей и вам нужно для КАЖДОГО ракурса вычислить список видимых полигонов, чтобы рисовать только их для данного ракурса. Я что-то не так понял? Я вообще думал, что это препроцессинг и тут скорость не так важна, зато простота решения должна иметь значение.
В моём понимании рендерить видимые части всё равно приходится, чтобы проверить — перекрывают ли они красный треугольник, разве не так?
По времени непосредственно на отрисовку — один рендер на ракурс всего. В пиксельный шейдер прокидывается индекс треугольника и по нему выставляется цвет фрагмента, меш рисуется целиком.
Может то что нет такого понятия как «полигон», есть вершины объединенные индексами.
вы плохо знаете GAPI :)
А может быть вы? (С) :)
Приведённый алгоритм выглядит не очень эффективным — для одного треугольника делать рендеринги со всех позиций?
Для каждого треугольника можно писать в буфер цвета его индекс, чтобы потом из картинки найти полный набор отображаемых треугольников. Дополнив этот набор со всех позиций — убрать те треугольники, индексы которых не встречались.

«Части первой категории обработать достаточно легко, используя стандартный способ удаления невидимых треугольников.»

Что за чушь?
никакого прироста FPS не приносит. Движок и так не тратит ресурсы на отрисовку невидимой геометрии, даже если она находится в пределах видимости камеры.
Производительность GPU зависит не только от количества треугольников в кадре. Важно количество и размер текстур в памяти и количество прочитанных пикселей с этих текстур, которые потребовалось сделать для отрисовки кадра. Обрезая невидимые ни при каких условиях треугольники мы, во-первых, уменьшаем размер карт освещения и время их просчета, во-вторых, можем более эффективно использовать пространство основной текстуры.
А как вы учитываете влияние невидимых треугольников на карту освещения?
По логике они являются источником отражений света, но в самой карте не нужны.
Суть как раз в том, чтобы избавиться от этих невидимых треугольников, и не запекать их в карте освещения. Соответственно, экономится текстурное пространство. А за счет уменьшения площади поверхности объектов экономится время просчета. Единственный нюанс – это корректность запекания освещения, а именно теней от объектов. Если сразу удалить невидимые треугольники и запечь сцену, оптимизированные объекты будут отбрасывать некорректные тени. Поэтому невидимые треугольники объединяются в отдельный меш, этому мешу выставляется нулевой масштаб в карте освещения (свет НА него не запекается), но при этом он отбрасывает тень. Проводится запекание, и только потом меш удаляется.
А чем не понравился вариант скалярного произведения векторов?
Вы имеете в виду произведение нормали треугольника и направления взгляда? Тем, что этот вариант подходит для удаления частей меша, которые находятся сзади модели (не «смотрят» в камеру). А вот перекрытые другими частями и объектами области так не найти.
Понял когда уже нажал отправить. Эту проблему я решил с помощью MeshCollider и рэйкастов. Сначала отсекаю невидимый меш с помощью произведения нормали треугольника и направления взгляда, после выбрасываю мусорный меш при помощи рэйкастов. Если длина вектора разницы позиции вертекса и точки в которую пришелся рейкаст больше определенной длины — я считаю точку невидимой. Если не один из вертексов не виден, и рейкаст в центр треугольника тоже не увенчался успехом — треугольник так же считается невидимым.

Точность конечно немного меньше чем точность вашего алгоритма — но у него есть свои плюсы. Процессинг выполняется очень быстро. И доступен предпросмотр в рантайме.
Вот так выглядит результат работы алгоритма:
Зарегистрируйтесь на Хабре, чтобы оставить комментарий