Дневник разработки №33
Всем привет! И с прошедшими новогодними праздниками!
Прошло уже больше месяца с последнего дневника разработки. Скажу сразу, что хотел выложить дневник раньше, но столкнулся с трудноразрешимой задачей, на которую потратил кучу времени. Но все по порядку.
Согласно плану разработки был реализован первый контакт с ИИ:
Внизу скриншота видны сообщения о пересечении зон контроля армии с другой армией и городом. Теперь предстояло разработать некий элемент интерфейса который бы отображал данные события:
На данном скриншоте в левом верхнем углу представлена реализация UILabel с возможностью переноса текста по словам. Важный элемент интерфейса который пригодиться в дальнейшем. В правом нижнем углу, над кнопкой конца хода теперь видны различные сообщения, по наведению курсора мышки на них выскакивает подсказка (тоже новый элемент интерфейса), с коротким описанием события. По нажатию правой кнопки событие можно закрыть без принятия какого либо решения, а левой кнопкой можно раскрыть сообщение.
В данном случае при нажатие на кнопку события произойдет первый дипломатический контакт в игре:
Далее были реализованы первые маневры ИИ. ИИ ходит по карте и пытается определить границы своего материка. В видео у Дуката https://youtu.be/69G51u_Mq3g?t=693 ,есть момент где он бегает за армией противника, который не обращает на него внимания, так как занят исследованием карты :)
И вот где-то в этом месте и в это время, я столкнулся с проблемой, проблемой производительности. У нашего моделлера достаточно мощный современный компьютер красной сборки. Но у него игра жутко тормозила грузя одно ядро процессора. Причина проста — в новых процессорах много ядер, но по факту они менее производительны в однопоточных приложениях. А тот момент у меня был рендер в один поток. Но на самом деле причины была не столько в этом. И в процессе поиска проблемы я решил посчитать сколько полигонов у нас присутствует в сцене:
На средней карте при максимальном отдалении и большом скоплении пальм - это просто жуть! 15 824 756 треугольников! Почти 16 миллионов!!!
Немного погенерировав карты я нашел место с 16,75 миллионами :)
Хотя вот подобное место с елками давало всего 8,5 миллионов треугольников:
А в среднем сцена состояло из примерно 4 миллионов:
В общем я был рад что мой рендер справляется с таким огромным числом треугольников, но их количество было чрезмерным. Нужно было оптимизировать количество полигонов в моделях.
На 40% снизился полигонаж елок! Отличий практически не видно.
Следом мы переделали и пальмы - полигонаж на пальмах был снижен в 10 раз. 600 - 700 против шести тысяч полигонов в одном паке.
Параллельно пока шла работа над моделями я занялся вопросом упрощения геометрии террайна. Вот как он выглядел до оптимизации:
И после первых шагов:
Но это было все сделано простым методом — все ровные тайлы были заменены двумя треугольниками вместо 882.
Но оставались еще ровные места которые можно было оптимизировать, и я начал строить полигоны из тех треугольников у которых была одинаковая высота:
Строить по ним выпукло-вогнутый контур (Concave Hull). С Convex Hull`ом проблем не было, я уже использовал алгоритм Грэхема (Graham scan). А вот построением Concave Hull появилась проблема... Информации на эту тему тему в интернете найти оказалось достаточно сложно. Пришлось писать реализацию алгоритмов с нуля. Не совру, если я скажу что прочитал с десяток разных диссертаций на эту тему. Но все предложенные алгоритмы давали приближенный результат с некоторой погрешностью. После недели мучений и боли мне пришла идея своего алгоритма, возможно я его когда-нибудь опишу :)
В результате уже двух недельного мучения я получил искомый результат и смог строить Concave Hull практически любой сложности, обходя стороной множества с дырками, просто разделяя их на 2 половины по дырке. Получал контур и триангулировал его:
[/spoiler]
Получая на выходе такой результат:
Также подвергся упрощению туман войны:
И в зонах где присутствовал только туман войны получалось всего порядка 300 полигонов:
Но в итоге я был расстроен результатом и расскажу что эти две недели я потратил в пустую... Разработанный мной алгоритм давал ощутимую прибавку в производительности при отрисовке, так как количество полигонов в среднем сокращалось на 60 — 70%. Но генерация карты стала происходить раз в 10 медленнее.... алгоритм был тяжелый по временным затратам.
3 дня я проиграл в ATOM RPG снимая стресс :) Даже на работу не ходил. Слава богу у нас в это время термометр зашкаливал на границе -44 - -46 градусов по Цельсию. И свою хандру я выдал за отмазку о не заводившейся машине.
И вот перед новогодними праздниками, вдоволь наигравшись, но правда не пройдя игру, я выдал новую облегченную версию алгоритма, который подходил только под мои условия тайлов. Вычисления данных для оптимизации были не заметны на фоне генерации карты и количество полигонов снижалось в среднем на 40-50%.
Но появились артефакты при отрисовке воды, пришлось переписать все алгоритмы связанные с водой.
Вот результат:
Анатолий тем временем сделал юнит кочевья:
Пока он лежит отдыхает :)
В процессе работы над оптимизацией, мне пришла в голову идея как можно изменить наши горы.
Горы стали более рельефными, это заметно без текстуры, так как текстура теперь к ним не подходит:
По сетке так вообще отличия очевидны:
Осталось дело за малым — нужна новая текстура гор.
Следующим этапом пришлось переписать загрузчик ресурсов и генератор карты. Попутно переделав стартовое меню под эти все дела:
Теперь загрузка ресурсов идет параллельно и после чего начинается генерация карты.
Огромную работу проделал по разделению рендера на 3 потока. Вся сложность была в синхронизации. Теперь у нас один поток отвечает только за отрисовку, второй поток за перерасчет видимого пространства при передвижении камеры и прочих с взаимодействий с пространством карты, и третий поток отвечает за анимацию и связь с серверной частью.
И да, у нас теперь есть серверная часть отвечающая за все события в игре и за ИИ. В свою очередь каждый ИИ игрок это отдельный процесс.
Подведем итоги проделанной работы:
- Оптимизация графики с программной стороны.
- Оптимизация графики — модели.
- Серверная часть.
- Разбитие рендера на 3 потока.
- Предзагрузка ресурсов (текстур и моделей).
- Переписал шейдеры тумана войны, воды и террайна.
- Сократил потребление оперативной памяти на 20-30%
- Реализован ряд элементов UI
- Переделано стартовое окно с новым UI.
- Устранил ошибки в расчетах нормалей.
- Подправил холмы.
- Новые горы.
- Ввели нормалмапу для террайна.
- Новое выделение юнитов.
- Новая анимация юнитов.
- Окно дипламатии.
- Действия ИИ. Исследование карты.
- Действия ИИ. Дипломатический контакт.
- Действия ИИ. Заключение мира, дружбы или объявление войны.
- Действия ИИ. Действие юнитов при столкновении.
В общем была проделана огромная работа по оптимизации и не много по игровым механикам. Надеюсь в этом месяце в се пойдет по плану и я наконец-то допишу города :)
Спасибо за внимание!
Вступайте в нашу группу в ВК: https://vk.com/thegreattribes
Смотрите также:
Комментарии
Хороший отчет, 16 милионов полгинов на один экрна это конечно мощно :D
У меня сейчас в игре кст тоже есть проблема с производительности на одном ядре, но там проблема не в графике, а в алгоритмах ИИ юнитов и прочих штуках
alexprey, Я сразу закладывал потенциал на то что ИИ будут в отдельных потоках. Сейчас у меня получается не более 4 миллионов полигонов с новыми пальмами.
Конечно не рендерятся. Ну я бы не сказал что прям вот так проще :)
Zemlaynin, ну я к тому, что мне приходится просчитывать поведение для юнита почти в каждом кадре игры, чтобы он принимал решения. Хотя на самом деле возможно я что-то делаю не так и ИИ писать надо как-то иначе. Но пока что у меня почти каждый кадр происходит перерасчет приоритетов поведения юнита и потом самое приоритетное поведение исполняется.
CollectableItemData.cs
[CreateMenuItem(fileName = "newItem", menuName = "Data/Items/Collectable", order = 51]