Музыкальный D: синтезатор в 100 строк

Моя статья 2018 года, изначально написанная для блога LightHouse Software. Приведенный код актуален и сегодня, статья служит неплохим вводным руководством к dlib.audio.

Библиотека dlib предоставляет базовые инструменты для работы с аудиоданными, которые позволяют написать синтезатор с сохранением полученных звуков в WAV. В этой статье я покажу, как с их помощью сгенерировать знаменитую мелодию «Popcorn» Гершона Кингсли, используя для этого всего три функции, умещающиеся в 100 строк кода.

(далее…)

Dagon 0.16.0

Выпустил новую версию Dagon. Главная особенность релиза — поддержка подповерхностного рассеивания (subsurface scattering) методом, аналогичным тому, который используется в Disney BRDF. Добавлено новое свойство материала subsurfaceScattering — это значение от 0 до 1, обозначающее долю излучения, которое рассеивается в толще материала: чем больше это значение, тем больше света проникает вглубь и меньше отражается от поверхности.

Также появилась поддержка зондов локального освещения среды (environment light probes). Это отложенный эффект наподобие точечных источников света, но для освещения среды: параллелепипед, внутри которого все объекты используют индивидуально заданную карту окружения вместо глобальной. Это позволяет, например, отделить освещение интерьера комнаты от уличного.

Добавлена ноддержка тональной компрессии AgX — и, соответственно, новые константы Tonemapper.AgX_Base и Tonemapper.AgX_Punchy.

Добавлена функция снятия скриншотов игры — метод Application.takeScreenshot.

Исправлен баг с некорректной передачей параметров в шейдер цветокоррекции (LUT). Исправлен прыжок в контроллере персонажа в расширении dagon:newton — прыжок плохо срабатывал на плоских поверхностях.

Dagon теперь использует dlib 1.3.0. Расширение dagon:imgui теперь использует bindbc-imgui 0.7.0.

Обновления

dlib 1.3.0

Вышла новая версия dlib. В библиотеке появился новый пакет dlib.math.random с реализацией генератора псевдослучайных чисел на основе C-функции rand. Проделан ряд улучшений в математическом пакете: добавлена поддержка компилятора GDC в модуль dlib.math.sse, появилась новая функция интерполяции bezierQuadratic.

Количество скачиваний dlib в реестре DUB достигло 1400 в месяц — рекордный показатель за все время существования проекта!

Подготовка к релизу Dagon 0.16

Новая версия Dagon планируется к выпуску совсем скоро — на днях внес ряд багфиксов и улучшений в физику Newton (в частности, исправлен прыжок контроллера персонажа на плоских поверхностях), а также добавил встроенную функцию создания скриншотов — Application.takeScreenshot.

AgX в Dagon

Добавил в Dagon поддержку AgX — это новая функция tonemapping’а, намного превосходящая ACES и Filmic по качеству результата. В частности, AgX более адекватно отображает засвеченные области — например, поверхности, освещенные яркими цветными источниками света или самостоятельно светящиеся поверхности, как показано на скриншотах ниже. При этом картинка в целом становится менее контрастной и насыщенной — для решения этой проблемы есть режим Punchy, который дает эффектный кинематографичный контраст.

Для сохранения обратной совместимости функцией по умолчанию пока останется ACES.

Обратил внимание, что многие в сообществе компьютерной графики не совсем понимают суть AgX и вообще тональной компрессии. Иногда AgX неверно называют «цветовым пространством» — пространство там BT.2020 RGB, предложенное для стандартизации изображения в устройствах UHDTV, а AgX — это цветовое преобразование (color transform) в этом пространстве. Перед тем, как применять AgX, нужно перевести цвет из линейного RGB в линейный BT.2020 RGB (а после применения — обратно). Тональная компрессия — это не какой-то волшебный фильтр, который «делает красиво», а просто функция, которая нелинейно сжимает яркость в ограниченный диапазон значений, сохраняя как можно больше информации с учетом особенностей человеческого зрения: в идеале должна сохраняться детализация и в темных, и в светлых участках картинки (не должно быть засветов и черных теней), а все цвета должны выглядеть правдоподобно на всем диапазоне яркости. Тема, опять-таки, довольно сложная, очень интересная и заслуживающая отдельной подробной статьи.

Как я перешел на фриланс и перестал выгорать

Согласно свежей статистике, 73% разработчиков испытывали симптомы выгорания. При этом 70% пишут код ради развлечения по выходным — я считаю, что это очень интересный момент, это говорит о важности хобби-проектов и о том, что программирование само по себе не является фактором психологических трудностей. Вспоминается хрестоматийный эпизод из «Приключений Тома Сойера», где покраска забора была и наказанием, и развлечением — все зависит от настроя и мотивации.

