Обновления

Лето подошло к концу — это печально 🙁 Но при этом спешу порадовать читателей хорошими новостями: одновременно вышли новые версии dlib и Dagon.

dlib 1.2.1 — в основном, исправляющий релиз. Исправлены ошибки в dlib.filesystem.posix.common, предупреждения о депрекациях в dlib.core.thread и dlib.math.utils. В dlib.image добавлен медианный фильтр (модуль dlib.image.filters.median).

Dagon 0.15.0 — первый релиз за последний год. Добавлена поддержка 1D и 3D-текстур и новые методы для класса Texture (setFaceImage, setFaceBit, createFromImage3D). Шейдер цветовых таблиц (LUT) теперь поддерживает таблицы в формате Hald CLUT — нужно создать 3D-текстуру из изображения Hald CLUT и просто передать в game.postProcessingRenderer.colorLookupTable. Появились новые параметры шейдера глубины резкости (DoF) для ручного управления эффектом: dofManual, dofNearStart, dofNearDistance, dofFarStart, dofFarDistance. Загрузчик glTF теперь декодирует встроенные в JSON-файл текстуры. Менеджер событий обзавелся поддержкой относительного режима мыши (EventManager.setRelativeMouseMode) для более надежной реализации управления мышью в играх. Соответственно, компонент управления FirstPersonViewComponent теперь использует по умолчанию относительный режим.
Обновился биндинг Newton Dynamics до свежей версии библиотеки: функция NewtonUserJointSetRowSpringDamperAcceleration удалена в пользу NewtonUserJointSetRowMassDependentSpringDamperAcceleration и NewtonUserJointSetRowMassIndependentSpringDamperAcceleration. Добавлен новый метод для ньютоновских твердых тел: NewtonRigidBody.localPointVelocity.

Реализация движка Sacrifice на D

Недавно узнал, что Dagon использовался для разработки свободной реализации игры Sacrifice (2000 г.) на D — sacengine. Только сейчас дошли руки собрать и протестировать. Сама игра мне не знакома, но проект очень интересный. Dagon используется в нем в качестве графического бэкенда. Как следствие, картинка sacengine имеет ряд существенных улучшений по сравнению с оригиналом — поддерживаются мягкие тени, SSAO, постэффект свечения, антиалиасинг.

Я рекомендую собирать игру компилятором LDC и обязательно в релизном режиме, в противном случае она будет заметно притормаживать:

dub build --compiler=ldc2 --build=release-nobounds

Для запуска нужно скопировать скомпилированный 3d.exe в папку с игрой, также нужны библиотеки freetype.dll, libmpg123-0.dll, OpenAl32.dll, SDL2.dll.

Исходники движка доступны под GNU GPL v3.

Докинг в ImGui

В тулките ImGui меня особенно радует поддержка докинга окон — это просто киллер-фича для создания сложных интерфейсов для различных редакторов, причем использовать ее очень легко, нужно только создать ImGuiIO со включенным докингом (io.ConfigFlags |= ImGuiConfigFlags.DockingEnable), а затем добавить в очередь объект DockSpace поверх вьюпорта:

ImGuiViewport* viewport = cast(ImGuiViewport*)igGetMainViewport();
ImGuiID mainDockSpaceId = igDockSpaceOverViewport(viewport, 
    ImGuiDockNodeFlags.PassthruCentralNode);

Затем можно создавать окна, как обычно — при перетаскивании окна появится виджет для его прикрепления к верхнему, нижнему, правому или левому краю вьюпорта. При наслоении окон друг на друга они отображаются в виде вкладок.

if (igBegin("Settings", null, ImGuiWindowFlags.NoCollapse))
{
    if (igCollapsingHeader("Post-processing"))
    {
        //...
    }
    
    igEnd();
}

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

Физика автомобиля: новое видео

Записал видео обновленной демки с физикой автомобиля на движке Dagon: новая модель трения (формула Пасейки), поддержка звуков (используется движок SoLoud), множество мелких улучшений и багфиксов.

Разработка на языке D – 13 лет спустя

13 лет назад я написал статью «Перспективы использования D в разработке игр» для журнала «FPS», в которой дал краткую характеристику основных особенностей языка и выделил главные его преимущества перед конкурентами. D изначально создавался как альтернатива C++ для разработки десктопных и серверных приложений – за прошедшие годы область применения языка не изменилась, хотя и добавились такие замечательные возможности, как поддержка ARM и Web Assembly. Но конъюнктура рынка и технологический статус кво сегодня уже несколько иные, поэтому я счел необходимым написать новую статью на ту же тему: насколько D актуален в геймдеве в 2023 году?

(далее…)

dlib 1.2 и другие обновления

Несколько обновлений за последние месяцы:

