TehnoMagEG

TehnoMagEG

Soon™ Временно отвалился на пока хз какое время. Надеюсь, не на долго
Пикабушник
Дата рождения: 3 июля
8043 рейтинг 30 подписчиков 9 подписок 75 постов 3 в горячем
Награды:
10 лет на Пикабу
4

Relict Engine: DevLog 20260604

Серия Relict Engine

Краткий список изменений

  • Удален юнион UniformValue, как ненужный и не используемый

  • Заменена функция Set на шаблон с предопределёнными типами для удобства

  • UniformType удален из движка и используется только для разбора входных динамических параметров материала в RatTools

  • Замены легаси OpenGL буферы на DSA в коде создания динамических экземпляров (Instancing) материалов

  • Создание инстанций, кроме инстанции по умолчанию, теперь используют прямое копирование данных на стороне GPU, заместо заполнения буфера через шину

  • Добавлена заготовка под шейдерный домен Surface на основе физически корректного рендеринга (PBR)

Комментарий

Думается мне, тему инстансов на этом можно закрыть. Оно работает как нужно, параметры определяются, обновляются, читаются и рисуются ровно так, как требуется.

Для закрытии самой темы материалов осталось реализовать только вставки пользовательского кода в скрипт материала. Думаю, завтра/послезавтра уже сделаю. SPIR-V контейнеры отложим в долгий ящик. Сейчас это явно не приоритет.

Следующий этап - класс камеры и юниты источников света (чтобы можно было начать полноценную работу над PBR)

Показать полностью
5

Relict Engine: DevLog 20260602

Серия Relict Engine

Краткий список изменений

  • Ассет материала теперь содержит отдельный блок с возможными вводными параметрами шейдера по умолчанию отдельно от юниформов шейдера меатерила

  • В шейдер введен макет std140 для юниформов

  • Добавлен отдельный класс в модуле рендера для работы с инстанциями материалов через Uniform Buffer Object (UBO)

  • Для материалов, имеющих хотя бы один input параметр создается инстанция по умолчанию со значениями юниформов по умолчанию, с запретом на изменение

  • Добавлено "ленивое" создание инстанций на стороне модуля отрисовки по мере необходимости

  • Исправлена синхронизация потоков при передаче параметров инстанции материала. Теперь утилизируется uniq_cmd потока отрисовки вместо прямой установки

Комментарий

Переделал инстанции материалов на UBO. Все еще считаю их несколько сырыми и буду их еще какое-то время тестировать и дописывать их код. Кратенько опишу как это работает.

Во первых: UBO требует в шейдере макетной структуры, и поля в ней не могут иметь инициализаторов, поэтому пришлось написать довольно массивный парсер параметров с утилизацией variant и type_identity

glsl именной uniform макет

glsl именной uniform макет

сущности парсера инпутов при импорте материала в движок через RatTools

сущности парсера инпутов при импорте материала в движок через RatTools

Во вторых: эта структура требует выравнивая данных, поэтому, уже на стороне движка пришлось делать особую уличную магию перегоняя сырой буфер в выровненный cогласно стандарту

msvc считает что она дофига умная и настойчиво требует cSize обернуть в sizeof()

msvc считает что она дофига умная и настойчиво требует cSize обернуть в sizeof()

В третьих: чтобы не пересоздавать UBO буфер каждый раз, пришлось высчитывать офсеты юниформов и хранить их отдельно в виде пары офсет-размер. Таким образом при изменении одного параметра, в GPU отправится только он.

а вот от текстовой метки до конца так и не удалось избавится, благо у unordered_map итерация идет как 0(1)

а вот от текстовой метки до конца так и не удалось избавится, благо у unordered_map итерация идет как 0(1)

ну и в четвертых, т.к. действие происходит сразу в двух потоках (игровом и отрисовки), то на выходе получается довольно много операций копирования (ссылки не доживают до исполнения очереди)

