🔥

Тред #8


Сегодня обсудим извечную тему с оптимизацией. Поговорим как про общие вещи, так и те, что относятся чисто к разработке игр.
notion image

Гифка выше из игры Horizon Zero Dawn. Фича называется Occlusion Culling и позволяет не рендерить то, что не попадает в область камеры. Давайте на примеры неё обсудим сабж.

Эта фича, думаю, по дефолту включена во всех движках. Но если и нет, то как бы вы пришли сами к такому решению? Если игра небольшая и объектов мало, то, вполне возможно, вам бы это никогда бы и не понабилось.

Но если объектов много, то в какой-то моменты вы бы заметили проблемы (падение фпс, как минимум). Начали бы профайлерить (если ещё не) и столкнулись с тем, что движок много лишнего отрисовывает. Что дальше?

Ищем, как же сократить число объектов для отрисовки. Решение с тем, чтобы не отрисовывать всё, а лишь видимые объекты — логично. Отлично. Проблема решена. Возможно...

А теперь посмотрим на этот скрин. Да тут же у нас отражения объектов, которые не попадают в камеру. Но мы их выгрузили. Или нет?
notion image

Как минимум, если нам нужны относительно достоверные отражения, то нужно оставлять информацию про геометрию и какую информацию о текстурах/цвете. Как мы уже поняли, всё это держать в памяти не выйдет. И тут опять какие-то трейдофы будут.

На консолях, к примеру, RAM меньше, чем на ПК обычно. Нужно периодически, всё же, выгружать ресурсы из памяти. Что очень медленно, если у вас HDD (как было ещё на PS4 фат). Да и с обычным SSD всё равно не получится это делать стримить.

Поэтому сейчас так много шумихи вокруг PS5, где стримить ресурсы с диска можно напрямую в память через спец. чип для распаковки, минуя CPU. И вот все эти выгрузки/загрузки умудряются за кадры происходить в фоне.

Вы могли слышать про Ratchet & Clank, который выходит на PS5. Там эту фичу по максимум задействовали. И в порталах даже видны куски других миров, а не просто какие-то спрайты-болванки.
notion image

Даже текущие nvme на PC не могут такого выдать, т. к. всё тормозит декомпрессинг и проход через CPU. К примеру, в RE8 на PS5 сейвы грузятся 2 секунды, у меня на PC с nvme около 4 секунд.

Порядок то вроде тот же. И в случае с сейвами это вполне приемлемо. Но если вам нужно стримить ресурсы в рантайме, напомню, в рамках кадра-двух, то эта разница вам не позволит такое провернуть.

При разработки игр стоит точно такой же вопрос, как и в случае любого софта: нужно ли париться об оптимизации, если "premature optimization is the root of all evil"? Многие фразу слишком буквально трактуют. Да и оптимизации же не только самого кода касаются.

Этот вопрос тесно связан с планированием и видением продукта. Нужно хотя бы примерно представлять, в каком направление будет развитие, чтобы на ранних этапах это заложить в систему. Всё это, по сути, тоже часть оптимизации.

Тут ещё как следствие частенько всплывает то, что люди часто доходят до оверинженеринга, что по итогу может нивелировать всё их планирование. Много раз сам ловил себя этом. Но про это в воскресенье расскажу.

Ещё интересный вопрос: как человек понять, что нужно что-то переделать? Как сформулировать проблему? У всех ведь разный уровень. Кто-то только начинает.

Скажем, в Unity 5.2 была проблема с лишними аллокациями при обходе циклов итерраторами. Проблема? Ну...нет наверно, если это один раз за кадр. А если не один раз? А зависит ли это от числа элементов?

Скажем, новичок умудрился заметить это в профайлере. Что он будет гуглить? "У меня странные аллокации"? Поэтому, если начинается работать с чем-то новым, то погуглите для начала всякие best practice для этой технологии/движка. Это в будущем кучу времени сэкономит.

И помните: правильно поставленный вопрос — это уже половина ответа. Не "почему у меня в игре лишние аллокации", а "почему при прогонке цикла с помощью итератора у меня лишние аллокации".

