Avoid loading bursts - managing texture loading

my code loads and disposes a lot of image tiles during run-time - something like google maps.
The new textures get loaded on demand based on camera location etc.
Now it can happen that the code fires 50 texture requests at once, and if the connection is fast enough they all come in within a few frames, which in turn leads to lag as they all get updated the same time.

What would be a good way to spread the loading? I looked at the imageloader, loadingmanager etc. but they all seem straightforward - no queues or anything like that.

While i know my way around graphic engines, i am very new to all the network stuff - is there anything in JavaScript where i can limit the number of concurrent requests, keeping the rest in the queue?

My plan for now would be to have an intermediate structure that keeps track of ongoing transfers, waiting for callbacks and making sure only a few are updated at a time. While this is doable, i wonder if there is something like that already implemented in the http protocol.

ok i got it working like this:

setTexture(x,y) { 
	this.loadRequest = true;
	this.loading = true;
	this.loadRequestName = scope.directory + x.toString().padStart(3, '0')  + "_" + y.toString().padStart(3, '0') + '.jpg';
	// remove old texture and set loading symbol texture
	if(this.texture !== baseTexture) {
		this.texture.dispose();
		this.texture = baseTexture;
		this.material.map = this.texture;
		this.material.needsUpdate = true
	}
}


updateTextureQueue() {	// runs every so often..
	if(this.loadRequest) {
		if(activeRequests < maxRequests) {
			activeRequests++;					
			this.texLoader.load(this.loadRequestName, (loaded) => {
				this.texture = loaded;												
				this.material.map = this.texture;
				this.material.needsUpdate = true;
				this.loading = false;
				this.loadRequest = false;
				activeRequests--;						
			 })		
		}
	}
}

I guess that your problem is not in the “load” but in the decoding. I’m guessing you use some form of compressed image format, like png or jpeg. What the browser is going to do for you - is convert that into RGB or RGBA bitmap as appropriate and that takes time. Actual upload of the texture to the GPU is relatively fast. This is based on my own observations.

1 Like

noticed the same, but with low enough request per time it works out…
I did not research much in that area - but it looks like every approach has its downsides:

  • compressed textures are bigger (bandwidth) have artifacts and are not supported everywhere… (do they need the same conversion as jpeg or can they be directly uploaded to the gpu?)
  • Jpeg need to be decoded and converted
  • some home-brew binary stream with zip compression that can be loaded as typed array?

are there better ways then jpeg/png when bandwidth is a factor?

Yeah, there’s always HTTP compression. It’s useful to check whether your bitmap might end up small enough when transferred via a compressed channel that PNG/JPEG encoding might not be necessary. I found that for low PNG compression together with HTTP compression texture size differences are quite small, at least in my use-cases.

For example, my entire game with models and textures and every other asset is about 60 Mb of HTTP traffic over a compressed channel. I rate that as quite acceptable.