Requirements:
- Some knowledge of JavaScript
- Optional: An editor like Atom, NetBeans, or Sublime Text
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.
- Part 1: Terms and Techniques
- Part 2: Geometries and Materials
- Part 3: Loading and Using Textures
- Part 4: Light Sources
- Part 5: Controls
Reviewing Example Code (from Part 1)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 ); |
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.

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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ); | |
} |
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:
Part 3 Code (Full Example)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.min.js"></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> |