В общем снова на очереди вычитка, удаление старого кода, правка нового. Что-то упростить можно, структуры собрать в одном месте, чтобы не были раскиданы по юнитам. Возможно, выбросить нафиг union, ибо от него сейчас пользы никакой уже, но зато сильно меньше удобства при обновлении переменной юниформа, или обертку над ним хотя бы сделать удобства для.

было/стало. SetVector3 выглядит как-то более удобоваримо

было/стало. SetVector3 выглядит как-то более удобоваримо

Показать полностью 5
8

Relict Engine: DevLog 20260529. MaterialInstance

Серия Relict Engine

Краткий список изменений

  • Добавлена смена рабочий директории на необходимую (давно надо было сделать, но все забивал)

  • Добавлена первая итерация материал инстансов (в очень сыром виде, но работает)

Комментарий

Касательно инстанций, значит. Передал несколько класс шейдера. Пока по тупому, в лоб. На выходных надо будет все это просмотреть, вычитать еще раз, и переписать по человечески. А работает это так:

  • При инициализации контекста дергаются ассеты материалов на загрузку. и передаются в GLShaderProgram

  • GLShaderProgram это дело компилирует, проверяет и линкует (когда-нибудь потом будет добавлен кэш, но пока рассчитываем на кэш драйвера)

  • После этого проходится по инпутам, собирая их в 100500 мапов

индуский код во всей красе, так еще и не все типы реализованы.

индуский код во всей красе, так еще и не все типы реализованы.

  • При отрисовке, если на юнит выставлен инстанс, а не сам материал, проверяет в таблице инстанса по текстовой (!) метке наличие установленного параметра.

Выставляем инстансы, но не задаем параметры. При инициализации рассчитываем на дефолт юниформа в шейдере (но можно и выставить при желании)

Выставляем инстансы, но не задаем параметры. При инициализации рассчитываем на дефолт юниформа в шейдере (но можно и выставить при желании)

  • Если текстовая метка присутствует в мапах класса инстанса (там столько-же мапов, по одному на тип), то передает в шейдер значение из него, если нет, то из таблицы дефолта.

длинный и грустный switch. Я не буду показывать эту портянку

длинный и грустный switch. Я не буду показывать эту портянку

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

Но зато даже в таком виде оно работает.

Простенький примерчик:

Меняем цвет кубиков раз в секунду

Меняем цвет кубиков раз в секунду

Показать полностью 4 1
5

Relict Engine: DevLog 20260525

Серия Relict Engine

Краткий список изменений

  • Добавлена заготовка под MaterialInstance

  • Добавлена обработка ключевого слова input в парсере скрипта материала

  • Добавлена дополнительная проверка и автоматический выбор параметра max_concurent_taks в случае, если в конфиге параметр равен нулю

  • Добавлено исключение, в случае, если процессор поддерживает менее 4х потоков

  • Добавлен программный ограничитель кадров в графическом потоке

  • Изменена сортировка рендера с сортировки по геометрии на сортировку по шейдерам для уменьшения кол-ва переключения контекста шейдеров OpenGL

  • Исправлена ошибка при запуске RatTools приводящая к полному запуску движка

  • Исправлено редкое исключение при обработке очереди AsyncTask разными потоками из-за неучтенного состояния гонки при проверке на пустую очередь

Комментарий

Готовлю движок для внедрения инстансов материалов, чтобы максимально сократить кол-во переключений контекста шейдера (материал == шейдер). Возможно еще проведу оптимизацию по vao - собирая определенные меши в один длинный буфер (сейчас один буфер - один меш + лоды). Однако там есть нюанс с динамической выгрузкой сеток и пересчетом индексов и вообще там не все так очевидно, да и прирост по кадрам не то чтобы прямо большой. Я бы даже сказал не заметный. Т.ч. возможно это того и не стоит, т.к. функция glBindVertexArray всего-лишь перещёлкивает указатель на уже загруженный в GPU буфер. Подумаю, в общем, ибо сейчас это не горит.

