Thunder Engine Development
34 subscribers
19 photos
14 links
Записки разработчика игрового движка. Чат канала @thunderengine_chat
Download Telegram
Решил сегодня немного поработать над рендером с использованием вулкана. В целом началось все довольно безобидно. Я исправил работу Bloom фильтра. (он конечно далек от идеального). И тут остро встала проблема, которая зрела довольно давно. А именно ресурс текстур требует небольших изменений. Дело в том, что у меня довольно неочевидно создаются текстуры, используемые в качестве рендер таргетов. Мне давно не нравился текущий способ их объявления. Так что сегодня я заделал рефакторинг этого ресурса. В целом, его формат не поменялся. Я добавил дополнительную систему флагов, которые можно устанавливать для ресурса. На их основе система будет создавать (или не создавать) CPU части для текстур.
1🔥1🤯1
А вы знаете что такое рендер таргеты?
Anonymous Poll
25%
Знаю
75%
Не знаю
Итак о Render Targets. Если вы работали с шейдерами, вы возможно знаете, что выполняющийся шейдер не может делиться результатами со своим соседом. Проще говоря, вычисляя цвет пикселя, вы не можете подсмотреть в тетрадку соседа, что-бы списать. На самом деле это возможно в очень лимитированном виде. Но иногда, этот момент критически важен. К примеру, когда вы делаете размытие или еще что-то подобное. И тут на помощь приходят рендер таргеты. Грубо говоря, ваши результаты будут записаны в виртуальную текстуру, а на следующем шаге, уже другой шейдер, сможет их прочитать и использовать в своих вычислениях. Применительно к размытию, мы сперва делаем размытие по вертикали, сохраняем результат в текстуру, а потом получившийся результат размываем по горизонтали. На самом деле рендер таргеты очень активно используются в любом графическом пайплайне. Для отрисовки света и фильтров пост-обработки.
6
Продолжая разговор о Рендер Таргетах (RT), поговорим о Frame Buffers (FB) и их связи с ними. FB - это по сути сущность "контейнер" для RT. Перед вызовом отрисовки, разработчик может указать в какой FB необходимо нарисовать. К FB, заблаговременно, присоединяются различные таргеты. Color Attachments и опционально Depth Attachment. Вероятно вы заметили, что Color Attachments стоит во множественном числе. Все верно! К FB можно подключать больше одного буфера цвета (обычно до 8), эта фича называется Multiple Rendering Targets (MRT). Она очень активно используется для создания рендеров, с поддержкой множественных источников света. О разнице между Forward Rendering и Deferred Rendering мы поговорим немного позже. Для отрисовки одновременно в несколько цветовых текстур, разработчик должен указать несколько out переменных (для GLSL).
4👍1
Вот уже неделю я нахожусь в неравной схватке с рендером на Vulkan. Постепенно, задачи, которые казались неподдающимися, постепенно сдаются под напором. Прочитано много документации. Многие аспекты стали намного ясней. Некоторые подходы, были существенно переписаны. Вот и сегодня, поддалась проблема с Ортогональной матрицей проекции. В OpenGL было все просто. Построил матрицу и живешь себе, радуешься. Но как только попробовал использовать ту-же матрицу на Vulkan. Меня ждал неприятный сюрприз. Экран предательски оставался черным. Т.к. у меня несколько окон используют вулкан, я сперва грешил на проблему с синхронизаций очередей отрисовки. Убил 3 дня на это. Но проблема оказалось банальной и одновременно не очевидной. Все дело в Clip пространстве для Z координаты вершины. В OpenGL оно выглядит так. -w < z < w а в Vulkan 0 < z < w. Иначе говоря Vulkan не любит отрицательные координаты в по Z в gl_Position.
3👍2🔥1
Так как же починить ортогональную матрицу проекции, что бы не сломать все в OpenGL и поддержать вулкан? Нужно переместить пространство Z из -1...1 в 0...1. И вот вам немного кода.
Было:
Matrix4 Matrix4::ortho(areal left, areal right, areal bottom, areal top, areal znear, areal zfar) {
Matrix4 result;

result[0] = 2.0f / (right - left);
result[5] = 2.0f / (top - bottom);
result[10] = -2.0f / (zfar - znear);
result[12] = -((right + left) / (right - left));
result[13] = -((top + bottom) / (top - bottom));
result[14] = -((zfar + znear) / (zfar - znear));

return result;
}
2
Стало:
Matrix4 Matrix4::ortho(areal left, areal right, areal bottom, areal top, areal znear, areal zfar) {
Matrix4 result;

result[0] = 2.0f / (right - left);
result[5] = 2.0f / (top - bottom);
result[10] = 1.0f / (znear - zfar);
result[12] = -((right + left) / (right - left));
result[13] = -((top + bottom) / (top - bottom));
result[14] = znear / (zfar - znear);

return result;
}
Сегодня, как и было обещано, релизнул новую версию своего игрового движка! Было сделано много улучшений и еще больше исправлений! Благодаря обратной связи от Павла, добавил несколько полезных функций, о которых раньше не задумывался. Больше деталей можно прочитать в Release Notes:
https://github.com/thunder-engine/thunder/releases/tag/2024.2
🔥41👍1
Итак, продолжим разговоры о графене. Как и обещал, поговорим Forward и Differed rendering. Изначально весь рендеринг был forward. Но что это значит? Это значит, что для рисуемого объекта сразу просчитываются эффекты и освещение. В ранних версия OpenGL (в до шейдерную эпоху) источники освещения задавались прямо из API. OpenGL поддерживал до 8 источников на экране. Но, что делать, если нужно больше? И нужны более гибкие настройки источников? Вот тут мудрые разработчики и придумали Deferred Shading (навел справки: 1988 год). Смысл подхода заключается, в дополнительном проходе формирующим Geometry Buffer (G-Buffer) в котором содержится вся необходимая информация. А свет просчитывает Отложено в экранном пространстве учитывая информацию из G-Buffer. Таким образом мы получаем поддержку огромного количества источников света. Возможность делать пост обработку на типа SSLR и SSAO. Однако, у этого метода есть один существенный минус. Если мы рисуем полу прозрачную поверхность. В G-Buffer не поместится (адекватно) информация о поверхности, находящейся под прозрачной. Так же не работает дефолтный антиалиясинг. Плюс, G-Buffer занимает дополнительную память (уже не так критично сейчас). Проблему полупрозрачных поверхностей решили третьим проходом. На первом проходе рисуются непрозрачные объекты. Потом накладывается свет. А потом, через Forward Pass, рисуются полупрозрачные объекты с ограниченным количеством источников света, влияющих на них.
🔥41
В для каких случаев подходит Forard, а для каких Deferred? Все очень просто. Если у вас мало динамических источников света (2D игры или простенькие 3Д игры со стилизованной графикой и малым количеством источников). Оптимальней использовать Forward если вы хотите море света то Deferred ваш выбор. Есть еще более продвинутые техники. Может быть когда-нибудь поговорим и о них.
👍41
Когда пишешь кроссплатформенный игровой движок. Всегда приходится смотреть на то, как поддерживается та, или иная фича графического API. Особенно это касается мобильных платформ. OpenGL ES очень аскетичен в этом плане. Вот так и сегодня. Только я хотел добавить поддержку Geometry Shaders. Как выяснилось, что они доступны только в ES 3.2. А это значит, что iOS платформа идет лесом. Так-же потенциально WebGL (когда-нибудь я до нее доберусь!). Похожая ситуация была и Shader Storage Buffer Objects на прошлой неделе. Похоже что, миграция на новые API становится все более актуальной =(
💔2🦄2🔥1
Простите. что давно ничего не писал. На данный момент я занят переработкой формата описания графов в редакторе. Хочу его сделать более читаемым для человеков. Так-же решил попробовать поучаствовать в Ludum Dare джеме с использованием своего движка. Надеюсь он не подкачает. Цель, сделать простенькую игру и выявить проблемные места.
6
Наконец доделал рефакторинг внутреннего формата описывающего графы в редакторе. Он стал гораздо компактней и читабельней. А, так-же есть задел на расширение функционала без изменения структуры формата. Я надеюсь, что не привнес слишком много новых багов. Задачка была не из простых.
👍4
Fixed:
Editor: "Local" property in particle editor is not saving #728
Editor: Add actor/component menu is not working in prefab #727
Editor: Areas on a Sprite are not saving #726
Editor: Infinite loading when import .wav file #725
2🔥1
ГОСПОДИ! Я сейчас поймал, наверное, самый странный баг, в своей жизни! Я убил добрых 2 часа на попытки понять, в чем же дело! В какой-то момент, у меня просто перестал загружаться один из плагинов редактора. Повторная сборка проекта с нуля не помогла. Откат на более старую версию кода тоже не помогал. Я проверил все зависимости библиотек. Проверил на срабатывания системы безопасности, которая могла блокировать загрузку. НИ-ЧЕ-ГО! Я уже начал сомневаться в своей адекватности и вере в человечество. И чисто, в приступе отчаяния, я убрал все Brake Point в дебагере. И оно ЗАРАБОТАЛО! Я не понимаю, как бряка роняла динамическую загрузку библиотеки! Но это факт!
😁4
Fixed:
Editor: Color constant is resetting in material editor #734
Editor: Deletion of Node in the MaterialEdit leads to crash #736
Audio: Sounds are not playing in the editor or in the game #738
Editor: Crash after relocating project assets #741
Editor: Project is not opening after creating new AngelBehaviour asset #744
Editor: Prefab window is not reopening after being closed #748
👏2
Выходные + понедельник выдались очень жаркими. Участвовал в составе команды в Ludum Dare гейм джеме. К сожалению, в последний момент, пришлось отказаться от использования собственного движка, из-за найденных проблем. Решили использовать Unity. Была проделана титаническая работа за эти 3 дня. Результат вы можете посмотреть тут.
5👍3
Целую неделю работал над рефакторингом того, как рисуются объекты в движке. Инстансинг был у меня и ранее, но он был не удобен в поддержке, того как уникальные данные передавались в шейдер. Мне известны 3 относительно честных способа передать эти данные. 1. Через вершинные атрибуты (так было раньше). 2. Через Uniform буфер. (ограничение на размер). 3. Через текстуру (Требует большое количество семплов, что может замедлить работу). В конечном итоге я пошел по пути Uniform буферов. Этот метод используется в том числе и крупными движками. Ограничения в UBO 65536 байт на буфер. Если использовать минимум параметров в шейдере этого хватит на 1024 объекта на 1 вызов отрисовки (это максимум). Если параметров у шейдера будет больше, то это количество снизится. (в будущем при использовании SSBO на тех платформах которые его поддерживают это ограничение можно существенно увеличить). Была проведена колоссальная работа по рефакторингу. Переделан подход того, как в целом рисуется объект. Генератор шейдеров так-же, в очередной раз, был доработан. Теперь стало намного понятней как организовать автоматический инстансинг в игре!
4👍1
После замечательного рефакторинга инстансинга в движке, наконец сложился пазл на счет поддержки автоматического инстансинга. Итак, сегодня я сделал первую версию поиска и группировки объектов, подходящих для объединения. Так-же вчера успел добавить поддержку SSBO буферов для десктоп платформ. В целом очень продуктивные выдались выходные!
👍6
Ох давненько я ничего сюда не писал. Все дело в том, что я последнее время занимался игровым проектом который мы вместе с ребятами продолжали делать после Людума. Времени на движок практически не оставалось. К сожалению в сутках слишком мало часов. Но вот я поехал в отпуск и решил позаниматься движком по грею брюхо. Купил себе макбук и наконец решил позаниматься его поддержкой.
3👍3
Оказалось, что Qt поддерживает Apple Silicon только с 6 версии. И я потратил кучу времени на поддержку этой версии библиотеки. Я планировал в будущем отказаться полностью от Qt, но на данный момент, это не представляется возможным. Слишком много на него сейчас завязано. В связи с этим, эта работа кажется немного бесполезной. Хотя, вероятно, полный отказ займет год, минимум. Так, что, возможно Qt еще поживет в каком-то виде. От чего я действительно избавлюсь в первую очередь, так это от QML. Ненавижу блять QML
🤔1😢1