Loading textures asynchronously
When you create Three.js scenes, you often need to load resources. There might be textures you want to load for your objects, you might have some external models you want to include in your scene, or maybe some CSV data that you want to use as an input for your visualization. Three.js offers a number of different ways of loading these resources asynchronously, which we'll explore in this and the following recipes.
To run these recipes and experiment with them, we included a simple sample in the source folder of this chapter that shows this loading in action. If you open an example 01.11-load-async-resources.html
in your browser, and open the JavaScript console, you'll see the progress and the result of loading resources asynchronously.
Please note that since we are loading files directly from the browser, you need to have either a local web server installed (see the Setting up a local web server with Python recipe or the Setting up a local web server with Node.js recipe) or disable some security checks as explained in the Solving cross-origin-domain error messages in Chrome recipe or the Solving cross-origin-domain error messages in Firefox recipe.
In these first of the five recipes, we'll show you how you can load textures asynchronously with Three.js.
Getting ready
Before looking at the steps in this recipe, you will need to create a number of standard callbacks that can be used by all the different loaders. These callbacks are used to inform you when a resource is loaded, when loading fails and, if available, the progress of the current request.
So for loading resources, we need to define three different callbacks:
- The
onload
callback: Whenever a resource is loaded, this callback will be called with the loaded resource as an argument. - The
onprogress
callback: Some loaders provide progress during the loading of a resource. At specific intervals, this callback will be called to inform you how much of the resource has been loaded. - The
onerror
callback: If something goes wrong during the loading of the resource, this callback is used to inform you about the error that occurred.
For all the recipes dealing with asynchronous loading, we'll use the same set of loaders. These loaders just output some information to the console, but you can of course customize these callbacks for your specific use case.
First, we define the onLoadCallback
function, which is called when a resource is loaded:
function onLoadCallback(loaded) { // just output the length for arrays and binary blobs if (loaded.length) { console.log("Loaded", loaded.length); } else { console.log("Loaded", loaded); } }
As you can see from the function definition, we just output the passed argument to the console. The other two callbacks, onProgressCallback
and onErrorCallback
, work exactly in the same manner as they are presented:
function onProgressCallback(progress) { console.log("Progress", progress); } function onErrorCallback(error) { console.log("Error", error) }
Note
In the following sections and recipes, we'll reference these callbacks when we use the Three.js provided functionality to load resources.
How to do it...
- To load a texture asynchronously, we use the
loadTexture
function fromTHREE.ImageUtils
:function loadTexture(texture) { var texture = THREE.ImageUtils.loadTexture(textureURL, null, onLoadCallback, onErrorCallback); console.log("texture after loadTexture call", texture); }
- The
loadTexture
function fromTHREE.ImageUtils
takes the following four arguments:- The first one points to the location of the image you want to load
- The second one can be used to provide a custom UV mapping (a UV mapping is used to determine which part of a texture to apply to a specific face)
- The third argument is the callback to be used when the textures have been loaded
- The final argument is the callback to be used in case of an error
- Note that the first console output also shows a valid texture object. Three.js does this, so you can immediately assign this object as a texture to a material. The actual image inside the texture, however, is only loaded after the
onLoadCallback
function is called.
How it works...
Three.js provides a nice wrapper to load textures. Internally, Three.js uses the standard way of loading resources from an XMLHTTPRequest
web page With an XMLHTTPRequest
web page, you can make an HTTP request for a specific resource and process the result. If you don't want to use the Three.js provided functionality, you can also implement an XMLHTTPRequest
function yourself.
See also
- To run these examples and load resources asynchronously, we need to either run a web server locally, as explained in the Setting up a local web server using Python recipe or the Setting up a web server using Node.js recipe, or disable some security settings, as explained in the Solving cross-origin-domain error messages in Chrome recipe or the Solving cross-origin-domain error messages in Firefox recipe.
- Alternatively, if you don't want to load resources asynchronously, but wait for all the resources to load, before you initialize your scene you can look at the next Waiting until resources are loaded recipe.