So far, we've focused on loading single models and textures. But real-world 3D scenes are rarely composed of just one asset. You'll often need to load multiple models, several textures for different materials, or even a combination of both. Fortunately, Three.js provides robust ways to handle this efficiently. The key to managing multiple assets lies in understanding how to initiate and track multiple asynchronous loading operations.
The THREE.LoadingManager is your best friend when dealing with multiple assets. It acts as a central hub for all loading operations. You can assign it to various loaders (like GLTFLoader, TextureLoader, etc.), and it will keep track of how many tasks are pending and when they've all completed. This is crucial for knowing when your entire scene is ready to be displayed or interacted with.
const manager = new THREE.LoadingManager();
manager.onStart = function ( url, itemsLoaded, itemsTotal ) {
console.log( 'Started loading file: ' + url + '.' );
console.log( 'Loading progress: ' + itemsLoaded + '/' + itemsTotal );
};
manager.onLoad = function ( ) {
console.log( 'All files have been loaded.' );
// Now you can render your scene or enable user interaction
};
manager.onProgress = function ( url, itemsLoaded, itemsTotal ) {
console.log( 'Loading file: ' + url + '.' );
console.log( 'Loading progress: ' + itemsLoaded + '/' + itemsTotal );
};
manager.onError = function ( url ) {
console.error( 'There was an error loading ' + url );
};The LoadingManager provides several callback functions that are invaluable for providing feedback to your users or orchestrating your application's logic: onStart, onLoad, onProgress, and onError. The onLoad callback is particularly important – it signifies that all the assets assigned to this manager have finished loading.
To use the LoadingManager, you simply create an instance of it and then pass that instance to the loaders you intend to use. Each loader that utilizes this manager will automatically report its status back to the manager.
const manager = new THREE.LoadingManager();
const gltfLoader = new THREE.GLTFLoader(manager);
const textureLoader = new THREE.TextureLoader(manager);
// Use gltfLoader to load models
gltfLoader.load('path/to/model1.glb', (gltf) => {
// ... handle model1
});
gltfLoader.load('path/to/model2.glb', (gltf) => {
// ... handle model2
});
// Use textureLoader to load textures
const texture1 = textureLoader.load('path/to/texture1.jpg');
const texture2 = textureLoader.load('path/to/texture2.png');
manager.onLoad = () => {
console.log('All assets loaded!');
// Add models to scene, apply textures, etc.
};