How to make a skybox in Three.js: A perfect guide

A skybox or a cubemap is an interesting topic if you want to create a scene of nature, open ambient, a room, and so on. The skybox looks the same as an HDR image in 3D space, where you can see the 360-degree view of the area you want to simulate; the difference is that creating a cubemap or sky box is much easier and showing it in Three.js takes a different method from the HDR image background. You can also zoom in on different views when using skybox in your three.js scene. To create a Cubemap or a Skybox, we need to create a cube using the box geometry; then create six photos from the area you want to render and show in your scene. These six photos should be taken from the center’s upward, downward, left, right, front and back views. Then, they should be added to the array of material textures. This mapping should be on the backside, and the camera’s position should be limited to the area inside the cube.

A simple example from scratch:

We will get started with the main elements of a Three js scene, including the camera, the renderer, the scene, and the object. Before doing that, we use the Vite plugin to easily create all the folders and files you need to run the Three.js code. First off, create a folder in the directory of your projects by using the following commands: mkdir Skybox
cd SkyBox
Then, inside of the your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create vite@latest Then enter the name of the project. You can write the name of your project as the name. And also the package (the name is arbitrary, and you can choose anything you want). Then select vanilla as the framework and variant. After that, enter the following commands in the terminal. Notice that here SkyBox is the project folder’s name, and thus, we have changed the directory to SkyBox. The name depends on the name you enter in the Vite plugin : cd SkyBox
npm install
Afterward, you can enter the JavaScript code you want to write in the main.js file. So, we will enter the base or template code for running every project with an animating object, such as a sphere. Also, do not forget to install the Three.js package library every time you create a project: npm install three

The code:

Now, enter the following script in the main.js file:

import * as THREE from 'three';
import { Mesh } from 'three';
import {OrbitControls} from "/node_modules/three/examples/jsm/controls/OrbitControls.js";
import Stats from "/node_modules/three/examples/jsm/libs/stats.module.js";
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight , 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
     antialias : true
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

//creating a cube
const geometry = new THREE.BoxGeometry(8,8,8);
var materials = [
     new THREE.MeshBasicMaterial({
          map : new THREE.TextureLoader().load('./img/1.bmp'),
          side : THREE.BackSide,
     }),
     new THREE.MeshBasicMaterial({
          map : new THREE.TextureLoader().load('./img/2.bmp'),
          side : THREE.BackSide,
     }),
     new THREE.MeshBasicMaterial({
          map : new THREE.TextureLoader().load('./img/3.bmp'),
          side : THREE.BackSide,
     }),
     new THREE.MeshBasicMaterial({
          map : new THREE.TextureLoader().load('./img/4.bmp'),
          side : THREE.BackSide,
     }),
     new THREE.MeshBasicMaterial({
          map : new THREE.TextureLoader().load('./img/5.bmp'),
          side : THREE.BackSide,
     }),
     new THREE.MeshBasicMaterial({
          map : new THREE.TextureLoader().load('./img/6.bmp'),
          side : THREE.BackSide,
     }),
];
const cube = new THREE.Mesh(geometry,materials);
scene.add(cube)
camera.position.z = 15
const controls = new OrbitControls(camera,renderer.domElement)
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
     camera.aspect = window.innerWidth / window.innerHeight
     camera.updateProjectionMatrix()
     renderer.setSize(window.innerWidth, window.innerHeight)
     render()
}
const stats = Stats()
document.body.appendChild(stats.dom)

function animate() {
     requestAnimationFrame(animate)
     render()
}

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

animate()


Next, we should copy and paste the 6 photos of the sky box in the img folder that you have created in the directory of the project. You can get the sky box images from a website like OpenGameArt.org. Now if we save the code, and enter the following command in the terminal: npm run dev The above script will give the following result:

Screenshot 2022 07 23 03 28 06 How to make a skybox in Three.js: A perfect guide

Screenshot 2022 07 23 03 27 14 How to make a skybox in Three.js: A perfect guide

Now, there are 2 problems that we need to deal with. The first one is that we do not want to see beyond the sky box and the second one is that. The cube shape of the background borders will make the background scene unrealistic. To solve the first problem, we need to set a limit for the zoom in and zoom out freedom using the below the script:

window.addEventListener('change', renderer)
controls.minDistance = 0
controls.maxDistance = 4


To cover the second problem, we can either change the size of the cube to larger dimensions:

const geometry = new THREE.BoxGeometry(800,800,800);


Or change the zoom in and zoom out limit:

window.addEventListener('change', renderer)
controls.minDistance = 0
controls.maxDistance = 0.04


If you look at the very first code, you will notice that this one is not very different from the dice example article we covered in the last articles we covered on blog. If we save the code, the result will look much nicer, more realistic and more importantly, the background will always be inside the sky box.

Screenshot 2022 07 23 22 55 24 How to make a skybox in Three.js: A perfect guide

Conclusion

In this tutorial, we learned how to create a skybox and make a background scene using this method. To create a skybox, we first created a cube and then added the six textures on the sides of the same cube which represents the background of an open area like a sea. To see the scene from inside the cube, we will need to select the backside of each side of the cube. And to keep the view inside of the sky box, we will need to set some limits for the area we want to zoom in and zoom out. The sky box or the cube map is one of the ways we can add the 360-degree background to the scene. However, if the zooming freedom range is set high, meaning that if we can zoom into the cube with a high range of freedom the scene will look less realistic and everyone will notice that the background is created inside of a cube. To solve this problem, we suggested an easy solution.

Download this Article in PDF format

3d websites

Arashtad Custom Services

In Arashtad, we have gathered a professional team of developers who are working in fields such as 3D websites, 3D games, metaverses, and other types of WebGL and 3D applications as well as blockchain developemnet.

Arashtad Services
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development