Если вы столкнулись с проблемой, то для описания нужно по максимуму сузить скоуп. На том же StackOverflow раньше даже была причина закрытия для вопросов "Слишком общий", т. к. люди не могли выделить точно проблему. Как следствие, было сложно им помочь (почти невозможно).

И нужно задавать себе постоянно вопросы. Оптимизация — это ещё и про оптимизацию работы всей команды. Если вы делаете синглплей платформер, то есть ли в планах локальный кооп? Если да, то возможно в будущем нужен будет мультиплеер с дедикейтед серверов?

В этом платформере явно будут абилки. Планируется ли даблжамп? Если такие вопросы не задавать, то левелдизайнерам придётся по нескольку раз перекраивать уровни.

А чардж в вохдухе? Отскок от стен? Представьте, сколько раз бы пришлось переделывать Hollow Knight, если бы все эти вещи не были продуманы изначально.
notion image

Многие вещи лучше заложить заранее. Особенно, учитывая, что в движках есть поддержка таких штук. В частности, хорошо бы оптимизировать модельки. В зависимости от расстояния грузить в отдалении LOD'ы с меньшим число вершим, чтоб не нагружать рендерер.
notion image

Вы даже не заметите разницы между такими модельками, а весть они будут в десятки раз меньше, вершин там может быть в сотни/тысячи раз меньше, что очень облегчает отрисовку.

По поводу LOD'ов был отличный доклад от разработчиков Assassin's Creed на GDC, где они кучу техник рассказали. И не только про LOD'ы. youtube.com/watch?v=Rz2cNW…

В отдалении, к примеру, когда нужно отрисовать армии врагов, это вообще были не полноценные модели, а простые меши-болванки с простой анимацией. На них даже физики никакой не висело. С ним нельзя взаимодействовать.

Даже всякие мелочи могут сильно ускорить кадр. Много полезных советов можно найти в этом видео про Unity. youtube.com/watch?v=mQ2KTR…

Всякие базовые вещи типа работы с геттерами/сеттерами, кеширование трансформа, кеширование deltaTime, уменьшение операций с векторами, работа с массивами вместо списков и прочее. Всё в сумме, в примере от разработчиков INSIDE, снизило время кадра со 106 до 10 мс.
notion image

Говоря про Unity (¬‿¬ )
notion image

В том же докладе ещё отмечается, что нужно тестировать на всех платформах, где будет издаваться игра. К примеру, в INSIDE синус в редакторе и на ПК (в их кастомной реализации) работал быстрее дефолтного, на Xbox медленней.
notion image

Это же касается и окружения. Если вы пишете бекенд, то настройте такое же окружение, как на удалённом серваке. Если на сервере nginx, то запускайте локально nginx. Не apache. Не какой-то dev-сервер. Именно nginx. Желательно ещё работать под той же ОС (или в виртуалке).

В геймдеве чуть ли не в абсолют возведена практика предвычисления значений, а потом поиск их по таблице/хешмепе. Синусы, косинусы, поиск по графам и прочее, прочее. Жертвуя памятью вы очень ускоряете многие вещи.

Зачем нам каждый раз прогонять алгоритм поиска пути, если у нас статичная карта и можно просто закешировать уже вычисленные пути? Или для относительно статичных уровней использовать штуки типа Навмешей, которые всё (ну, почти) сделают за вас. docs.unity3d.com/Manual/nav-Nav…

В реалтайме очень ресурсоёмко просчитывать свет и тени, поэтому используются различные техники, когда свет запекают в лайтмепы. Особенно полезно для мобилок. learn.unity.com/tutorial/confi…

Про свет в Unity был отличный доклад прошлым летом. youtube.com/watch?v=hMnetI…

В Silent Hill был туман, ограничивающий видимость.
notion image

В Witcher 3 уровни проектировались так, чтобы ограничить обзор игрока. Об этом и многих других трюках можно в этом докладе с GDC узнать. youtube.com/watch?v=9vEfH9…

Я сам вряд ли смогу когда-либо поработать над такими крутыми проектами, но очень интересно читать/смотреть за тем, как люди побеждают технические проблемы. Очень вдохновляет. youtube.com/watch?v=wavnKZ…