Распространено мнение, что лучший отдых — это смена деятельности. Но в случае с IT эту смену парадоксальным образом можно осуществить, «не отходя от кассы». Я работаю дома и часто отдыхаю на рабочем же месте, просто переключаясь на хобби-проекты и другие интересные мне задачи. При этом бывает, что я пишу для души примерно то же самое, что и для заработка! Осознав этот примечательный факт, я решил, что мой опыт заслуживает описания в виде статьи.

(далее…)

Обновления

bindbc-wgpu 0.19.0, соответствующий wgpu-native 0.19.x. Каких-то существенных изменений в этой версии нет, кроме того, что структуры и функции опроса статистики конвейера вынесены в платформоспецифичную часть API (bindbc.wgpu.types2).

Также рад сообщить, что bindbc-wgpu теперь успешно собирается и работает под Linux — как и демо-приложение с моделью Cerberus. Тестировал на Mint 21.2 с wgpu-native 0.19.1.1.

Работа над новым релизом Dagon продолжается: на днях внес множество исправлений, связанных с поддержкой Linux. В частности, теперь расширения dagon:newton и dagon:imgui загружают библиотеки из папки проекта, если не находят их в /usr/lib. При сборке под 64-битный Linux нужные библиотеки теперь копируются в папку с проектом — это должно упростить работу с расширениями, пользователи неоднократно жаловались на неинтуитивность подключения Newton. Также обновлен биндинг ImGui.

Статус по проектам

Начало года — неплохое время для того, чтобы поразмыслить над тем, что я буду делать в ближайшем будущем, и в какую сторону будут двигаться мои OpenSource-проекты. Также у меня есть ряд других направлений деятельности, о которых я тут еще не упоминал. Если интересно, читайте дальше.

К сожалению, далеко не все, что я делаю, имеет какие-либо перспективы серьезного развития. Некоторые из проектов остались на уровне любительских, другие я просто физически не успеваю развивать надлежащими темпами. Третьи — это своего рода эзотерика в сфере IT, понятная и интересная лишь единицам)

Dagon. Развивается, но медленно. В данный момент я работаю над версией 0.16, в которую войдут нововведения прошлого года: подповерхностное рассеивание и зонды освещения среды. Я планирую работать над движком и дальше, планы по нему довольно масштабные: так, я хочу сделать встроенный редактор на основе ImGUI — он будет генерировать исходники на D и вызывать DUB для сборки проектов, таким образом движок станет намного дружелюбнее для начинающих. Также в планах переписать стек постпроцессинга.

dlib. Понемногу развивается ветка 1.x, а вот 2.x пока заморожена. Исследую возможность поддержки прогрессивных JPEG.

Electronvolt (проект Atrium). Временно заморожен, но не исключено, что я к нему еще вернусь.

bindbc-wgpu, dusk и прочие наработки по WebGPU на D. Периодически обновляю, но для серьезного перехода на WebGPU пока нет мотивации и ресурса. Никаких особых планов на этот счет тоже нет.

dray. Новый проект — движок рейкастинга на основе dlib. Находится в разработке. Я в него переношу код из моего старого физ. движка dmech, а то пропадают даром хорошие алгоритмы) На сегодняшний день dray уже поддерживает пересечение луча с произвольной выпуклой геометрией, движок включает классы для таких стандартных тел, как сфера, параллелепипед, цилиндр, конус, эллипсоид. Тела могут быть произвольным образом трансформированы при помощи матриц 4×4.

Журнал FPS. Он жив-здоров, просто уже не имеет PDF-версии и существует в виде новостной странички. У меня есть идея окончательно объединить его с порталом Xtreme3D — думаю, это будет сайт или даже целая соцсеть по любительской разработке игр.

Этос Метамодерна. Telegram-канал для пространных философских рассуждений, которые по формату не подходят для других моих площадок.

Живопись и 3D-моделирование для стоков я окончательно забросил — коммерческий выхлоп там теперь уже нулевой, а времени работать для души совершенно перестало хватать.

Не упоминаю тут свои бизнес-процессы — это большая тема для отдельной статьи, и даже не одной.

Сжатие текстур, часть III. BPTC

Продолжение серии постов о сжатых текстурных форматах (часть I, часть II).

BPTC (BC6, BC7)

Block Partition Texture Compression

BPTC является частью ядра OpenGL начиная с версии 4.2. Обеспечивает лучшее качество по сравнению с семейством S3TC, при этом у него хорошая поддержка на десктопных платформах. У формата есть есть две разновидности: BC6 и BC7 (в обозначении DXGI).