dlib 1.2.0 — добавлены функции гомотетии (homothetyMatrix, homothetyMatrix2D) в модуль dlib.math.transformation, функции конвертации радианов в обороты и обратно (radtorev, revtorad) в модуль dlib.math.utils. В dlib.image.render.shapes появилась функция отрисовки прямоугольника (drawRect) — автор реализации ReactiveAlkali. Добавлен файл CODE_OF_CONDUCT.md — краткий кодекс поведения для сообщества dlib:

Code of Conduct

Этот проект приветствует вклад в любой форме и поощряет открытое обсуждение и обмен мнениями о его функциях, архитектуре и деталях реализации. Для поддержания надлежащей культуры общения был сформулирован настоящий Кодекс поведения. Это относится к системе отслеживания проблем проекта, чату и, возможно, другим каналам связи.

1. Мы не приемлем нецензурные выражения, грубые и/или пренебрежительные сообщения, использование сексуальной, жестокой и иной оскорбительной лексики и изображений.

2. Любая критика должна быть конструктивной и разумной. Простого личного недовольства без каких-либо объективных причин недостаточно, чтобы делать критические заявления и влиять на развитие dlib.

3. Этот проект держится в стороне от нетехнологических вопросов и тем. Мы приветствуем всех, независимо от возраста, гендерной идентичности, религии, этнической принадлежности, гражданства или культурного происхождения, и наше сообщество не придерживается какой-либо определенной идеологии. Сайты, репозитории, каналы связи и прочие ресурсы, связанные с dlib, не должны использоваться как площадка для пропаганды.

Также добавлена поддержка Doxygen для генерирования документации.

bindbc-wgpu 0.16.0 — синхронизация с wgpu-native 0.16.0.1. Кстати, также обновил демку wgpu-dlang, добавил поддержку мипмаппинга и перевел на dlib 1.2.0.

Dagon 0.15 пока, к сожалению, откладывается на неопределенный срок — не доходят руки сделать поддержку 1D-текстур, которой не хватает для того, чтобы реализовать загрузчик KTX. В марте добавил новые параметры постобработки для ручного управления эффектом Depth of Field (dofManual, dofNearStart, dofNearDistance, dofFarStart, dofFarDistance) — это нужно, если необходимо реализовать кастомную расфокусированность, труднодостижимую стандартными параметрами focalDepth, focalLength и fStop.

Hald CLUT

В Dagon появилась поддержка 3D-текстур, что позволило реализовать цветокоррекцию с использованием цветовых таблиц формата Hald CLUT. CLUT расшифровывается как color lookup table — таблица поиска цвета: в памяти хранится текстура, в которой стандартным цветам sRGB сопоставлены какие-то другие цвета — вместо оригинальных цветов пикселей на вывод идут значения, прочитанные из 3D-таблицы. Принцип примерно тот же, что использовался в индексированных цветовых режимах, только в данном случае таблица охватывает более широкий диапазон RGB. Чаще всего CLUT используется для имитации характерной «пленочной» цветовой гаммы на цифровых снимках, но ее возможности гораздо шире. В таблице цвета могут быть абсолютно любые — с математической точки зрения, она является функцией, которая переносит цвет из одного пространства в другое. Чем больше таблица, тем точнее ее охват.

Оргинал таблицы в формате Hald CLUT выглядит следующим образом (PNG можно скачать тут):

Если отредактировать это изображение в графическом редакторе — например, изменить яркость, контраст, насыщенность и т. д. — результат будет хранить информацию, необходимую для того, чтобы повторить эти же операции на другом изображении. Единственное условие: цветокоррекция должна выполняться для каждого пикселя параллельно и независимо от остальных. Если фильтр использует оконную свертку и другие алгоритмы, работающие с несколькими пикселями одновременно, то метод с использованием CLUT не будет с ним работать.

Преимущество Hald CLUT состоит в эффективном расположении значений — таблица размером 4096×4096 охватывает весь 24-битный диапазон sRGB (16777216 цветов) и при этом отлично сжимается в PNG. Для хранения таблицы важно использовать lossless-формат, так как сжатие с потерями вносит мелкие искажения в цвета, а в данном случае важно сохранить точность информации.

Еще одна немаловажная фича формата — прямая совместимость с 3D-текстурами OpenGL. Достаточно просто декодировать картинку в буфер RGB и создать из этого буфера текстуру функцией glTexImage3D — никаких промежуточных конвертаций не требуется. Эта текстура затем передается в шейдер постобработки, который выглядит совсем элементарно:

vec3 inputColor = texture(colorBuffer, texCoord).rgb;
vec3 outputColor = texture(lookupTable, inputColor).rgb;

В Dagon поддержка создания 3D-текстуры из двумерного буфера встроена в класс Texture. Нужно загрузить таблицу, создать новую текстуру и проинициализировать ее методом createFromImage3D. Результат передается в стандартный стек постобработки (game.postProcessingRenderer):

