Реакция визуализации на звук

Для начала необходимо инициализировать движок Babylon.js и создать сцену. Основные объекты включают Engine, Scene и Camera. Например:

const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);

const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera("camera", Math.PI/2, Math.PI/4, 10, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);

const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);

Эта базовая установка создаёт трехмерное пространство, камеру с возможностью управления мышью и простое освещение сцены.


Подключение и анализ аудио

Для реализации реакции объектов на звук необходимо подключить аудиоисточник и анализатор частот. Babylon.js поддерживает встроенный Sound и интеграцию с Web Audio API.

const music = new BABYLON.Sound("music", "audio/song.mp3", scene, null, { loop: true, autoplay: true });
const analyser = new BABYLON.Analyser(scene.getEngine().getAudioContext());
music.connectToAnalyser(analyser);

Analyser позволяет получать массивы данных частот и амплитуд в реальном времени. Эти данные служат основой для динамического управления визуальными элементами сцены.


Работа с данными частот

Analyser предоставляет методы getByteFrequencyData() и getFloatTimeDomainData(). Пример использования:

const frequencyData = new Uint8Array(analyser.frequencyBinCount);

scene.registerBeforeRender(() => {
    analyser.getByteFrequencyData(frequencyData);

    const bass = frequencyData.slice(0, 10).reduce((a,b) => a+b, 0) / 10;
    const mid = frequencyData.slice(10, 50).reduce((a,b) => a+b, 0) / 40;
    const treble = frequencyData.slice(50, frequencyData.length).reduce((a,b) => a+b, 0) / (frequencyData.length - 50);

    // Применение к объектам сцены
});

Здесь bass, mid и treble представляют низкие, средние и высокие частоты, которые можно использовать для управления масштабом, цветом или движением объектов.


Визуальная реакция объектов

Часто для визуализации используют геометрические объекты с изменяемыми свойствами:

const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { diameter: 1 }, scene);

scene.registerBeforeRender(() => {
    analyser.getByteFrequencyData(frequencyData);
    const bass = frequencyData.slice(0, 10).reduce((a,b) => a+b, 0) / 10;
    
    sphere.scaling.y = 1 + bass / 50; // Реакция на бас
    sphere.material.emissiveColor = new BABYLON.Color3(bass/255, 0, 1-bass/255);
});
  • Масштабирование: изменение размеров объекта в зависимости от амплитуды выбранного диапазона частот.
  • Цвет: динамическое изменение цвета материала через emissiveColor или diffuseColor.
  • Движение: можно добавлять вращение или перемещение вдоль осей, синхронизированное с частотами.

Использование ParticleSystem для эффектов

Babylon.js позволяет создавать сложные визуальные эффекты с помощью системы частиц. Частицы могут реагировать на звук, создавая динамичное визуальное сопровождение.

const particleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);
particleSystem.particleTexture = new BABYLON.Texture("textures/flare.png", scene);
particleSystem.emitter = sphere;
particleSystem.minSize = 0.1;
particleSystem.maxSize = 0.5;
particleSystem.minLifeTime = 0.5;
particleSystem.maxLifeTime = 1.5;
particleSystem.start();

scene.registerBeforeRender(() => {
    analyser.getByteFrequencyData(frequencyData);
    const intensity = frequencyData.slice(0, 10).reduce((a,b) => a+b, 0) / 10;
    particleSystem.emitRate = 50 + intensity * 2; // Реакция на звук
});

Количество частиц (emitRate), их скорость или цвет можно синхронизировать с разными диапазонами частот, создавая сложные музыкальные визуализации.


Создание более сложных визуализаций

Для продвинутых эффектов используют:

  • Плоскости с динамическими шейдерами: через ShaderMaterial можно изменять вершины и цвета в реальном времени на основе аудиоданных.
  • Массивы объектов: создание сетки кубов или сфер, каждая из которых реагирует на отдельный диапазон частот, формируя спектр-анализ.
  • Геометрические деформации: изменение вершин мешей с использованием vertexData для создания пульсирующих волн или волн частотного спектра.

Пример сетки кубов:

const cubes = [];
for (let i = 0; i < 32; i++) {
    const cube = BABYLON.MeshBuilder.CreateBox(`cube${i}`, { size: 0.5 }, scene);
    cube.position.x = i - 16;
    cubes.push(cube);
}

scene.registerBeforeRender(() => {
    analyser.getByteFrequencyData(frequencyData);
    cubes.forEach((cube, index) => {
        cube.scaling.y = 1 + frequencyData[index] / 50;
        cube.material.emissiveColor = new BABYLON.Color3(frequencyData[index]/255, 0.5, 1-frequencyData[index]/255);
    });
});

Такой подход позволяет создавать визуальные эквалайзеры, синхронизированные с любым аудиофайлом.


Оптимизация производительности

  • Использовать ограничение количества объектов и частиц.
  • Пересчитывать данные частот не каждую миллисекунду, а с определённым шагом (requestAnimationFrame уже ограничивает до ~60 FPS).
  • Для сложных шейдеров применять GPU-подсчёт, минимизируя вычисления на CPU.
  • Повторно использовать материалы и текстуры, чтобы уменьшить нагрузку на движок.

Эти методы позволяют создавать плавные и эффектные аудиовизуальные сцены без снижения производительности.