Всем привет! Добро пожаловать в новый ежемесячный отчёт о проделанной работе, который теперь называется не "результаты работы", а "итоги месяца". Название хоть и меняется, но суть остаётся прежней.
[Grim Wild]
В конце прошлого месяца я наобещал вам много всего, но в итоге 3 недели у меня ушли на большое исследование в области отрисовки. Надеюсь, что фантастические результаты работы перебьют ваше негодование от того, что сценарий ролика так и не был написан и озвучен :)
Значительная оптимизация отрисовки
Сразу скажу, что у меня для Бусти планируется отдельный ролик на эту тему. Здесь я бы не хотел уходить в дебри кода, так что пройдусь кратко.
Раньше (до ноября) для отрисовки объектов я использовал GroupedSpriteComponent, который объединял спрайты одного объекта в единый Draw Call (объяснения будут в ролике). Но выяснилась большая проблема: анимации оказались невероятно "тяжёлыми". Дело в том, что при каждом малейшем изменении спрайта движок уничтожал всю старую информацию об объекте и воссоздавал её с нуля (каждый кадр, да).
Я долго пытался найти выход из этой ситуации, но его просто не было. Пришлось погружаться в тему рендера ещё глубже. Спустя 3 недели мучений я, наконец, добился своего. Теперь у меня самый оптимизированный рендер спрайтов в Unreal Engine за всю мою карьеру.
Без снижения FPS одновременно на сцене может отрисовываться до 10 000 разных объектов. А вот демонстрация одновременного отображения 196 000 динамита:
Да, здесь всего 8 FPS. Но я считаю этот результат невероятным, потому что тут почти двести тысяч объектов.
По скриншоту не очень понятен масштаб, но вот картинка поближе:
Мне пришлось отказаться от плагина Paper2D и создать свой класс "Static Sprite", который не только имеет Dynamic Instancing (то есть возможность соединять Draw Calls воедино), но и Draw Command Caching (спрайт вычисляет информацию для рендера ровно 1 раз после добавления на сцену, а не каждый кадр, как в Paper2D). В общем, технических деталей много, и придётся ждать выхода ролика.
Единственное, что я хочу отметить сейчас - это наличие багов и ограничений. Получившаяся система имеет проблемы, и решать мне их придётся ещё долгие месяцы (на фоне работы над новыми системами, конечно)
Сглаживание
Сглаживание (Anti-Aliasing), по моему мнению, в Unreal Engine сделано просто ужасно. Вот выбор, который у меня был:
1) Ничего
2) FXAA
3) TAA (Temporal AA)
4) MSAA
5) TSR (Temporal Super Resolution)
А вот визуализация каждого алгоритма сглаживания на большом отдалении камеры:
1) None: Выглядит ужасно
2) FXAA: Выглядит ужасно
3) TAA: Выглядит мыльно + создает много проблем
4) MSAA: разницы с None нет, оно создано для 3D графики
5) TSR: next-gen сглаживание; точно не для 2D игры
6) "Мой" FXAA: Расскажу дальше
Всё это время я использовал TAA, потому что это был наименее ужасный выбор из доступных. Правда, за 2 года разработки проекта я уже повидал тонну проблем, на решение которых я суммарно потратил чуть ли не сотню часов рабочего времени.
Вот краткий список проблем, которые случаются в TAA: Jittering (дрожание), Ghosting (след), Disocclusion (растворение), Smearing (размазывание), Flickering (мерцание) и Blurring (размытие). Подробнее можно почитать тут.
В Grim Wild это проявлялось так:
В общем, в ноябре я перешёл на FXAA, потому что мне удалось подкрутить некоторые значения и сделать его лучше. Теперь игра выглядит так:
Всё ещё не идеально, но уже намного лучше TAA. Кстати, в действии этот метод сглаживания вы могли видеть в предыдущих роликах на Бусти.
Обновление графического стиля
FXAA не дружит с прямыми и контрастными линиями, так что мне пришлось изменить визуальный стиль игры: обводка теперь имеет низкую контрастность и уменьшенную толщину, а также наследует оттенок материала (дерево, камень, золото, пластик, листва ...)
Оттенки материала
В ноябре я сделал интересную систему, которая делает оттенки материалов красивее. Вместо простого умножения текстуры на цвет, я делаю сдвиг по яркости и насыщенности. Все расчёты выполняются на видеокарте, так что ущерба производительности от такой системы не будет.
Информация об оттенке материалов будет храниться в памяти видеокарты (VRAM) для быстрого выполнения расчётов.
В процессе
Кое-какие нововведения, работа над которыми велась в ноябре, до конца сделаны не были (многое из этого - это долгосрочные планы):
1. Состояния клеток и их отслеживание (Cell States & Trackers): скоро доделаю
2. Поклеточная симуляция: я ищу разные способы реализации этой системы на GPU
3. Внедрение модов: в ноябре я начал тестировать плагин LuaMachine для интеграции Lua в Unreal Engine
4. Генерация мира: я продумал систему "мировой жидкости" и то, как она будет существовать и меняться (генерация и пересыхание рек / впадание в озёра). Планируется, что она тоже будет происходить на GPU.
5. Инвентари, склады и рабочие места: надеюсь, в скором времени я смогу показать вам результаты работы над этими системами.
6. Закрытое тестирование: из-за того, что рендер до сих пор не готов, я не могу начинать тестирование. В любом случае, подготовка к нему продолжается
[Публичная деятельность]
Глава под названием "YouTube" расширяется. Так получилось, что моя "публичная деятельность" выходит за рамки одной платформы, и называть всё это "Ютубом" уже некорректно.
Увы, из-за оптимизации отрисовки мне пришлось пожертвовать шестым роликом. Сценарий и озвучка сделаны не были. Зато я набросал структуру для 7, 8 и даже 9 серии. Мне есть, о чём рассказать, и это хорошо.
На Boosty вышел ролик про глобальную реконструкцию и новую отрисовку (тогда ещё без оптимизации)
Ещё у меня скопилось 33 черновика для постов в Telegram-канале. Увы, пока ни один из них не был завершён, так что открытие новой площадки откладывается.
[Планы на декабрь]
Нововведений ждать не стоит. Весь декабрь я буду заниматься работой над новым роликом, а в проекте буду решать проблемы отрисовки. Звучит не так интересно, и, скорее всего, именно по этой причине "итогов работы за декабрь" не будет. Вместо этого будут "итоги года", и вот это звучит уже намного интереснее!
Спасибо за внимание 🙃