Аудиореактивный шейдер на GLSL: свой визуализатор музыки в браузере
Фрагментный шейдер — небольшая программа, которая выполняется для каждого пикселя экрана в каждом кадре. Передайте ему несколько чисел о том, что звучит прямо сейчас — насколько громкий бас, была ли только что бочка, — и он становится аудиореактивным шейдером: визуализатором, который вы пишете сами, в несколько десятков строк на GLSL.
Обычно сложнее всего не сам шейдер, а всё вокруг: захват звука, БПФ, сглаживание, поиск долей и ударов, передача значений в WebGL. Deus Studio берёт это на себя — открываете редактор в Chrome и сразу занимаетесь картинкой.
Что такое Deus Studio
Deus Studio — редактор GLSL внутри расширения Deus, подключённый к настоящему движку Deus. Вы пишете фрагментный шейдер и сразу видите, как он реагирует на вкладку, которую слушает Deus, или на аудиофайл с компьютера. Превью использует те же uniform-переменные, анализ звука и рендерер WebGL 1, что и визуализатор, так что в превью вы видите ровно то, что заиграет в Deus. Studio входит в бесплатный тариф Free.
Чтобы открыть редактор, запустите визуализатор для вкладки (см. инструкцию про любую вкладку) и выберите в его меню «Создать › GLSL». Начать можно с шаблона «Заготовка», с «Обзора аудиовходов», который рисует каждый звуковой вход в виде индикатора, или с редактируемой копии любого из 70 встроенных WebGL-пресетов. Оригинал при этом не меняется.
Какие данные получает шейдер
Studio работает с GLSL ES 1.00 и функцией mainImage в стиле Shadertoy. Deus в реальном времени передаёт каждому шейдеру набор uniform-переменных; их имена используются напрямую, объявлять ничего не нужно. Самые полезные:
u_resolution— размер рендера в пикселях,u_time— секунды с запуска пресета.u_bass,u_mid,u_treble,u_level— басы, середина, верха и общая громкость, нормализованные в диапазон 0–1.u_kick,u_snare,u_hihat— детекторы бочки, малого барабана и хай-хэта, 0–1.u_attackрезко растёт на каждом новом звуке,u_bass_pulse— затухающий импульс на ударах баса.u_level_integral— часы, которые идут быстрее, когда музыка громче. Используйте их вместоu_time, чтобы движение следовало за треком.u_frequency[32]иu_waveform[32]— спектр от басов до верхов и форма волны, по 32 значения.u_note_color,u_note_intensity[12]и другиеu_note_*— анализ нот по 12 звуковысотным классам, от C до B.
Работают и iTime, iResolution и iFrame из Shadertoy, так что код оттуда переносится с меньшим числом правок. Наведите курсор на любое имя с u_ в редакторе — появится подсказка и текущее значение; на вкладке «Входы» все они собраны со значениями в реальном времени.
Первый аудиореактивный шейдер
Вот готовый пресет: кольцо дышит в такт басу, подпрыгивает на каждой бочке и вращается быстрее, когда трек становится громче.
// Кольцо дышит с басом и подпрыгивает на бочке.
uniform vec3 u_tint; // @color #ff2bd6 label="Tint"
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// Координаты от центра: y от -1 до 1.
vec2 p = (fragCoord * 2.0 - u_resolution) / u_resolution.y;
float r = length(p);
float a = atan(p.y, p.x);
float radius = 0.35 + u_bass * 0.35 + u_kick * 0.15;
float ring = 1.0 - smoothstep(0.0, 0.04, abs(r - radius));
// Полосы крутятся быстрее, когда музыка громче.
float stripes = 0.6 + 0.4 * sin(a * 8.0 + u_level_integral * 2.0);
vec3 color = u_tint * ring * stripes;
color += u_tint * u_hihat * 0.25 * (1.0 - smoothstep(0.0, 0.6, r));
fragColor = vec4(color, 1.0);
}
Несколько деталей. Дробные литералы пишутся с точкой: 1.0, а не 1. Комментарий // @color превращает u_tint в выбор цвета — и в Studio, и на панели «Настроить» визуализатора. Ползунки устроены так же: uniform float u_speed; // @param 0 3 1 даёт ползунок от 0 до 3 со значением 1 по умолчанию, а // @toggle 1 — переключатель. Каждый элемент управления — одна строка в коде, поэтому он всегда остаётся с шейдером.
Элементы управления без набора кода
Писать такие комментарии вручную не обязательно. Выделите число в коде или цвет vec3 и нажмите «Сделать ползунок» — он появится и в Studio, и на панели «Настроить». У цветовых литералов есть образец цвета, по которому можно кликнуть, а ошибки компиляции отмечаются на тех строках, где они возникли.
Смотрите, что слышит шейдер
Вкладка «Аудио» показывает сырой и нормализованный спектр и последние 12 секунд уровня, басов, середины, верхов, атак и распознанных ударов барабанов — с подписью uniform-переменной, которая их читает. С этим настраивать намного проще: если кольцо почти не двигается, видно, доходит ли u_bass до 1.0 на этом треке, и формулу можно подправить. Источник звука — вкладка, которую захватывает Deus, или трек с вашего компьютера.
Проходы рендера, обратная связь и другие имена
Комментарии задают и рендер: // @pass buffA scale=0.5 добавляет проход, который читается как uniform sampler2D buffA;, // @feedback 0.09 плавно гасит прошлый кадр вместо очистки — получаются шлейфы, а // @fps 30 ограничивает частоту кадров. Если вы переносите шейдер в стиле Synesthesia, движок задаёт и имена вроде syn_BassLevel, syn_Hits или TIME — объявите их в коде, чтобы использовать.
Сохраните шейдер в Deus
Нажмите «Сохранить» (⌘S), и пресет появится в «Пресеты › Мои пресеты» с миниатюрой из превью, или «Сохранить и включить», чтобы визуализатор сразу переключился на него. Несохранённые правки переживают перезагрузку как черновик, а ваши пресеты хранятся локально в браузере.
Дальше шейдер играет в визуализаторе рядом со встроенными пресетами — его можно вывести на весь экран на телевизоре или втором мониторе. А чтобы разобраться в анализе звука, который стоит за uniform-переменными, прочитайте, как работают визуализаторы музыки.