В новой версии движка дебютирует физический движок Jolt Physics, в виде расширения dagon:jolt. Он предоставляет примерно тот же набор возможностей, что и Newton, при этом он лучше оптимизирован под многоядерные процессоры, а также имеет встроенный контроллер персонажа, который работает более стабильно, чем старый NewtonCharacterController. Newton, однако, в обозримом будущем никуда не денется, оба расширения будут развиваться параллельно. Я планирую также добавить поддержку встроенного симулятора автомобиля Jolt — об экспериментах с ним напишу как-нибудь в отдельном посте.
Исправлен микростаттеринг, связанный с неверной работой главного таймера. Визуально это проявлялось в виде периодических скачков изображения, заметных при движении камеры. Свойство stepFrequency переименовано в updatesPerSecond, в классе Application и в settings.conf.
Добавлены новые цветовые профили вывода: линейный (gl.outputColorProfile = "Linear") и Gamma 2.4 (gl.outputColorProfile = "Gamma24").
Добавлено новое свойство Entity.autoUpdateTransformation. Если его отключить, то Dagon не будет автоматически обновлять матрицы трансформации Entity. Это нужно, главным образом, в компонентах, которые заменяют встроенную трансформацию своей собственной математикой.
Реализована поддержка кинематических тел в dagon:newton. С их помощью можно реализовать, например, движущиеся платформы. Также добавлены новые свойства NewtonRigidBody: bodyType, collisionShape, angularVelocity, acceleration, linearDamping, angularDamping, simulationState, collidable, sleepState, autoSleep, freezeState, gyroscopicTorque и новые методы setMassMatrix, setMassProperties. В контроллере персонажа исправлено застревание в стенах при прыжке.
В dagon:audio добавлены новый метод AudioManager.setPlaySpeed и опциональный параметр громкости в методах SoundComponent.play.
Как я уже не раз отмечал, игровая физика — это крайне недооцененный вид софта. Люди много говорят о графике, обыватель в играх вообще ничего, кроме графона, не замечает. А между тем, проверка столкновений и физика — вот что по-настоящему важно. Устаревший визуал и любительский уровень моделей игре можно простить, но проваливание персонажа сквозь пол и стены — нет. Я видел множество инди-проектов, потенциал которых был загублен именно плохой физикой (и, как следствие, неудобным управлением), а не графической или геймплейной составляющими. В мире инди и СПО вообще редко связываются с «физичными» жанрами типа экшнов, гонок, симуляторов и т.д. Свободные игры — это в основном стратегии, песочницы, 2D-аркады, рогалики. Физика довольно устойчиво ассоциируется с AAA и колоссальными бюджетами крупных издателей. Причина, конечно, в том, что она непредсказуема и плохо программируется. Она хороша в «чистом» виде — скажем, в симуляторе бильярда, где простая геометрия и нет вычислительно сложных ситуаций. Но если физика должна быть подчинена игровой логике, а не наоборот, то решения «по учебнику» резко перестают работать, приходится изобретать невиданные хаки и решать дичайшие корнер-кейсы. Это и отличает AAA от любительского геймдева — там коммерческие секреты, ноу-хау, огромный опыт. Я вот давно уже пишу контроллеры персонажа и не понаслышке знаю, как это непросто. А ведь хочется получить этот священный Грааль — чтобы персонаж свободно двигался по карте, не застревал, правильно сталкивался с препятствиями, поднимался по склонам и лестницам. Сегодня это необходимая база для 3D-игр любого жанра, кроме совсем уж простеньких.
Я пробовал писать собственный физдвижок (dmech). Это был очень полезный опыт, но, взвесив все «за» и «против», я все-таки решил использовать то, что сделано профессионалами — я ведь не физик, а графический разработчик. Пусть каждый занимается тем, что лучше всего получается. Я выбрал Newton Game Dynamics, который долгое время был, пожалуй, самым оптимизированным и точным среди всех, что имеют C-интерфейс. Это отличный физический движок, и я очень благодарен Хулио Хересу за этот проект, Newton много лет был прекрасным дополнением к Dagon. Я долго не хотел его менять, но технологии не стоят на месте. Newton 3 заметно устаревает, а Newton 4 — это уже чистый C++ без C-враппера, поэтому настало время переходить на что-то альтернативное. Есть серьезные основания полагать, что новым стандартом индустрии станет Jolt Physics от Guerrilla Games. Jolt используется в их движке Decima, лежащем в основе серий Horizon и Death Stranding — редкий случай, когда технология AAA-уровня сразу переходит в Open Source! Jolt — это реальный конкурент PhysX и Bullet, многие бесплатные и свободные игровые движки уже переходят на него один за другим: Godot, NeoAxis, Dagor. И, что самое замечательное, к Jolt есть полноценный C-враппер, позволяющий использовать его не только в C++.
Итак, что же там такого уникального? Во-первых, отличная оптимизация под SIMD и поддержка многопоточности (правда, это имеет значение лишь при каких-то редко встречающихся высоких CPU-нагрузках). Во-вторых, изначальная ориентация на игры — дизайн и набор фич показывают, что Jolt разработан игроделами для игроделов, для реального продакшна, а не академических публикаций. Движок ощущается, как некий «бесплатный Havok» из закромов энтерпрайза. У него много архитектурных особенностей, но в целом с ним очень приятно работать. Например, очень понравилось, что структуры векторов и кватернионов в Jolt бинарно совместимы с моими родными Vector3f и Quaternionf. Да и сама синхронизация через позиции и кватернионы вместо матриц 4×4 — это мудро, так как матрицы требуют декомпозиции.
Я, пока писал этот пост, уже успел написать для Dagon базовую обертку над Jolt (расширение dagon:jolt), концептуально весьма близкую с dagon:newton. Движки во многом похожи — используется классическая схема с разделением на тела и полиморфные шейпы. Многие функции имеют более удобный API, чем в Newton — например, рейкастинг. В данный момент обертка поддерживает создание статических и динамических тел, шейпов всех видов, включая меши, а также базовый контроллер персонажа, который я планирую довести, как минимум, до уровня NewtonCharacterController. К релизу Dagon 0.41 будут добавлены сочленения.
Контроллер персонажа CharacterVirtual особенно порадовал: я решил сразу попробовать его в деле. Шикарно, что управление контроллером (включая гравитацию и прыжок) осуществляется путем произвольного изменения вектора скорости — можно реализовать любую механику. Контроллер стабильный и точный, встроенный ground-тест работает надежно — основа для игры от первого лица пишется буквально за один вечер.
В Jolt есть поддержка мягких тел и даже встроенный симулятор автомобиля! Очень надеюсь, что когда-нибудь все это тоже получится перенести в dagon:jolt.
Использовать расширение не сложнее, чем dagon:newton, а в чем-то даже проще. Сначала нужно вызвать joltInit для инициализации:
Поддержка Web Assembly в LDC существует достаточно давно, и я когда-то уже делал экспериментальный мини-проект — приложение с треугольником, рисующимся через OpenGL ES, которое можно скомпилировать как под десктоп, так и в WASM-модуль. Для этой работы пришлось написать минимальную замену стандартной библиотеке, поскольку поддержка WASM в Phobos чуть более, чем никакая. Надеюсь изменить эту ситуацию в dlib2 — dcore уже сейчас можно собрать под WASM!
Например, вот такой «Hello, World» на десктопе печатает в стандартный вывод, а в браузере — в консоль, причем с поддержкой UTF-8:
module main;
import dcore.stdio;
extern(C):
void main()
{
// Minimal cross-platform betterC application.
// Will print to stdout on desktop and to the console in browser.
printf("Hello from D! Привет из D!\n");
}
В ближайшее время напишу пост по статусу dlib2 и всем деталям планируемых фич.
Багфиксы и улучшения в MiniGL
Актуализировал и чуть доработал MiniGL, мой программный растеризатор. Исправил альфа-смешивание, а также теперь можно отключить запись и чтение z-буфера для отрисовки экранных спрайтов. Обновил также демонстрационное приложение — теперь это почти готовый движок для коридорных ретро-шутеров: есть проверка столкновений со стенами, стрельба магией и спрайт оружия.
Выпустил новую версию Dagon. В загрузчике OBJ наконец-то появилась поддержка групп — если в файле присутствуют группы, они будут доступны через свойство OBJAsset.groupMesh, так что вы можете использовать их в качестве отдельных мешей вместо единого OBJAsset.mesh. Также загрузчик теперь не падает на моделях с N-гонами, а выводит предупреждение, что они не поддерживаются.
Добавлен новый экстра-шейдер dagon.extra.starfieldsky — ночное небо со звездами. Он представляет собой улучшенную версию шейдера звездного неба из демки с планетой. Основное нововведение — поддержка мерцания звезд.
Слегка переделан NewtonCharacterComponent: появился новый параметр радиуса. Логика теперь следующая: контроллер персонажа, как и прежде, представлен двумя Newton-сферами, но их радиус теперь задается пользователем, а не вычисляется автоматически. Сферы располагаются сверху и снизу от барицентра на расстояниях, которые вычисляются исходя из радиуса и роста персонажа.
В dagon:iqm появились новые свойства для анимированных моделей: Actor.looping (зацикленность), Actor.state.finished (индикатор завершения текущей анимации). Исправлен баг с фейсгруппами при загрузке некоторых IQM.
Вышла новая версия dlib. В библиотеке появился новый пакет dlib.math.random с реализацией генератора псевдослучайных чисел на основе C-функции rand. Проделан ряд улучшений в математическом пакете: добавлена поддержка компилятора GDC в модуль dlib.math.sse, появилась новая функция интерполяции bezierQuadratic.
Количество скачиваний dlib в реестре DUB достигло 1400 в месяц — рекордный показатель за все время существования проекта!
Подготовка к релизу Dagon 0.16
Новая версия Dagon планируется к выпуску совсем скоро — на днях внес ряд багфиксов и улучшений в физику Newton (в частности, исправлен прыжок контроллера персонажа на плоских поверхностях), а также добавил встроенную функцию создания скриншотов — Application.takeScreenshot.
Демка с физикой автомобиля, которую я разработал в начале этого года для Patreon Sponsor Folder, теперь доступна на GitHub в репозитории https://github.com/gecko0307/vehicle-demo — с многочисленными улучшениями, которые я сделал за последние месяцы (в частности, появилась поддержка модели трения колес Pacejka Magic Formula). Пруф того, что на основе связки Dagon + Newton вполне можно написать гоночную игру. Как-нибудь, возможно, напишу подробную статью на эту тему.
Выпустил новую версию движка. Основное нововведение — рефакторинг системы текстур: в частности, текстуры теперь могут быть загружены напрямую, без необходимости создавать объект SuperImage, что позволяет создавать текстуры любого формата, поддерживаемого OpenGL — таким образом, достигается лучшая совместимость с DDS. 2D-текстуры и кубические карты объединены в один класс Texture, и работать с ними стало проще. Появилась поддержка формата сжатия ASTC.
Классный подарок на Новый год: на днях наконец-то вышел Newton 4. Скомпилировал, потестил — очень понравились производительность и точность в сценах с большим количеством тел, а также примеры с физикой автомобиля. К сожалению, пока нет C-интерфейса, поэтому невозможно написать биндинг для D, но, похоже, работа в этом направлении ведется (разработчики планируют использовать SWIG, либо собственный генератор API для произвольных языков).
Вышла новая версия движка Dagon. Главное нововведение в этом релизе — поддержка моделей в формате glTF (gltf+bin). glTF представляет собой текстовое описание трехмерной сцены на основе JSON, хранящее всю информацию, необходимую для ее отрисовки (граф, материалы, текстуры и т.д.). Главной особенностью glTF является лейаут, оптимизированный по скорости загрузки — для передачи в графические API данные из glTF практически не нужно декодировать или конвертировать, поэтому сцены загружаются очень быстро.
Также значительно улучшен загрузчик текстур в формате DDS. Список поддерживаемых пиксельных форматов расширился (в частности, 32- и 16-битными RGBA с плавающей запятой), появилась поддержка кубических карт и mip-уровней. К примеру, теперь стало возможно загружать кубические карты с предрассчитанными зеркальными лепестками (specular lobes) для разных уровней шероховатости. Декодирование неигровых форматов изображений (PNG, JPEG и др.) в Dagon теперь осуществляется при помощи библиотеки stb_image, что в разы ускорило загрузку ресурсов. Как бесплатный бонус — появилась поддержка формата PSD.
Добавлен новый эффект постобработки Depth of Field (расфокусированность) с реалистичным боке и настройками оптики. Исправлены некоторые баги постобработки и отложенных эффектов — в частности, устранен артефакт «черных точек».
На смену встроенному физическому движку dmech идет привязка к Newton Dynamics, реализованная как расширение dagon:newton (подключается к проекту как отдельная зависимость). Newton предоставляет отличный компромисс между производительностью и стабильностью симуляции, поддерживает все стандартные геометрические тела, а также поддержку физики для ландшафтов и произвольных объектов (автоматически генерирует выпуклые оболочки для мешей).
Был значительно улучшен движок Dagon: добавлена поддержка декалей, трубчатых источников света и «фонариков», кубических карт окружения. Благодаря сторонним разработчикам появилась поддержка рендеринга ландшафтов, в том числе процедурных с использованием шума OpenSimplex, а также интеграция GUI-тулкита Nuklear. Были полностью переписаны рендер и система постобработки в Dagon, упорядочена структура модулей движка, внесено множество оптимизаций производительности, реализован эффект объемного рассеяния света в атмосфере (volumetric light scattering) для направленных источников света. Mateusz Muszyński на основе Dagon и Nuklear написал клон Sokoban с редактором уровней.
Я начал работу по интеграции физического движка Newton Dynamics в Dagon в рамках проекта dagon-newton и биндинга bindbc-newton. Newton был выбран как наиболее функциональный физический движок с интерфейсом C.
Вышли dlib 0.16.0 и 0.17.0. Библиотека постепенно приближается к релизу версии 1.0.
Я написал bindbc-wgpu, биндинг к графической библиотеке wgpu.
Ну и, конечно, не могу не назвать самые значимые для меня события в мире CG, СПО и геймдева:
Появление WebGPU, нового веб-стандарта для высокопроизводительной графики.
Выход Blender 2.80 c новым вьюпорт-движком Eevee.
Открытие кода Mimalloc, быстрого и компактного аллокатора памяти от Microsoft.