Инстанс Материала

Особый класс, который можно создать как вручную, так и загрузив через заранее подготовленный ассет. Содержит перечень переменных со значениями для передачи через uniform шейдера. Привязывается к Материалу(шейдеру) и используется как надстройка над материалом для ускорения процедуры отрисовки.

Показать полностью
8

Relict Engine: DevLog 20260521

Серия Relict Engine

Краткий список изменений

  • Добавлен дополнительный интерфейс IThread

  • Добавлен класс GameThread

  • RenderThread перенесен из реликта RenderCore в Core

  • Все семейство классов Thread вынесена из фреймворка RelictClass в обычные классы

  • Исправлена работа сборщика мусора при удалении объектов с владельцем в другом потоке

  • Исправлена работа сборщика мусора при закрытие движка

  • Исправлено завершение потоков семейства Thread в Linux

Комментарий

Мультипоточность отлажена на столько, на сколько это на данном этапе возможно. Движок работает стабильно в обоих целевых ОС. Правда кое-что пришлось таки переделать. В частности Потоки теперь не являются частью фреймворка RelictClass, теперь это самые обычные Сишные классы. Появился дополнительный класс потока GameThread, который по факту не является потоком, но абстракцией над основным потоком приложения. Соответственно изменены и метапараметры RelictClass. Теперь заместо класса потока передается указатель на объект потока. Это добавит в будущем немного сложности, если нам понадобятся пул воркеры, но на данном этапе это сильно упростило жизнь при синхронизации объектов.

Показать полностью
6

Relict Engine: DevLog 20260517

Серия Relict Engine

Краткий список изменений

  • Добавлен интерфейс IWorkerThread

  • Добавлен класс RenderThread

  • Добавлена обработка очереди сообщений

  • Добавлен функционал проверки текущего контекста потока в рамках привязанного контекста к мета классу

  • Добавлено ограничение по минимальному времени тика в главном потоке (по умолчанию 60 раз в сек)

  • Изменена работа Сборщика мусора для работы с разными контекстами потоков

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

  • Изменена работа тикера для работы с разными контекстами потоков для правильной работы флагов ClassInitializer

  • Исправлен access_violation при удалении RenderObject в случае, если он привязан к уже удаленному VAO

Комментарий

Ну вот мультипоточность и заработала. Есть еще косяки в Сборщике мусора, и возможно еще по ходу дела вылезут, но тем-не-менее я доволен как слон.

Ну и результат на большом fps:

Показать полностью 1
4

Relict Engine: Многопоточность

Серия Relict Engine

Давайте вернемся немного назад, а именно к посту Relict Engine: ThreadManager и DevLog 20250822, где я говорил о сущностях ThreadManager и AsyncTask. Теперь пришло время несколько расширить этот функционал.

В предыдущем девлоге я упомянул, что нужно развести основной поток и процедуру отрисовки. Собственно этим и займемся. Ведущим потоком у нас все равно будет выступать основной поток приложения (от этого как не крути никуда не деться), а рендер уйдет в отдельный поток со всеми своими объектами.

Основных проблем при работе с воркерами (потоки с бесконечным циклом) в нашем случае будет три:

  1. Т.к. рендерер построен на фреймворке TRelictClass, то необходимо убедится, что экземпляр созданного класса не выходит за рамки контекста потока, для которого он был создан.

  2. Вытекающее из первого: Сборщик мусора должен понимать, в каком потоке находится регулируемый им объект.

  3. Передача данных из главного потока в рендер поток.


Проблема 1

Ее предполагается решить, с помощью добавления дополнительной структуры в ClassInitializator
вида:

enum ThreadType : uint8_t
{ THREAD_MAIN = 0,

THREAD_RENDER = 1 << 0,

THREAD_CUSTOM = 0xff

};

struct ThreadInitializer

