Learning Three.js: Part 3: Loading and Using Textures

Requirements:

In Part 1, I covered some general terms and techniques used in Three.js, a three-dimensional rendering JavaScript library. Part 2 reviewed some of the geometry and material options in creating meshes. In this third part, I explain how to load and use textures (images) for those same meshes as a continuation of building from the first example code.

Reviewing Example Code (from Part 1)

// Create a scene
scene = new THREE.Scene();
// Create a geometry
// Create a box (cube) of 10 width, length, and height
geometry = new THREE.BoxGeometry( 10, 10, 10 );
// Create a MeshBasicMaterial with a color white and with its wireframe turned on
material = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true} );
// Combine the geometry and material into a mesh
mesh = new THREE.Mesh( geometry, material );
// Add the mesh to the scene
scene.add( mesh );

view raw
part1Examples.js
hosted with ❤ by GitHub

In Part 1, the example code used a BoxGeometry as the shape for a MeshBasicMaterial with a solid color of 0xffffff (white). While materials can have solid shading of colors (and have their wireframes enabled), they can also have mapped textures loaded from other sources.

Textures

Usually, when referring to other externally loaded or internally generated images resources, the term used is texture. In three-dimensional work, these are defined in terms of three positions mapped into a space based on other objects and points. In Three.js, textures are nearly always a component of a material. Choosing which of the main material types (Basic, Lambert, or Phong) then affects how the textures appear and what effect, if any, lighting will have as well.

checkered
A 32×32 image (zoomed by 10x)

To load a texture in Three.js, the TextureLoader object is used. After defining and then setting a loaded texture object or variable, it can become the map for a material.

To expand the example from Part 1, and in using the above image, the init() section of the code would now look like this:

var camera, scene, renderer, geometry, material, mesh;
var texture;
function init() {
// Load a texture
texture = new THREE.TextureLoader().load( "checkered.png" );
// Create a scene
scene = new THREE.Scene();
// Create a geometry
// Create a box (cube) of 10 width, length, and height
geometry = new THREE.BoxGeometry( 10, 10, 10 );
// Create a MeshBasicMaterial with a loaded texture
material = new THREE.MeshBasicMaterial( { map: texture} );
// Combine the geometry and material into a mesh
mesh = new THREE.Mesh( geometry, material );
// Add the mesh to the scene
scene.add( mesh );
// Create a camera
// Set a Field of View (FOV) of 75 degrees
// Set an Apsect Ratio of the inner width divided by the inner height of the window
// Set the 'Near' distance at which the camera will start rendering scene objects to 2
// Set the 'Far' (draw distance) at which objects will not be rendered to 1000
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 2, 1000 );
// Move the camera 'out' by 30
camera.position.z = 30;
// Create a WebGL Rendered
renderer = new THREE.WebGLRenderer();
// Set the size of the rendered to the inner width and inner height of the window
renderer.setSize( window.innerWidth, window.innerHeight );
// Add in the created DOM element to the body of the document
document.body.appendChild( renderer.domElement );
}

view raw
part3Example.js
hosted with ❤ by GitHub

Note: Because of security settings, web browsers will not load resources like images across different protocols and origins. In order to correctly and safely load textures for Three.js projects, it is highly recommended to use functionality like the Live Server plugin for Atom or NetBeans’ local web-server service.

The result of the loaded texture on the rotating cube now looks like the following:

myitni6hhe

Part 3 Code (Full Example)

<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.min.js&quot;></script>
</head>
<body>
<script>
var camera, scene, renderer, geometry, material, mesh;
var texture;
function init() {
// Load a texture
texture = new THREE.TextureLoader().load( "checkered.png" );
// Create a scene
scene = new THREE.Scene();
// Create a geometry
// Create a box (cube) of 10 width, length, and height
geometry = new THREE.BoxGeometry( 10, 10, 10 );
// Create a MeshBasicMaterial with a loaded texture
material = new THREE.MeshBasicMaterial( { map: texture} );
// Combine the geometry and material into a mesh
mesh = new THREE.Mesh( geometry, material );
// Add the mesh to the scene
scene.add( mesh );
// Create a camera
// Set a Field of View (FOV) of 75 degrees
// Set an Apsect Ratio of the inner width divided by the inner height of the window
// Set the 'Near' distance at which the camera will start rendering scene objects to 2
// Set the 'Far' (draw distance) at which objects will not be rendered to 1000
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 2, 1000 );
// Move the camera 'out' by 30
camera.position.z = 30;
// Create a WebGL Rendered
renderer = new THREE.WebGLRenderer();
// Set the size of the rendered to the inner width and inner height of the window
renderer.setSize( window.innerWidth, window.innerHeight );
// Add in the created DOM element to the body of the document
document.body.appendChild( renderer.domElement );
}
function animate() {
// Call the requestAnimationFrame function on the animate function
// (thus creating an infinite loop)
requestAnimationFrame( animate );
// Rotate the x position of the mesh by 0.03
mesh.rotation.x += 0.03;
// Rotate the y position of the mesh by 0.02
mesh.rotation.y += 0.02;
// Render everything using the created renderer, scene, and camera
renderer.render( scene, camera );
}
init();
animate();
</script>
</body>
</html>

view raw
example3code.js
hosted with ❤ by GitHub