BC7 используется для сжатия беззнаковых нормализованных изображений (то есть, обычных изображений глубиной цвета 8 бит на канал). Блок 4×4 преобразуется в 128 бит. Принцип сжатия во многом аналогичен S3TC — хранятся начальный и конечный пороговые цвета (endpoints), вместо пикселей сохраняются индексы интерполированных значений между ними. Отличие в том, что BPTC может хранить отдельные градиенты для каждого канала, подобно тому, как DXT5 разделяет цвет и альфу. BPTC поддерживает гибкий механизм группировки каналов: каждый блок может использовать один из 7 разных режимов группировки.

BC7 кодирует изображения с альфа-каналом. У него есть две версии — в линейном (GL_COMPRESSED_RGBA_BPTC_UNORM_ARB) и гамма-пространстве (GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB). Они математически эквивалентны, различие существует лишь для удобства интерпретации данных в приложениях (то есть, сэмплы из sRGB-текстур нужно, как обычно, переводить в линейное пространство перед тем, как использовать в каких-либо вычислениях).

BC6 (BPTC_FLOAT) — самый распространенный на сегодняшний день (и единственный на большинстве платформ) формат сжатия для HDR-изображений. Формат кодирует числа с плавающей запятой и не поддерживает альфа-канал. Первый endpoint хранится с высокой точностью, второй представляет собой смещение относительно первого, хранящееся с низкой точностью.

BC6 существует в двух версиях — COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB и COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, которые, соответственно, кодируют знаковые и беззнаковые значения.

Итоги 2023 года

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

  • Можно считать, что я достиг своей цели — стать профессиональным разработчиком игр. На сегодняшний день солидную долю моих доходов составляют фрилансерские проекты по разработке рекламных мини-игр и интерактивных баннеров. И, хотя все они пишутся на JavaScript, я стал чаще по работе использовать D для создания различных утилит, что не может не радовать.
  • Выпустил Dagon 0.15, в котором появилась поддержка Hald CLUT, 1D и 3D-текстуры, новые параметры постобработки для ручного управления эффектом Depth of Field, новые методы для текстур, обновлен биндинг Newton.
  • В репозиторий с примерами Dagon добавлены примеры создания ландшафта и работы с пользовательскими шейдерами.
  • Выпустил dlib 1.2.0 и 1.2.1. Добавлены функции гомотетии (масштабирования относительно точки), функции конвертации радианов в обороты и обратно, медианный фильтр, а также функция отрисовки прямоугольника. Спасибо Олегу Бахареву aka aquaratixc, Aaron Nédélec aka ReactiveAlkali, Razvan Nitu aka RazvanN7, Nick Treleaven aka ntrel за багфиксы и новые фичи.
  • Я наконец-то дописал вводную статью о PBR для начинающих, она доступна на сайте журнала «FPS». Кстати в уходящем году журналу исполнилось уже 15 лет.
  • Начал изучать микроконтроллеры — Arduino и ESP32. Полным ходом иду к своей детской мечте — сделать своими руками радиоуправляемую машинку (как-нибудь напишу пост об этом проекте).

Ну и, конечно, не могу не назвать самые значимые для меня события в мире IT:

  • Выход Blender 4.0
  • Выход Godot 4
  • Смена ценовой политики Unity
  • Появление ChatGPT (хотя я не думаю, что нейросети в обозримом будущем кого-то заменят).

Освещение интерьера в Dagon

Добавил в Dagon экспериментальную поддержку зондов освещения среды (environment probes). Это специальные невидимые объекты, которые перезаписывают освещение среды в буфере кадра для всех пикселей внутри прямоугольной коробки заданного размера. То есть, вы можете, например, создать комнату с зондом такого же размера внутри — он будет влиять на освещение внутри комнаты, а все, что снаружи, будет освещаться при помощи глобальной карты окружения, заданной в опциях environment текущей сцены. Таким образом, решается проблема неправильных «наружных» отражений в интерьере. Скриншоты ниже демонстрируют разницу:

Некорректные отражения на стенах внутри комнаты + в целом, слишком яркий интерьер
Световой зонд заменяет освещение среды в комнате на более тусклое

По сути, это простейшая аппроксимация GI. Зонд может освещать интерьер однородным излучением заданного цвета, либо использовать собственную HDR-карту окружения. Единственная нерешенная на данный момент проблема — видимая граница двух сред освещения в тех местах, где отсутствует геометрия здания (т.е. в дверных проемах). Поэтому при использовании данной фичи необходимо как-то маскировать эту границу — например, сделать в этом месте порог или переход текстуры пола.