@thibka/three-multiloader

Three.js loading manager for textures, basis textures, cube textures, images, videos and GLTF files.

Usage no npm install needed!

<script type="module">
  import thibkaThreeMultiloader from 'https://cdn.skypack.dev/@thibka/three-multiloader';
</script>

README

multiloader

Three.js loading manager for textures, basis textures, cube textures, images, videos, and GLTF files.

Install

npm i @thibka/three-multiloader

Usage

import MultiLoader from '@thibka/three-multiloader'

let options = {
    progressBar: true,
    logs: true
};
let loader = new MultiLoader( options );

loader.onLoaded.add( callbackFunction );

loader.load([
    // textures
    { alias: 'cat', type: 'texture', path: 'path/to/texture.jpg' },
    { type: 'texture', path: 'path/to/texture.basis' }, // if no alias is used, the asset name will be its path

    // images
    { alias: 'dog', type: 'image', path: 'path/to/image.jpg' },

    // glb files
    { alias: 'main-scene', type: 'gltf', path: 'path/to/model.glb' },

    // videos
    // The 'loadEvent' property can be any video event ('loadedmetadata', 'canplaythrough', etc.) 
    // and will define when the video is considered to be loaded.
    // Default is 'loadedmetadata'.
    { alias: 'my-video', type: 'video', path: './path/to/video.mp4', loadEvent: 'loadedmetadata' },
]);

function callbackFunction() {
    console.log(loader.textures['cat']);
    console.log(loader.textures['path/to/texture.basis']);
    console.log(loader.images['dog']);
    console.log(loader.models['main-scene']);
    console.log(loader.cubeTextures['skybox']);
    console.log(loader.videos['my-video']);
}

Loading progress bar

Default progress bar

By default the MultiLoader instance will create a full screen progress bar. This can be turned off by setting the progressBar option to false.

let loader = new MultiLoader( { progressBar: false } );
// MultiLoader.load(...);

The loading bar should be disabled for lightweight models as the bar animation would add unnecessary waiting time.

Custom progress bar

A custom loading function can be define within the onProgress attribute, before calling the load method.

loader.onProgress = progress => {
    console.log(progress * 100 + '%'); // Will display 0% to 100%
}

Additionally, you can access the loading completion this way:

loader.progress; // returns a number between 0 and 1.

Logs

Settings the logs to true will output the loading progress in the console.
Default is false.

let loader = new MultiLoader( { logs: true } );

SMAA

Postprocessing SMAA images are provided as images:

let smaaSearch = loader.images['smaa-search'], 
    smaaArea = loader.images['smaa-area'];

CubeTexture loading

An alias must be provided for each cube-texture since they don't have a single unique path.

import MultiLoader from '@thibka/three-multiloader'
import { CubeTextureLoader } from 'three';

const loader = new MultiLoader({ 
    cubeTextureLoader: CubeTextureLoader,
});

loader.onLoaded.add( callbackFunction );

loader.load([
    { alias: 'skybox', type: 'cube-texture', path: [
        'path/to/px.png', 'path/to/nx.png',
        'path/to/py.png', 'path/to/ny.png',
        'path/to/pz.png', 'path/to/nz.png'
    ]}
]);

function callbackFunction() {
    console.log(loader.cubeTextures['skybox']);
}

Basis Texture loading

Transcoder files must be provided in the build.
This can be done

  • by manually moving the file from node_modules/three/examples/js/libs/basis/ to build/basis/
  • or using using something like the CopyWebpackPlugin:
/* webpack.config.js */
new CopyPlugin({
    patterns: [
        { from: 'node_modules/three/examples/js/libs/basis', to: 'basis' },
    ]
})
import MultiLoader from '@thibka/three-multiloader'
import { BasisTextureLoader } from 'three/examples/jsm/loaders/BasisTextureLoader.js';

const loader = new MultiLoader({ 
    basisLoader: BasisTextureLoader, 
    basisTranscoderPath: 'basis/', // Transcoder files must be provided in the build. See below.
    renderer: renderer // A renderer must be provided so that the basisLoader can work.
});

loader.onLoaded.add( callbackFunction );

loader.load([
    { alias: 'some-texture', type: 'texture', path: 'path/to/my_texture.basis' }
]);

function callbackFunction() {
    console.log(loader.textures['some-texture']);
}

DRACO compressed GLTF file loading

draco_decoder.js (600ko) must be provided in the build.
This can be done

  • by manually moving the file from node_modules/three/examples/js/libs/draco/draco_decoder.js to build/draco/draco_decoder.js
  • or using using something like the CopyWebpackPlugin:
/* webpack.config.js */
new CopyPlugin({
    patterns: [
        { from: 'node_modules/three/examples/js/libs/draco/draco_decoder.js', to: 'draco/draco_decoder.js' },
    ]
})
import MultiLoader from '@thibka/three-multiloader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';

const loader = new MultiLoader({ 
    dracoLoader: DRACOLoader,
    dracoDecoderPath: 'draco/' // draco_decoder.js must be provided in the build.
});

loader.onLoaded.add( callbackFunction );

loader.load([
    { alias: 'some-model', type: 'gltf-draco', path: 'path/to/model.glb' }
]);

function callbackFunction() {
    let gltf = loader.models['icosphere-draco'];

    scene.add(gltf.scene);
}

.drc file loading

This loader should only be used for .drc files.

import MultiLoader from '@thibka/three-multiloader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';

const loader = new MultiLoader({ 
    dracoLoader: DRACOLoader
});

loader.onLoaded.add( callbackFunction );

loader.load([
    { alias: 'some-model', type: 'drc', path: 'path/to/model.drc' }
]);

function callbackFunction() {
    let geometry = loader.models['some-model'];
    let material = new THREE.MeshStandardMaterial();
    let dracoMesh = new THREE.Mesh( geometry, material );
    scene.add( dracoMesh );
}

To do

  • Bug: When loading a looped video with 'canplay' event, the loading callback keeps being triggered.