TextureAsset aCLUT;

override void beforeLoad()
{
    aCLUT = addTextureAsset("data/food.png");
}

override void afterLoad()
{
    Texture clut = New!Texture(assetManager);
    clut.createFromImage3D(aCLUT.image, 256);
    game.postProcessingRenderer.colorLookupTable = clut;
    game.postProcessingRenderer.lutEnabled = true;
}

Поддерживаются таблицы любых разрешений, но вы должны сами правильно вычислить размер 3D-текстуры, соответствующей вашей CLUT. Например, для таблицы 4096×4096 это будет 256x256x256, как в моем примере. Если в этот параметр передать неправильное значение, то будет построена некорректная текстура (в релизе обязательно добавлю валидацию).

Пример использования на основе демки с автомобильной физикой — обработанное изображение и соответствующая таблица:

Ссылки

У меня много разных сайтов, ресурсов и аккаунтов в соцсетях, но я нечасто их рекламирую — вероятно, не все мои проекты известны читателям этого блога. В этом посте привожу исчерпывающий список ссылок на все, что актуально на сегодняшний день.

Общее
https://timurgafarov.ru — портфолио с проектами и примерами дизайнерских работ (в будущем планирую сделать на этом домене сайт моего бизнеса);

Геймдев и разработка
https://github.com/gecko0307 — профиль на GitHub;
https://www.patreon.com/gecko0307 — страница на Patreon;
https://gamedev.timurgafarov.ru — блог о разработке игр на языке D;
https://timurgafarov.medium.com — блог о языке D на Medium;
https://www.youtube.com/channel/UCVaRZr3TpAWVP_kaqBfmoew — YouTube-канал;
https://xtreme3d.ru — портал, посвященный Xtreme3D, 3D-движку для Game Maker и Game Maker: Studio, а также, в целом, созданию 3D-игр на GM;
https://psxdev.xtreme3d.ru — страничка о разработке под первую PlayStation;
https://fps.xtreme3d.ru — журнал о цифровом творчестве;

Моделирование
https://www.artstation.com/gecko0307 — портфолио на ArtStation;
https://dobrofile.ru/gecko0307 — 3D-модели в продаже;
Также у меня до недавнего времени был профиль с моделями на CGTrader, но меня лишили статуса продавца в связи со всем известными событиями;

Искусство
https://art.timurgafarov.ru — основное художественное портфолио и краткая творческая биография;
https://www.deviantart.com/timurgafarov — профиль на DeviantArt;
https://www.behance.net/timurgafarov — профиль на Behance;
https://500px.com/p/gecko0307 — фототворчество;

Соцсети
https://twitter.com/gecko0307 — Twitter;
https://www.linkedin.com/in/timurgafarov — профиль на LinkedIn;
https://vk.com/tgafarov — страница ВКонтакте;

Разное
https://kadath.fandom.com — википроект по вселенной Страны Снов Лавкрафта;
https://timurgafarov.ru/pixeltavern — фанатский микроблог, посвященный игре Margonem.

Новая статья на Medium

Я написал статью «Almighty Alias» на Medium о моем любимом ключевом слове alias, основное назначение которого — определение псевдонимов к типам и объектам. Но на самом деле alias способен на большее, особенно в связке с шаблонами.

Новости по проектам

Долго не писал в блог — не потому, что не о чем, а просто в последнее время психическое состояние не располагало к публичности. Ушел в себя, в рефлексию и размышления. Не могу отрицать, что энтузиазм по хобби-проектам у меня уже не тот, что раньше. Стало сложно сохранять прежний настрой, и вообще очень многие вещи в жизни отошли на второй план. Но я не бросаю D, не бросаю работу над движком — просто в данный момент пишу код небольшими итерациями, насколько хватает кратковременных состояний потока.

Из нового: практически доделал рефакторинг системы загрузки текстур в Dagon (ветка texture). Текстуры из DDS теперь загружаются напрямую, без создания промежуточных объектов SuperImage. Также 2D-текстуры и кубические карты объединены в один класс Texture, и работать с ними стало проще — например, загрузка карты окружения на стороне пользователя теперь выглядит одинаково как для кубической карты из DDS, так и для равнопромежуточной карты HDR. А еще появилась поддержка формата сжатия ASTC.

Обновил и выложил на GitHub свой старый программный растеризатор MiniGL. Попутно внес несколько улучшений — например, теперь конвейер поддерживает «шейдеры»: можно задать функции D, которые выполняются при обработке вершины и пикселя. Я не знаю, кому и для чего эта штука может пригодиться в 2022 году, но писать ее было весело, и код получился довольно наглядный и компактный — меньше 1000 строк, так что это как минимум хороший пример использования dlib.

И, наконец, около месяца у меня ушло на доработку одного интересного инструмента, не связанного с D, о котором я напишу подробнее в одном из следующих постов.