LoadingManager: централизованное управление загрузкой

LoadingManager в Three.js — это объект, предназначенный для централизованного контроля процесса загрузки ресурсов, таких как текстуры, модели, шейдеры и любые другие ассеты. Он обеспечивает удобное управление состояниями загрузки и позволяет выполнять действия при начале, прогрессе и завершении загрузки.


Основные свойства и методы

LoadingManager создаётся с помощью конструктора:

const manager = new THREE.LoadingManager();

Он поддерживает несколько ключевых событий:

  1. onStart Срабатывает при начале загрузки любого ресурса. Сигнатура:

    manager.onSt art = function (url, itemsLoaded, itemsTotal) {
        console.log(`Начало загрузки: ${url} (${itemsLoaded}/${itemsTotal})`);
    };
    • url — адрес загружаемого ресурса
    • itemsLoaded — количество уже загруженных элементов
    • itemsTotal — общее количество ресурсов для загрузки
  2. onLoad Вызывается, когда все ресурсы полностью загружены:

    manager.onL oad = function () {
        console.log('Все ресурсы загружены');
    };
  3. onProgress Отслеживает прогресс загрузки каждого ресурса:

    manager.onProgr ess = function (url, itemsLoaded, itemsTotal) {
        console.log(`Загружено ${itemsLoaded} из ${itemsTotal}: ${url}`);
    };
  4. onError Срабатывает при ошибке загрузки:

    manager.onEr ror = function (url) {
        console.error(`Ошибка загрузки: ${url}`);
    };

Интеграция с загрузчиками

LoadingManager тесно интегрируется со всеми загрузчиками Three.js: TextureLoader, GLTFLoader, OBJLoader, FontLoader и другими. При создании загрузчика можно передать менеджер:

const textureLoader = new THREE.TextureLoader(manager);
const gltfLoader = new THREE.GLTFLoader(manager);

Это позволяет собирать статистику по всем загрузкам в одном месте, независимо от типа ресурсов.


Пошаговый пример использования

const manager = new THREE.LoadingManager();

manager.onSt art = (url, loaded, total) => {
    console.log(`Старт загрузки: ${url} (${loaded}/${total})`);
};

manager.onProgr ess = (url, loaded, total) => {
    console.log(`Прогресс: ${loaded}/${total} (${url})`);
};

manager.onL oad = () => {
    console.log('Все ресурсы загружены, можно запускать сцену');
};

manager.onEr ror = (url) => {
    console.error(`Ошибка при загрузке: ${url}`);
};

const textureLoader = new THREE.TextureLoader(manager);
const gltfLoader = new THREE.GLTFLoader(manager);

const texture = textureLoader.load('textures/wood.jpg');
gltfLoader.load('models/chair.glb', (gltf) => {
    scene.add(gltf.scene);
});

В этом примере manager отслеживает загрузку одновременно текстуры и 3D-модели, обеспечивая централизованное управление.


Использование кастомного прогресс-бара

LoadingManager удобно использовать для визуализации загрузки:

const progressBar = document.getElementById('progress');

manager.onProgr ess = (url, loaded, total) => {
    const percent = (loaded / total) * 100;
    progressBar.style.width = percent + '%';
};

manager.onL oad = () => {
    progressBar.style.display = 'none';
};

Такой подход позволяет создать единый индикатор загрузки для всей сцены, даже если загружается несколько типов ресурсов.


Асинхронная загрузка с Promise

Можно обернуть загрузчики с менеджером в Promise для более гибкой работы с ассинхронностью:

function loadTexture(url) {
    return new Promise((resolve, reject) => {
        const loader = new THREE.TextureLoader(manager);
        loader.load(url, resolve, undefined, reject);
    });
}

async function initScene() {
    const texture = await loadTexture('textures/brick.jpg');
    const material = new THREE.MeshBasicMaterial({ map: texture });
    const cube = new THREE.Mesh(new THREE.BoxGeometry(), material);
    scene.add(cube);
}

Такой подход упрощает организацию кода и позволяет использовать async/await для последовательной или параллельной загрузки ресурсов.


Советы по оптимизации

  • Группировка ресурсов: использовать один LoadingManager для всех ресурсов сцены, чтобы централизованно отслеживать состояние.
  • Отображение прогресса: обновлять пользовательский интерфейс через onProgress, чтобы отображать процент загрузки.
  • Обработка ошибок: обязательно реализовать onError, чтобы корректно реагировать на недоступные файлы.
  • Предзагрузка критических ресурсов: сначала загружать текстуры и модели, необходимые для первой сцены, а менее важные — по мере необходимости.

Взаимодействие с другими компонентами Three.js

LoadingManager может работать совместно с:

  • Cache: кэширование загруженных ресурсов, чтобы повторные загрузки не создавали новые запросы.
  • TextureLoader и GLTFLoader: синхронное управление загрузкой текстур и 3D-моделей.
  • EffectComposer и Post-processing: можно отслеживать загрузку эффектов или текстур для шейдеров.

Использование LoadingManager позволяет строить сцены с плавной загрузкой, отображением прогресса и обработкой ошибок без разрозненных вызовов каждого загрузчика.