Trouble getting an image to display on the side of a cube

I downloaded this project from that shows an image on the side of a cube. THREE.js - CodeSandbox
When it’s downloaded and run locally, the cube is rendered, but the image is not added. After downloading, I run npm install and npm run start. There are warnings about gamma not being supported. I tried a few changes based and added postprocessing, but couldn’t get the image to show on the face of the cube. Are there some new ways to place an image on geometric objects?

I’ve updated the code and cleaned it up a bit so you can copy/paste it into one of the official examples e.g. webgl_geometry_cube and run it locally. The code works with the latest official three.js release r141.

import * as THREE from 'three';

import { OrbitControls } from './jsm/controls/OrbitControls.js';

let camera;
let renderer;
let scene;
let mesh;
let controls;

function init() {

	// Creating the scene
	scene = new THREE.Scene();
	scene.background = new THREE.Color("skyblue");


	renderer.setAnimationLoop(() => {

function createCamera() {
	const fov = 35;
	const aspect = window.innerWidth / window.innerHeight;
	const near = 0.1;
	const far = 100;
	camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
	camera.position.set(-2, 2, 10);

function createLights() {
	const mainLight = new THREE.DirectionalLight(0xffffff, 5);
	mainLight.position.set(10, 10, 10);

	const hemisphereLight = new THREE.HemisphereLight(0xddeeff, 0x202020, 5);
	scene.add(mainLight, hemisphereLight);

function createMeshes() {
	const textureLoader = new THREE.TextureLoader();
	const texture = textureLoader.load("./textures/uv_grid_opengl.jpg");
	texture.encoding = THREE.sRGBEncoding;

	const geometry = new THREE.BoxGeometry(2, 2, 2);
	const material = new THREE.MeshStandardMaterial({ map: texture });
	mesh = new THREE.Mesh(geometry, material);

function createRenderer() {
	renderer = new THREE.WebGLRenderer({ antialias: true });
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.outputEncoding = THREE.sRGBEncoding;
	renderer.physicallyCorrectLights = true;

function createControls() {
	controls = new OrbitControls(camera, renderer.domElement);

function update() {
	// mesh.rotation.x += 0.01;
	// mesh.rotation.y += 0.01;
	// mesh.rotation.z += 0.01;

function render() {
	renderer.render(scene, camera);


function onWindowResize() {
	camera.aspect = window.innerWidth / window.innerHeight;

	// Update camera frustum

	renderer.setSize(window.innerWidth , window.innerHeight);
window.addEventListener("resize", onWindowResize, false);

Thanks for looking at this.
I incorporated your changes but I’m still not seeing the image on the cube.
I get a little confused on importing three.js. I copied the orbitcontrol in examples from node_modules into /src. I think it is reading both three.js and orbitcontrol from /src.
I can build and I have pushed and deployed to netlify.
I can’t figure out why the image doesn’t show up on the cube??
Here’s the code: GitHub - rebeccapeltz/three-test: testing three.js
Here’s the deployed code:

I just got this to work by loading the image to the texture from a remote URL rather than from the local server - I think that parcel is not copying the local image over to the build output directory. I don’t get a 404, but the image you need in the inspector network tab when you load locally is not the image.

I’m not familiar with Parcel, sorry. I’ve just used the local server which is defined as a dev dependency of the three.js npm package.

1 Like

Do you recommend using the CDN’s over NPM?

IMO, using CDNs is fine when you learn three.js or just want to hack around/ try out features. For all other cases, I recommend using the npm package in combination with a built tool.