Creating a 360° image using ThreeJS cube mapping

Projecting a skybox image to create a 360° image

Razni Hashim
IntuitionMath
4 min readAug 6, 2023

--

Cube mapping is an environment mapping technique used to create 360° images.

To create a 360° image using cube mapping, we use skybox images. A skybox image is an image capturing the top, bottom, front, back, left and right of the environment.

A Skybox image from Learn Open GL

Let’s see how to create a 360° image using ThreeJS step by step.

First of all, make sure you have installed ThreeJS and other necessary dependencies. Next setup your HTML file.

1. Setting up the HTML file

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Environment Map with Three.js</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script src="path_to_js_file" type="module">
</script>
</body>
</html>

Make sure to replace the script source path_to_js_file, with your JS file path. Also make sure to specify the script type as module, because we are using ES6 modules in our JS codes. Now let’s move on to our JS file.

2. Importing ThreeJS & Orbit Controls to JS file

First of all import the ThreeJS library. We are also using Orbit Controls for 360° camera movement. I am using a CDN link to import ThreeJS and Orbit Controls.

import * as THREE from 'https://cdn.skypack.dev/three@0.133.0/build/three.module.js';
import { OrbitControls } from 'https://cdn.skypack.dev/three@0.133.0/examples/jsm/controls/OrbitControls.js';

3. Setting up the scene, camera and the renderer

The Perspective Camera is the camera that will rotate around to give a 360° view.

// Set up the scene
const scene = new THREE.Scene();

// Create the camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 1;

// Create the renderer
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

4. Define the damping factor in Orbit Controls

Enable damping in Orbit Controls and define the damping factor. The damping factor in Orbit Controls plays a crucial role in moving the camera smoothly. The lower the damping factor, the higher the smoothness in camera motion.

// Add OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // Smoothly damping effect during rotation
controls.dampingFactor = 0.05;

5. Loading the skybox image

Now comes the main part. The skybox image consists of 6 images. The front, back, right, left, top and bottom images of the environment forms the skybox image. Make sure you have stored these 6 images as 6 different images in your PC.

Using the Cube Texture Loader to load the 6 images

The Cube Texture Loader is a texture loader, used to load 6 images at once. First define a constant and then assign the Cube Texture Loader to the constant defined.

const cubeTextureLoader = new THREE.CubeTextureLoader();

Then set the path of the directory, that contains the six images. My six images contain in the directory skybox/. You can replace it with the path of the directory that contains your six images.

cubeTextureLoader.setPath('skybox/');

There’s an order of placing the six images. The order of placing the six images is right, left, top, bottom, front and back.

const skyboxTexture = cubeTextureLoader.load([
'right.jpg', 'left.jpg', 'top.jpg',
'bottom.jpg', 'front.jpg', 'back.jpg'
]);

Then the 6 images loaded are set to the background of the scene.

scene.background = skyboxTexture;

Using the Cube Camera to render

Then Cube Camera is used to render the skybox images. The Cube Camera uses WebGL Cube Render Target to render the skybox images.

// Create the CubeRenderTarget
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(512);
const cubeCamera = new THREE.CubeCamera(1, 1000, cubeRenderTarget);
scene.add(cubeCamera);

After rendering, the Cube Camera is added to the scene.

6. Handling Window Resize

You can define a function to handle the window resize.

// Handle window resize
window.addEventListener('resize', () => {
const width = window.innerWidth;
const height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});

7. Animate

Define the animate function. Make sure to update the environment map of the Cube Camera. Then render the scene using the camera. Also make sure to update the controls in Orbit Controls.

// Render the scene
function animate() {
requestAnimationFrame(animate);
// Update the CubeCamera's environment map
cubeCamera.update(renderer, scene);
// Render the main scene
renderer.render(scene, camera);
controls.update();
}
animate();

7. Save and run the code in local host

Make sure to save the code. Then before running the code using local host, make sure you have installed NodeJS. If not, install NodeJS from the Official Website.

Now open the terminal and then navigate to the project directory that contains the HTML file. Now install the serve package using the below command.

npm install -g serve

After the installation is complete, use the below command to run the code.

npx serve .

Now you will see something like this:

http://localhost:5000

Copy that link and paste it in the web browser. You will be able to get the 360° view of the image now. You can use the mouse to move the camera around.

I hope you learnt how to create 360° image viewer using ThreeJS cube mapping.

If you want to learn more on ThreeJS you can enroll in my course.

--

--