{

ThreadType Thread = THREAD_MAIN;

uint64_t CustomThreadId = 0;

};

Таким образом мы сможем убедится, что создание/удаление экземпляров этого класса будет доступно исключительно в контексте указанного потока. Вызовы же функций, в случае, если они не являются потоко-безопасными, стоит ограничить специальными вызовами проверки контекста.

Как пример:

[Fatal] 2026-05-16 13:34:38.277 GMT+3 - Trying to create new object Relict::Renderer with name Renderer_S in incorrect thread context


Проблема 2

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


Проблема 3

Передачу данных предполагается организовать с помощью очереди команд, представляющие из себя лямбда-функции и передающие в поток нужные данные. Так-же, в теории, механизм AsyncTask через делегат OnTaskFinished так-же сможет безопасно передать данные в нужный нам поток (но с нюансами).


Мысли

Т.к. Relict Engine пишется на 20м стандарте C++, то нам доступны замечательные вещи: jthread и queue из std библиотеки. Таким образом, мы, в принципе, сможем отделаться лишь одной дополнительной сущностью - классом потока, в котором, через queue будет определена очередь команд на исполнение, контекст сборщика мусора и, собственно, цикличная функция обработки этого всего дела. Конечно нужно будет доделать ThreadManager, чуть поменять очередность инициализации движка, и Сборщик мусора (для определения контекста потока из которого его дернули). Мета объект Class оставляем в основном потоке - нам в принципе все равно из какого контекста его дергают, если это не создание или не удаление объекта. Так-же стоит организовать ограничитель частоты цикла потока с выводом параметра ограничения в конфиг.

Показать полностью
9

Relict Engine: DevLog 20260511

Серия Relict Engine

Краткий список изменений

  • Добавлен временный контейнер RAT для подготовленного GLSL

  • Добавлена временная обработка GLSL движком

  • Добавлен Simple домен шейдера

  • Добавлена первая итерация рендера статичных сеток

  • Исправлено заполнение индексного буфера VAO

  • Исправлен access violation при вызове метода SetAsset юнита сцены с аргументом nullptr, в случае, если до этого вызова для юнита не было установлено никакого ассета

  • Исправлен переключатель vsync для контекста OpenGL

  • Исправлена очистка буфера вывода графического api в начале кадра

  • Исправлено "залипание" буферов парсера RatTools при последовательной обработке нескольких материалов

  • Исправлено смещение индексного буфера статичного меша при отрисовке мультиматериала

Комментарий

Ну что-ж. Худо-бедно движок рисовать простенькие сетки научили. Теперь это не просто залипушный код, а уже полноценный пайп, основанный на правилах и логике работы движка.

кубик с мультиматериалом (есть косяк с наложением, но я похоже в blender накосяпорил с вершинами)

кубик с мультиматериалом (есть косяк с наложением, но я похоже в blender накосяпорил с вершинами)

[UPD: нет, косяк в ретрансформе, правда пока не понятно в чем именно конкретно, но плейн второго материала уходит на 1 кадр вперед от предыдущего, хотя используется общий кэш юнита. Возможно предикшен CPU инструкций шалит]

Исправлено. Действительно предикшен, но не CPU, а шейдерная каша

Теперь нужно сделать самое, наверное, главное - вытащить отрисовку в отдельный поток

игровые тики нужно разводить с процедурой отрисовки

игровые тики нужно разводить с процедурой отрисовки

И поставить отдельные настраиваемые таймеры для этих потоков. Таким образом я хочу получить довольно плавную картинку как при высоком, так и при низком фреймрейте, и, соответственно, управляемую кривую накопления погрешности в математике при работе с числами с плавающей точкой.

Параллельно, конечно, буду допиливать шейдеры для работы через SPIR-V прослойку - там не много, но нужно разбираться, как либу собрать так, чтобы ее можно было нормально интегрировать в RAT.

Показать полностью 2
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества