Шейдеры и WebGPU пришли в p5.js: тысячи частиц без боли низкоуровневого кода

Обычный цикл в JavaScript начинает задыхаться уже на паре тысяч кругов или сфер, превращая интерактивный постер в слайд-шоу. До сих пор единственным спасением оставался побег в тяжелую графическую артиллерию. Но чтобы нарисовать банальный треугольник с нуля на условном Vulkan, приходится написать больше тысячи строк сугубо технического кода с ручным распределением памяти и настройкой конвейера. Разработчик Дейв Пагурек решил избавить визуальных художников от этой пытки и представил поддержку вычислительных шейдеров и WebGPU прямо внутри p5.js.
Библиотека, на которой выросло целое поколение медиахудожников, годами ассоциировалась с уютным двухмерным скетчингом и неспешной графикой. Сначала p5.js получила экспериментальную сборку с WebGPU, затем команда долго чистила внутренние ошибки, а теперь в проект интегрировали вычислительные шейдеры через модульную систему под названием p5.strands. Главная задача обновления — опустить планку входа в параллельные вычисления до уровня обычного креативного кода. Вместо того чтобы заставлять авторов разбираться в тонкостях классического пайплайна, новая архитектура прячет от глаз вершинные и фрагментные шейдеры, ручное жонглирование униформами и вариантными переменными. Всё строится на концепции поэтапного обучения, когда сложные механизмы сначала скрыты готовыми каркасами, а для работы хватает базового JavaScript: переменных, ветвлений, стандартных функций и школьной математики.
Фильтры, искажения и чистая геометрия
Сердцем системы стали высокоуровневые методы, которые говорят с автором на привычном визуальном языке. Чтобы пересобрать изображение на холсте, больше не нужно настраивать кастомные проходы рендеринга. Достаточно вызвать функцию buildFilterShader и обратиться к объекту filterColor. Координаты пикселей в нем уже нормализованы в диапазоне от 0 до 1 через свойство texCoord, а оживить картинку шумом или волнами можно стандартным таймингом millis(). Параметры со слайдеров в интерфейсе пробрасываются в код одной строкой через uniformFloat — без громоздких связок и биндингов.
Работа с трехмерным пространством строится похожим образом. За деформацию полигональной сетки отвечает метод buildMaterialShader со специальным блоком worldInputs. Внутри него вершины объектов можно сдвигать по оси Y с помощью знакомой тригонометрии вроде sin(), заставляя статичные формы плавно дышать в такт системному времени. При этом логика работы с геометрией теперь выглядит так:

- Метод
buildGeometryупаковывает модель в переиспользуемый меш; - Функция
model(geometry, count)выводит на сцену тысячи копий этой формы в один вызов; - Встроенная функция
instanceID()внутри шейдера выдает уникальный номер каждому экземпляру, позволяя сдвигать, вращать и перекрашивать элементы без участия центрального процессора.
Там, где стандартный цикл for намертво вешал вкладку браузера, инстансинг на WebGPU бодро крутит тысячи сфер или штрихов на шестидесяти кадрах в секунду.
Автономные частицы и буферы данных
Самый мощный пласт изменений связан с буферами хранения — storage buffers. До появления WebGPU в p5.js практически невозможно было заставить тысячи независимых точек взаимодействовать друг с другом без чудовищной потери скорости. Теперь под динамические массивы векторов выделена функция createStorage. Данные из такого хранилища считываются напрямую в шейдере материалов с помощью метода uniformStorage, открывая дорогу сложным поведенческим системам и роевому интеллекту.
Источником координат для таких массивов может стать что угодно. Например, можно загрузить векторный SVG-контур, программно снять с него опорные точки методом path.getPointAtLength() и отправить координаты в буфер. На ролике автора видно, как сотни маленьких сфер мгновенно выстраиваются вдоль витиеватых векторных линий, реагируя на движения курсора без малейших задержек. Вся тяжелая физика и расчет положений ложатся на плечи видеокарты, а код в файле остается компактным и читаемым.
По-нашему, это редкий случай, когда технологический апгрейд не усложняет жизнь, а возвращает в творческий код чувство легкости. Моушн-дизайнерам и разработчикам интерактивных инсталляций больше не нужно выбирать между простотой p5.js и вычислительной мощью «взрослых» графических библиотек — собирать процедурные текстуры, генеративные фильтры и многотысячные стаи частиц теперь можно в том же блокноте, где вчера рисовались простые круги.
Генеративный веб наконец-то избавляется от статуса медленного эскиза и превращается в полноценный продакшен-инструмент.


