Dagon 2
Переработанная и улучшенная версия Dagon, которую я разрабатываю с начала 2026 года. Архитектура движка осталась прежней, но внесено множество мелких изменений, и полностью переписан рендер, который теперь обеспечивает фотореалистичную графику. При этом он не требует более мощной конфигурации железа и работает на тех же видеокартах, что и Dagon 1.0 (я тестирую на GeForce RTX начального уровня).
Репозиторий: https://github.com/gecko0307/dagon2




Идеи для второй версии движка у меня начали копиться еще до выхода первой. Главным вопросом последних лет была, конечно, перспектива перехода на низкоуровневый графический API (и заодно на SDL3). Кроме того, многие техники и фичи современного рендеринга не слишком хорошо вписывались в архитектуру Dagon 1.0, поэтому я решил с ними повременить. То же самое касалось скриптового языка GScript, который я только в прошлом году довел до уровня применимости в реальных проектах. В общем, все, что я изучал и потихоньку пилил, не добавляя в Dagon 0.x/1.0, станет частью Dagon 2.0.
SDL3 и GPU API
SDL — штука фундаментальная. Первые шаги в разработке движка на D я делал еще в эпоху SDL 1.x. Эта чертовски хорошо написанная библиотека значительно упрощает достижение кроссплатформенности в мультимедийных приложениях: создание окна, инициализацию контекста OpenGL, обработку ввода. Постепенно я выстроил свой фреймворк вокруг оконной и событийной систем SDL, и он стал ключевым компонентом ядра Dagon.
На SDL2 я сидел очень долго и вплоть до недавнего времени не видел особых причин обновляться. Все изменилось с появлением GPU API, который мне показался идеальным компромиссом между тем, чтобы переходить на чистый Vulkan и оставаться на OpenGL 4.
Может возникнуть вопрос, зачем вообще куда-то переходить, если рендер на GL уже готов, отлажен и проверен временем? Если не прибегать к чистой риторике «современное – лучше», то вот вполне прагматические соображения:
- Vulkan быстрее за счет отсутствия валидации состояния в рантайме и явного управления проходами. Для рендера Dagon это большой плюс, так как он уже аккуратно разбит на изолированные проходы;
- Vulkan потоково-безопасен, что упрощает загрузку ресурсов из второго потока во время рендеринга. В OpenGL приходится делить процедуру загрузки на thread-safe и thread-unsafe стадии, а тут это не нужно;
- SPIR-V делает возможным кроссплатформенное кэширование шейдерных бинарей. Это значит, что в дистрибутив игры не обязательно класть исходники шейдеров – удобно для защиты интеллектуальной собственности (я не апологет, но все же);
- С Vulkan есть хотя бы гипотетическая возможность поддержки macOS. Хотя моя заинтересованность в этом остается минимальной (и у меня нет компьютера Apple), в теории Vulkan-приложения должны работать на macOS через MoltenVK.
Долгое время я думал, что будущее за WebGPU, а точнее, за его мозилловской реализацией wgpu, которую можно использовать в любых языках через враппер wgpu-native, но надежды пока совершенно не оправдываются. Сам стандарт пилят очень долго (W3C, как-никак), API wgpu-native жутко нестабилен, общий хедер с Dawn (гугловской реализацией) так и не достигнут. Плюс там очень громоздкие инициализующие структуры, которые мало где удобны, кроме как в JS. Странная система с bind group layout’ами и, наконец, мутная ситуация с шейдерными языками: не поймешь, то ли надо переписывать все на WGSL, то ли не надо… На этом фоне появление SDL GPU стало глотком свежего воздуха: наконец-то обертка над Vulkan/D3D12/Metal не на C++, не растоманская, с вменяемым и хорошо задокументированным API, который не перекраивается вдоль и поперек каждый месяц. Ну как тут устоять, тем более если уже есть поддержка в bindbc-sdl?
Классное определение SDL GPU дали на Reddit:
«One of the reasons that SDL even exists was to reduce the amount of platform-specific boilerplate code needed to create and configure an OpenGL window. Before SDL, it was a pain. It sort of sounds like SDL is now doing the same for Vulkan».
Спешу, однако, оговориться, что я пока не планирую поддерживать все три бэкенда. Dagon 2 будет только под Vulkan. О мультитаргете буду задумываться только после того, как успешно доделаю весь порт.
Нововведения
- Переработан
dagon.render. Deferred-рендеринг, пост-обработка и вывод теперь объединены в одну структуру; - Реализована поддержка отражений в экранном пространстве (SSLR);
- Шейдерный воркфлоу теперь основан на GLSL 4.60 и включает встроенный в движок компилятор GLSL в SPIR-V. Модули SPIR-V кэшируются на диск для переиспользования;
- Загрузчик текстур полностью основан на SDL3_Image и не использует
dlib.image.io. Поддержка KTX теперь является функцией ядра, а не расширением; - Тонмаппинг полностью основан на AgX. Все остальные операторы удалены. Реализованы изменяемые параметры для управления AgX Look (
offset,slope,power,saturation); - Изменилась семантика классов
SceneиWorld.Sceneтеперь является просто контейнером дляEntityи графических данных; для обработки ввода и кастомной игровой логики используетсяWorld; - Все
Entityпо умолчанию статичны, и их матрицы не пересчитываются каждый кадр, чтобы уменьшить нагрузку на процессор. Для динамических обновлений нужно включитьEntity.dynamicили использоватьEntityController(частичный аналог старомуEntityComponent); - Рендер теперь использует отдельную irradiance-карту для диффузного света (в Dagon 1.0 использовался максимальный уровень шероховатости specular-карты);
- BRDF LUT теперь генерируется в рантайме, а не загружается из файла;
- Физика Jolt теперь встроена в ядро движка в виде пакета
dagon.jolt; - Встроенная виртуальная машина GScript3. Скрипты пока компилируются внешней утилитой, Dagon только исполняет байт-код. Можно экспонировать скриптам любые функции и свойства игры.