How to make a rotating 3D cube with Three.js?
Have you ever used JavaScript to make a 3D object? Of course, you very well may have. However, using pure JavaScript to create 3D needs a lot of code, which is where Three.js shines. You can create 3D environments in your browser with Three.js with a very minimal level of complexity.
This article aims to introduce you to the capabilities of Three.js by creating a straightforward three-dimensional spinning cube. To help you understand how Three.js truly functions, I’ve provided live working code examples and an explanation of how to create a spinning 3D cube. I hope this tutorial will be quite helpful to you, especially if you are new to the 3D world. Let’s begin to understand Three.js.
What is Three.js?
Three.js is a free, open-source, and compact JavaScript 3D library that eliminates the need for expensive browser add-ons to create and show animated, interactive 3D computer graphics on any supported web browser. An equivalent in Three.js is merely a portion of a simple cube in raw WebGL, which generates hundreds of lines of Shader and JavaScript code.
Three.js allows you to use JavaScript as part of a website to generate GPU-accelerated 3D animations and is compatible with all WebGL-capable browsers. You can quickly create objects, cameras, materials, lights, and much more using Three.js. The best part is that you can combine Three.js scripts with HTML5 canvas, SVG, CSS3D, or WebGL.
Unfortunately, not all browsers can display 3D animations. At the moment, we are limited to using Google Chrome, Mozilla Firefox, Safari, and Opera at the moment, while Internet Explorer 11 has limited WebGL support. The most recent versions of Chrome and Firefox come with default WebGL functionality enabled. Hopefully, full support for Internet Explorer will increase in the next few years.
Let’s start With Three.js
The Setup of three.js
Create a folder on your desktop called “ThreeJS” first. It can be given whatever name you choose and placed wherever you like.
Make two files in this folder next. The initial file is a standard index.html
file. We’ll call the second one script.js
, a JavaScript file. Put the following code in your index.html file by copying it:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial- scale=1.0" />
<title>Codedamn Blog Three.js</title>
</head>
<body style="margin: 0; padding: 0">
<!-- CDN url to import three.js library -->
<script
defer
src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r125/three.js"
></script>
<script defer src="./script.js"></script>
</body>
</html>
Code language: HTML, XML (xml)
Here, we’re using two scripts to create a simple HTML file. While the second script is the JavaScript that we’ll be building in this lesson, the first script is a CDN to the ThreeJS library. Both script tags’ defer attributes instruct browsers to delay the execution of certain scripts until the page has fully loaded.
Although this characteristic isn’t strictly necessary, it’s a nice precaution as our CDN pulls content from a distant server. I typically avoid using inline styling, but since we only need to remove any default padding and margins, it will work perfectly for us. For the remainder of this tutorial, we won’t touch this HTML file. That’s all. All the code we’re going to create will go into the empty <script> tag.
Creating the Scene in three.js
Three.js requires that you produce the following three things in order to display anything:
- Scene,
- Camera,
- Renderer
By doing this, you’ll be able to use the camera to render the scene. Start with a scene, please.
Scene
Everything we wish to display in our application goes into the Scene object. For instance, you would include this teapot model in the scene if you wanted to display a teapot model. Do you want the teapot to be on the floor? The floor model must also be included in the scene. Write the below line to make your scene.
var scene = new THREE.Scene();
Code language: JavaScript (javascript)
The next step is to create the camera after setting up the scene.
Camera
Think of the camera as representing the user’s point of view. Copy the below code and paste it right after the scene.
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 1, 10000);
Code language: JavaScript (javascript)
Our camera, which we utilize to watch our scene, is created by the code mentioned above. Let me describe the situation. Although ThreeJS offers a variety of camera kinds, the PerspectiveCamera that we are using here is the most popular. Four arguments are captured by this camera:
The field of view, or FOV, serves as the first parameter. This is the perspective that our camera can capture. You can view more with a higher FOV without turning the camera. If you enjoy playing games like PUBG or Fortnite, you’re undoubtedly already aware of this: a greater FOV enables you to view more of the surrounding game environment, which makes it easier to identify enemies. A smaller FOV, on the other hand, limits what you can see. A reduced FOV is advantageous when utilizing real-world cameras for close-up photography. You can fit more pixels into an object you’re wanting to get up close to, like a bowl of fruit, by using a lens with higher magnification and lower FOV.
Our aspect ratio, which is the ratio of the screen’s width to its height, serves as the second argument. The most prevalent aspect ratio is 16:9, which is frequently found in TVs and computer monitors. This is due to the fact that the most popular screen resolutions—such as 1280×720, 1920×1080, and 3840×2160 (also known as 4K)—can all be scaled down to 16×9. window.innerWidth
and window.innerHeight
describes the width and height of the actual HTML body that we view.
The two final arguments—near and far—tell us about the camera’s field of view. The near value in our code is 0.1, and our far value is 500. This means that anything beyond 500 meters will not be visible to our camera. Similar to that, nothing closer than 0.1 meters will be seen. This page provides various sliders so you can conceptually understand how the perspective camera functions.
Renderer
Everything comes together in the renderer. Copy and paste the below code just after the camera.
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);
Code language: JavaScript (javascript)
We must first identify the type of rendering engine we are using. We are informed in the first line that we want to use the WebGLRenderer. Other renderers in Three.js, such as CanvasRenderer, can be used as fallbacks for users whose browsers do not, for whatever reason, support WebGL.
Using the renderer’s setSize()
method, the second line instructs the engine what our renderer’s dimensions should be. In this instance, we pass in our window.innerWidth
and window.innerHeight
values as we want them to fill the whole browser view.
Next, we call the render()
method on our renderer to provide the precise content we want to display. Using our scene and camera, this technique essentially commands the camera to focus on the scene. In order for the renderer to know what it needs to display, it instructs our camera to watch our scene.
Last but not least, we must instruct our browser where to place this. Fortunately, our renderer provides a property called domElement, an HTML element that can be attached to our DOM and holds our WebGL view. As you might have predicted, the final line accomplishes this for us by adding our renderer to the body of our webpage.
Complete Code of three.js till now
//create a scene
const scene = new THREE.Scene();
//create a camera
const camera = new THREE.PerspectiveCamera(
90,
window.innerWidth / window.innerHeight,
0.1,
500
);
//create renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);
Code language: JavaScript (javascript)
In your browser, open the index.html file now:
You’re doing great if all you receive is a meaningless, dark nothingness! I guess in ThreeJS. This is not what you want in life. But in ThreeJS, this is advantageous. It indicates that all is well. We must now design our cubic item.
Creating the 3D Cube with Three.js
Let’s add some stuff to our scene now. First, let’s add a blue cube. Two things are required to accomplish this: geometry and material. Our 3D object’s shape will be determined by the geometry. In this instance, a cube will be the shape of our geometry.
Thankfully, ThreeJS offers us access to a variety of straightforward geometries, sometimes known as primitive shapes in computer graphics. All the 3D objects you’ve seen in games or movies are combinations and/or modifications of these primitive shapes, which is why we call them the building blocks of all 3D objects. One such form is a cube, and ThreeJS offers geometries for all of them, in addition to spheres, cones, and cylinders. Using ThreeJS’s BoxGeometry()
object, we can build the geometry for our cube. Anywhere after our camera and before our renderer code, insert the following piece of code:
const geometry = new THREE.BoxGeometry(1, 1, 1);
Code language: JavaScript (javascript)
A cubic shape of 1 meter in width, 1 meter in length, and 1 meter in depth will result from this. You have a total of five arguments in your BoxGeometry()
. The width, height, and depth of the sides are the last three optional parameters, and their default value is 1, which refers to the number of segmented faces along each. However, these three parameters are sufficient for now.
Our material is the second item we require. The material explains a variety of things, including the color of the object and how it interacts with light. Different effects can be produced by various materials. For instance, a shiny ball has a material that is glossy, whereas the fabric of my sweater is more velvety. We’ll use MeshBasicMaterial, the most basic material ThreeJS has to offer, to create our cube. Add the following code right after our geometry code:
var material = new THREE.MeshBasicMaterial({color: 0xfffff, wireframe: false});
Code language: JavaScript (javascript)
To make it easier for you to see the animating cube, set the wireframe to true. But here I set it to false to make it look solid. Now we want to combine our geometry and material. We have both: we have our cube and our blue. We desire the blue cube. To accomplish this, we will build a mesh. When we mix geometry with a material, we get a mesh. In other words, it provides information about the shape and composition of our object. Add the following line of code after our material:
var cube = new THREE.Mesh(geometry, material);
Code language: JavaScript (javascript)
Simply put, this line of code instructs the computer to construct a new mesh with our cubic geometry and blue material. We call it the “blue cube.” All we have to do is add it to our scene as follows:
scene.add(cube);
Code language: JavaScript (javascript)
We just give it to our scene’s add()
method to add something to it. Currently, reload your browser.
As you see, we can’t see the cube, but it is there. We are unable to view it because ThreeJS by default positions any new object we create at (0, 0, 0), also known as our origin, which is located at the (x, y, z) coordinates of the middle of our screen. Both the cube and the camera are at the starting point. We simply need to move the camera back a little to make room for our cube in order to remedy this. After the line of code where we constructed our camera, insert the following:
camera.position.z = 5;
Code language: JavaScript (javascript)
Our camera will be 5 meters away as a result. The z-axis in ThreeJS extends beyond our screen; the higher the z-value, the closer it will appear to us. While the y-axis moves up and down on our screen, the x-axis moves across it. I couldn’t have explained it better than this image:
Okay, now refresh your screen once again.
It works! Congratulations! You used ThreeJS to create your first 3D application. In a way, it’s not what we wanted. After all, we are getting a square when we construct a cube. Yes, it is a cube, but it is a flat cube in three dimensions. We may rotate the cube along the y-axis and x-axis to add a little more depth to the image.
Animating the Cube
Every time a change is made, whether it be a character sprinting across a bridge or a cube rotating, we must render our scene again in ThreeJS. Yes, a new render is required.
JavaScript includes a built-in method called requestAnimationFrame(foo)
, which will execute the function we pass it, foo, at a target frame rate of 60 frames per second while taking care of any calibration difficulties. We included this requestAnimationFrame()
call inside the definition of our function because it is recursive (we want it to run repeatedly).
A function called “animate” should be created, implemented, and placed immediately before our document.body.append(renderer.domElement)
line:
const animate = () => {
requestAnimationFrame(animate);
cube.rotation.y += 0.01;
cube.rotation.x += 0.02;
renderer.render(scene, camera);
};
Code language: JavaScript (javascript)
Our animate()
function calls the requestAnimationFrame()
function first, sending itself as a parameter to ensure that it will be called again. It will then update the rotation of our cube. By adding 0.02 radians and 0.01 radians to it, we get the x and y values, respectively. Finally, it will update our scene to reflect this modification. Simply call animate()
after its declaration to start this.
animate();
Code language: JavaScript (javascript)
Refresh the page now.
The Result
It’s alive! In addition to rendering a cube, we also managed to make it rotate happily ever after. Congratulations! Your first Three.js application was constructed successfully. This is the complete code:
//create a scene
const scene = new THREE.Scene();
//create a camera
const camera = new THREE.PerspectiveCamera(
90,
window.innerWidth / window.innerHeight,
0.1,
500
);
camera.position.z = 5;
//create an object
const geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0xfffff,
wireframe: false,
});
var cube = new THREE.Mesh(geometry, material);
//add the object to scene
scene.add(cube);
//create renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
//animation loop
const animate = () => {
requestAnimationFrame(animate);
cube.rotation.y += 0.01;
cube.rotation.x += 0.02;
renderer.render(scene, camera);
};
animate();
document.body.appendChild(renderer.domElement);
Code language: JavaScript (javascript)
Conclusion
As you can see, you don’t need to be a highly knowledgeable JS developer to use this fantastic JavaScript library. Anyone familiar with JavaScript’s fundamentals can get started using it right away. But it’s obvious that you can do much more than just rotate a cube. I sincerely hope this tutorial was useful.
Please feel free to share this blog with your friends if you find it useful. If you have any queries related to the front end, do drop them down in the comment section. Also, do check out Codedamn courses if you want to learn HTML, CSS, and JavaScript along with great projects. They also have an in-built playground for different programming languages and environment sets, so do check that out and join Codedamn’s community!
Thank you for reading ?
{Happy Coding!}
Sharing is caring
Did you like what Shubham Gupta wrote? Thank them for their work by sharing it on social media.
No comments so far
Curious about this topic? Continue your journey with these coding courses: