Deferred Texturing для ландшафта

Еще одной новинкой в Dagon 0.14 станет довольно интересная и нетипичная техника, которую я еще не встречал в готовых реализациях – Deferred Texturing (отложенное текстурирование) для ландшафта.

Когда у меня в движке появилась поддержка ландшафтов, я не стал особо мудрить и сделал для них простейший шейдер, к которому подключаются до четырех текстур, причем для них пришлось сделать специальные свойства у материала, что выглядело не очень эстетично с точки зрения дизайна API. Также этот шейдер не поддерживал текстуры шероховатости и металличности, что делало его неполноценным по сравнению с остальными компонентами рендера. Техника Deferred Texturing, описанная Натаном Ридом, практически идеально вписалась в мой пайплайн и полностью решает эти две старые проблемы.

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

Полученные буферы вместе с PBR-текстурами (карта нормалей, base color, roughness, metallic) скармливаем текстурирующему проходу, который рисует экранный квад и записывает значения уже в обычный G-буфер. Для вычисления финальных нормалей используются значения из буфера нормалей ландшафта (плюс глубина, которую я сохраняю как альфа-канал буфера нормалей – она нужна для реконструирования eyespace-позиции пикселя). PBR-текстуры сэмплируются UV-координатами из буфера. Чтобы экранный квад не перезаписывал значения, уже сохраненные в G-буфере, нужно отсекать пиксель по маске, которую я храню в Z-координате буфера нормалей – 0 означает, что в данной точке нет ландшафта, 1 – есть.

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

ImGui

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

Nuklear при этом никуда из движка не денется, оба тулкита будут сосуществовать в виде двух отдельных расширений.

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

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

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

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

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

Обращение к пользователям dlib, Dagon и других моих публичных проектов в связи с украинским кризисом

Я, Тимур Гафаров, создатель и мэйнтейнер dlib, Dagon, bindbc-wgpu, bindbc-newton, bindbc-soloud и др., в настоящее время живу в России без возможности в обозримом будущем покинуть эту страну.

В целях личной безопасности, не буду сейчас комментировать саму ситуацию и делать заявления, которые могут быть расценены как политические. Скажу только, что при работе над свободным ПО между людьми не должно быть границ. dlib объединяет труд разработчиков из Украины, России и многих других стран. Политика не должна мешать людям во всем мире делиться знаниями, создавать нечто новое, решать интеллектуальные задачи.

Тем не менее, реальность такова, что разработчики из России в любой момент могут оказаться отрезанными от мирового сообщества СПО. Это серьезно повлияет на проекты, в которых они принимают участие. Я искренне надеюсь, что этого не произойдет. В противном случае я, к моему огромному сожалению, не смогу управлять разработкой dlib, Dagon и других моих пакетов в реестре Dub. В отсутствие сопровождения эти пакеты будут постепенно терять актуальность. Также у меня пока нет уверенности, что я смогу получать финансирование через Patreon и PayPal.

До ухудшения ситуации, пока у меня есть доступ к GitHub и реестру пакетов, я продолжаю сопровождение dlib и Dagon, в настоящее время уделяя этому минимум своего свободного времени. Я на неопределенный срок приостанавливаю разработку dlib 2.0 и новых версий Dagon из-за негативного психологического фона и неясной картины будущего. В случае катастрофического развития событий я не обещаю, что смогу посвящать проектам даже минимальные время и силы.

В связи с этим, я с сегодняшнего дня не рекомендую использовать dlib, Dagon и другие мои пакеты в качестве критических зависимостей в важных программных продуктах. Кто хочет взять активную разработку на себя, создать форк – буду только рад. Пожалуйста, не делайте pull request’ы с большим количеством коммитов, существенными изменениями и новыми фичами, которые мне придется читать и проверять – у меня для этого может физически не оказаться возможности. Если у меня сохранится доступ к GitHub, я, скорее всего, увижу ваш форк и сам сделаю слияние, как только смогу.

P.S. Я в срочном порядке выпустил Dagon 0.13.0.

P.P.S. Облачная папка с примерами Dagon (Sponsor Folder), которая была ранее доступна только для подписчиков на Patreon, теперь открыта для всех.

DagoBan

DagoBan возвращается! Игра, изначально написанная Mateusz Muszyński в целях демонстрации возможностей тулкита Nuklear в Dagon, недавно была портирована мной на актуальную версию движка. Сборку для Windows можно скачать здесь.

Напомню, DagoBan – это мини-клон Sokoban на D со встроенным редактором уровней.