HELP! Possible to load multiple gltf objects on a single loader?

Hi gurus, sorry for the noob question but I search everywhere and I can’t find the answers.
so I am using gltf loader plugin to load a gltf object, but I would like to use ONE single gltf loader to load multiple gltf objects, is it possible to do that?

loader = new GLTFLoader();
dracoLoader.setDecoderPath("js/libs/draco/gltf/");
	loader.setDRACOLoader(dracoLoader);
	loader.load("models/tmp.glb", function(gltf) { // do something here }

as you can see that, the loader only takes one .glb file to load, what I want is load a second .glb but using the same loader(maybe as an arrary?), so that I can tweak everything(materials that share the same name for those glb) for those two glb objects at the same time.

currently I have to seperate them into different loader for such as var a loader1 and a loader2 and then tweak them seperately, it’s painful since those glb has many same material name sharing exactly the same settings with each other.

Is it a stupid behaviour for a noob like me dealing with this situation? Please guide me through, thank you guys so much. and THREEjs rocks the world forever :slight_smile:

You can using THREE.LoadingManager() for manage event when object loaded !

This works:

loader.load("models/model1.glb", function(gltf) { // do something with model 1 here } )
loader.load("models/model2.glb", function(gltf) { // do something with model 2 here } )

Just remember that loading models is asynchronous, which means that you don’t know which model will finish first (model 2 might load before model 1 if it’s smaller, for example).

You can’t load more than one model in a single loader.load call, but what you should do is create an onLoad function to process each loaded model.

A very simple one looks like this:

function onLoad( gltf ) {

   console.log( gltf );

   scene.add( gltf.scene.children );

}

Then you can use it like this to add each loaded model to the scene:

loader.load("models/model1.glb", onLoad );
loader.load("models/model2.glb", onLoad );
4 Likes

Hi there!

I get the following error when trying to use this with a THREE.GLTFLoader:

‘Error: WebGL warning: < SetDimensions > : Exceeded 16 live WebGL contexts for this principal, losing the least recently used one.’

Can somebody help?

@jedinger I don’t think your problem is related. Please create a new thread, and read this post on what to include when asking a question.

I think you’re creating too many webgl contexts. 16 seems to be the limit so when you exceed that, your oldest context is destroyed. Hope this helps.

Sorry, but that is a bit confusing for me. I thought Loader.loadAsync() does the trick. Every load method is async?

Every load method is async?

Yes, but they are implemented differently. My answer was written before Loader.loadAsync was added, which uses promises. The older Loader.load is callback-based. I wrote quite a bit about the different ways of writing asynchronous code in JS so I won’t go into it again here - in that chapter, the section on callbacks relates to Loader.load and the sections on Promises and async functions relate to Loader.loadAsync.

which means that you don’t know which model will finish first (model 2 might load before model 1 if it’s smaller, for example)

This still applies to Promises, however we can get deterministic load order using async/await and/or Promise.all. See here for details, or in short:

Deterministic load order with Promises

Promise.all([
  loader.loadAsync('modelA.glb'),
  loader.loadAsync('modelB.glb'),
  loader.loadAsync('modelC.glb'),
  loader.loadAsync('modelD.glb'),
]).then((results) => {
  // here the models are returned in deterministic order
  const [modelA, modelB, modelC, modelD] = results;
}).catch((err) => {
  console.log(err);
});

Deterministic load order, async/await

async function main() {
  const [modelA, modelB, modelC, modelD] = await Promise.all([
      loader.loadAsync('modelA.glb'),
      loader.loadAsync('modelB.glb'),
      loader.loadAsync('modelC.glb'),
      loader.loadAsync('modelD.glb'),
  ]);
}

main().catch((err) => {
  console.log(err);
});
3 Likes

Thank you very much for your explanation and examples! :smile: