Subscribe to our free newsletter

To make sure you won't miss any valuable content we share with our community.

How to Load an OBJ 3D Model with its Texture in Three JS?

Most of the 3D models that we want to use in games, such as characters, furniture, closed areas, rooms, cars, etc, are designed in the OBJ format and naturally, they have a texture too. The texture is usually exported in the MTL file format. Most of the prepared free models that you will find different on websites that offer 3D models for free like Thingiverse, will give a zip file containing OBJ and MTL file formats. In this tutorial, we will focus on importing OBJ and MTL files in Three JS. This tutorial is an important part of designing your game, animation, or any other kind of web application because there are already many free 3D designs out there on the internet. You only need to import and use them in your scene. So now, let’s get started with the project. Don’t forget to find a 3D model of your choice from where ever you like. Notice that the file needs to have .obj and .mtl file formats. Some of these models have a .png or .jpg photo with them.

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 OBJLoader
cd OBJLoader
Then, inside of your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] 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 OBJLoader is the project folder’s name, and thus, we have changed the directory to OBJLoader. The name depends on the name you enter in the Vite plugin : cd OBJLoader
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

Importing the OBJ 3D model:

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

import * as THREE from 'three';
import { Mesh } from 'three';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
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 pointLight = new THREE.PointLight(0xffffff,5);
pointLight.position.set(0,8000,0);
pointLight.intensity = 5;
scene.add(pointLight);

const pointLight2 = new THREE.PointLight(0xffffff,5);
pointLight2.position.set(2000,3000,4000);
pointLight2.intensity = 5;
scene.add(pointLight2);

const width = 20;
const height = 20;
const intensity = 5;
const rectLight = new THREE.RectAreaLight( 0xffffff, intensity,width, height );
rectLight.position.set( 5000, 5000, 5000 );
scene.add( rectLight );

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);
const controls = new OrbitControls(camera,renderer.domElement);

//Loading the MTL and OBJ files
var mtlLoader = new MTLLoader();
mtlLoader.load('/Models/plane.mtl',function(materials){
     materials.preload();
     var objLoader = new OBJLoader();
     objLoader.setMaterials(materials);
     objLoader.load('/Models/plane.obj',function(object){
          scene.add(object);
     });
});

camera.position.z = 15;
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();
     //stats.update();
};

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

animate();


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:

As you can see, we are observing the smallest details of an airplane with all the textures of the different parts.

Explaining the code:

As always, we added the necessary elements of every scene, such as the scene itself, the camera, the renderer, the orbit controls, and the animation function. Notice that we also imported all the necessary packages for our purpose. The main part of this code is related to loading the OBJ and MTL files where we first imported the MTL and inside of its function added the OBJ file as well. In other words, MTL is the material of the OBJ object. It is like creating an object and adding its material to it. Notice that most of the objects that you find on the internet, are very large or they could be in size. So you should set the lights and the camera according to the dimensions of the given object. Otherwise, you will see nothing or you have to zoom in or zoom out so much in order to see the object clearly. Also, the lighting might not display the object properly. So, you have to set the position and intensity of it, too. We have placed the models in the Models folder and have imported them according to their names. Make sure you set the names according to your files and you should have the files ready for display!

Conclusion

In this tutorial, we have managed to import an object and its texture using the OBJ loader and MTL loader in Three JS. Using such a tool, we can import as many 3D models as we want to create the animation, game, or web application of our choice using Three JS. The .mtl file format works like the material of the object which is imported in the format of .obj. Hope this tutorial has helped you import the 3D models that you like in your Three.js scenes.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

Specular Map Three JS: A Fantastic Tutorial

The specular map is a texture image that affects the specular surface highlight on MeshLambertMaterial and MeshPhongMaterial materials. Using the specular map, you will be able to set the shininess of a surface by giving the a grayscale value from white to black or from 0 to 255. The white points will reflect the light more and the dark points will reflect the light less. In this tutorial, we will create a sphere geometry and map the texture of the globe on then. Next, we will use the grayscale specular map of the globe to determine the shininess on the surface of the globe. In this tutorial, we will also create the a GUI to set different parameters like the shininess, the intensity of the light, the color of the light source, the material and so on. If you would like to enhance your design portfolio in Three JS, follow along with this tutorial.

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 SpecularMap
cd SpecularMap
Then, inside of the your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] 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 SpecularMap is the project folder’s name, and thus, we have changed the directory to SpecularMap. The name depends on the name you enter in the Vite plugin : cd SpecularMap
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 For this project, we need to install dat.gui package as well: npm install --save dat.gui

Implementing the specular map:

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

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import Stats from 'three/examples/jsm/libs/stats.module';
import { GUI } from 'dat.gui';
const scene = new THREE.Scene();
const light = new THREE.PointLight(0xffffff, 2);
light.position.set(0, 5, 10);
scene.add(light);
const camera = new THREE.PerspectiveCamera(
     75,
     window.innerWidth / window.innerHeight,
     0.1,
     1000
);
camera.position.z = 3;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.screenSpacePanning = true;

const SphereGeometry = new THREE.SphereGeometry(1,50,50);
const material = new THREE.MeshPhongMaterial();
const texture = new THREE.TextureLoader().load('img/globe.jpg');
material.map = texture;
const specularTexture = new THREE.TextureLoader().load('img/SpecularMap.jpg');
material.specularMap = specularTexture;
const globe = new THREE.Mesh(SphereGeometry, material);
scene.add (globe);

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);
const options = {
     side: {
          FrontSide: THREE.FrontSide,
          BackSide: THREE.BackSide,
          DoubleSide: THREE.DoubleSide,
     },
     combine: {
          MultiplyOperation: THREE.MultiplyOperation,
          MixOperation: THREE.MixOperation,
          AddOperation: THREE.AddOperation,
     }
};

const gui = new GUI();
const materialFolder = gui.addFolder('THREE.Material');
materialFolder.add(material, 'transparent');
materialFolder.add(material, 'opacity', 0, 1, 0.01);
materialFolder.add(material, 'depthTest');
materialFolder.add(material, 'depthWrite');

materialFolder.add(material, 'alphaTest', 0, 1, 0.01).onChange(() => updateMaterial());
materialFolder.add(material, 'visible');
materialFolder.add(material, 'side', options.side).onChange(() => updateMaterial());

const data = {
     color: material.color.getHex(),
     emissive: material.emissive.getHex(),
     specular: material.specular.getHex(),
};

const meshPhongMaterialFolder = gui.addFolder('THREE.MeshPhongMaterial');

meshPhongMaterialFolder.addColor(data, 'color').onChange(() => {
     material.color.setHex(Number(data.color.toString().replace('#', '0x')))
});
meshPhongMaterialFolder.addColor(data, 'emissive').onChange(() => {
     material.emissive.setHex(Number(data.emissive.toString().replace('#', '0x'));
     )
});
meshPhongMaterialFolder.addColor(data, 'specular').onChange(() => {
     material.specular.setHex(Number(data.specular.toString().replace('#', '0x'));
     )
});

meshPhongMaterialFolder.add(material, 'shininess', 0, 1024);
meshPhongMaterialFolder.add(material, 'wireframe');
meshPhongMaterialFolder.add(material, 'flatShading').onChange(() => updateMaterial());
meshPhongMaterialFolder.add(material, 'combine', options.combine).onChange(() => updateMaterial());
meshPhongMaterialFolder.add(material, 'reflectivity', 0, 1);
meshPhongMaterialFolder.open();

function updateMaterial() {
     material.side = Number(material.side);
     material.combine = Number(material.combine);
     material.needsUpdate = true;
};

function animate() {
     requestAnimationFrame(animate);
     globe.rotation.y += 0.01;
     render();
     stats.update();
};

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

animate();


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:

As you see, we have a rotating globe with the effect of the sun light on the oceans and not on the lands, which is the effect of the specular map. You can set different parameters on the GUI. For instance you can change the shininess of the light source, and also the color of it.

The Specular Map:

Before we get into the details of the code, it is important to notice that we should create a folder in the project directory and call it img. Then inside of that folder paste in the below images related to the texture of the globe and the specular map of it

Explaining the code:

As always, we added the necessary elements of every scene, such as the scene itself, the camera, the renderer, the material, the geometry, the orbit controls, and the animation function. Notice that we also imported all the necessary packages for our purpose. The main part of this code is related to the type of the material, the light source, and the texture mapping. We also wrote many lines of code related to the GUI ( you can skip that part of the script, and yet you will get the same result with the difference that you cannot change the options using the GUI.) We used the main texture of the globe (the RGB photo or the map of the globe) and the specular map containing the RGB values related to the shininess of the surface of the texture, which also represents the land and the sea. For the material, you can use either the Lambert or the Phong material to be able to get the effect that you want. For the light source we should preferably use the point light to be able to simulate the sun light.

Conclusion

In this tutorial, we have managed to create a realistic globe with the shininess effect of the sunlight on the seas and a weaker effect of such on the lands using the specular map in Three JS. Moreover, we created a GUI for the user to set the preferred shininess on the object’s surface (globe). We learned what kind of material, color, light source, and mapping we needed to get the different shininess effects on the different sections of the surface of an object. This was an excellent practice to get the effect we wanted on the surface of various objects with the same mapping.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

How to Rotate Camera in Three JS

This tutorial focuses on a simple but useful animation you can create in your scene by rotating the camera. At first glance, you might think there is no need to rotate the camera as long as we can rotate the object. But in fact, the main reason we need to rotate the camera is that sometimes we need to rotate both the object and the camera, for instance, when you want to simulate the solar system from the Mars point of view. In this situation, you need to keep Mars rotating around the sun; as a result, the camera must be placed in the position of Mars. Moreover, the camera’s rotation can be used for more complex and beautiful animations. In this tutorial, we want to use the scene we created in the last article about the point cloud of a torus knot with the difference that here we also make the camera rotate around a certain point. After you see the result and compare it with the simple animation we had in our previous article, you will understand what difference will using a rotating camera make in your animation.

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 RotateCamera
cd RotateCamera
Then, inside of the your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] 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 RotateCamera is the project folder’s name, and thus, we have changed the directory to RotateCamera. The name depends on the name you enter in the Vite plugin : cd RotateCamera
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 TorusKnot
const geometry = new THREE.TorusKnotGeometry(10, 3, 300, 20 );
const material = new THREE.PointsMaterial({
     //color:0xffff00,
     size: 0.1 
});

const TorusKnot = new THREE.Points(geometry,material);
scene.add(TorusKnot);
camera.position.z = 30;
var angle = 0;
var radius = 5; 

function animate() {
     requestAnimationFrame(animate);
     TorusKnot.rotation.y += 0.002;
     render();
     camera.position.x = radius * Math.cos( angle ); 
     camera.position.z = radius * Math.sin( angle );
     angle += 0.01;
};

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

animate();


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:

Explaining the code:

The tricky part of our code is written in the animation section. If you want to get familiar with how you can create the point cloud effect, you can head over to our recent article with the title ‘Point Cloud Effect in Three JS’. To make the camera rotate, we need to first determine the radius of rotation and the initial angle from which the rotation begins. We have defined these variables as angle and radius. Afterward, in the animation function, we incremented the angle to and change the position of the camera on the circle path using some mathematical calculations. Notice, that the object (Torus knot) is also rotating.

camera.position.z = 30;
var angle = 0;
var radius = 5; 
function animate() {
     requestAnimationFrame(animate);
     TorusKnot.rotation.y += 0.002;
     render();
     camera.position.x = radius * Math.cos( angle ); 
     camera.position.z = radius * Math.sin( angle );
     angle += 0.01;
}


Conclusion

In this article, we focused on the way we can rotate a camera around a particular path. This kind of animation is not just related to the object’s rotation, but we have the camera’s rotation, too. One of the use cases of such a scene is simulating the solar system. However, in this tutorial, we worked on a simpler example: the point cloud of a torus knot. We rotated the camera around a particular path to see the different parts of the rotating object from inside and outside. If you compare the scene we created with the one created in the recent article with the same object and scene, you will notice how beautiful the animation has become compared to it.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

Point Cloud Effect in Three JS

This tutorial will focus on an exciting topic called a point cloud. Technically, we use a point cloud for creating the polygons. Then using the normal of the polygons, we make the meshes. In Three JS, the point cloud is also used for aesthetics, which means we use the points instead of meshes to represent an object or a geometry. This style of representing the objects makes the design more beautiful and charming than the mesh representation. We achieve this goal by simply using the points material and adding the geometry and the material to the points instead of the mesh. Point cloud representation makes your design look more modern and smart. You can use this effect for technological and innovative items and products, giving them a more modern look. Moreover, the point-cloud-based design could provide a fantastic look for any other type of website other than technology or product based. Let’s give it a shot together!

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 PointCloud
cd PointCloud
Then, inside of the your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] 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 PointCloud is the project folder’s name, and thus, we have changed the directory to PointCloud. The name depends on the name you enter in the Vite plugin : cd PointCloud
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 (using the mappings together):

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 TorusKnot
const geometry = new THREE.TorusKnotGeometry(10, 3, 300, 20 );

const material = new THREE.PointsMaterial({
     //color:0xffff00,
     size: 0.1 
})

const TorusKnot = new THREE.Points(geometry,material);
scene.add(TorusKnot);
camera.position.z = 15;
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);
     TorusKnot.rotation.y += 0.002;
     render();
     stats.update();
}
function render() {
     renderer.render(scene, camera);
}

animate();


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:

Explaining the code:

To create the above point cloud effect, we made very few changes to a boilerplate code that we used to copy in all of our three.js scripts. One of these changes was using the PointsMaterial instead of MeshBasicMaterial. Then, by using the size property of the material, we set the size of the points to have enough visibility afterward, instead of using THREE.Mesh, we used THREE.Points to create the objects.

const geometry = new THREE.TorusKnotGeometry(10, 3, 300, 20 );
const material = new THREE.PointsMaterial({
     //color:0xffff00,
     size: 0.1 
})
const TorusKnot = new THREE.Points(geometry,material);


In the below photo, you can see another photo of the torus knot with point cloud effect from another angle:

Conclusion

In this tutorial, we learned how to create the point cloud effect using the points material in Three.js. This effect is very useful for designing modern websites and the concept of modern technology marketing. Creating such an effect is simple and, at the same time, clever. An object’s point cloud representation differs from the PCL loader or PCDLooader function, which loads the point cloud files. There are moments when we have the point cloud file of an object, and we want to import it, which is different from creating the points out of a geometry built in Three.js. If you have an object that you want to import and represent in the point cloud form, make sure you read our articles on the Loaders subject on this blog.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

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 [email protected] 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:

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.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

Bump Map vs Normal Map in Three JS

In many 3D designing platforms, especially in WebGL and the Three.js, we have the concept of bump map, normal map and the displacement map. You have probably heard or read about these three kind of mappings, if you have ever searched about the textures and how to create them. The main reason we use these mappings, is to create either the illusion or the effect of the bumps and dumps on the surface of a texture. Definitely, using the said mappings will make a huge difference in your design and that is why we have decided to talk about these concepts in our article. When we talk about these three mappings, we do not mean the texture itself. Because even if you have a photo of a certain kind of texture or any surface that you might have captured using your camera, you can still map it on top of an object. But if you want to have a natural texture, with all the ups and downs, you definitely need one or a group of the three main mappings. In this article, we want to get familiar with all these mappings and use them in three.js scripts.

What is a bump map?

Bump maps create the illusion of depth and texture on the surface of a 3D model using computer graphics. This kind of mapping is the older version of creating the effect of the wrinkles, cracks, bumps, and dumps. These days, the displacement map and the normal map are more popular because they create the more realistic kind of a texture by creating the actual ups and downs and not just the illusion of it. On the other hand, in the bump map, textures are artificially created on the surface of objects using grayscale and simple lighting tricks, rather than having to manually create individual bumps and cracks. Generally, bump maps are grayscale images that contain 8-bit data of color information. In other words, there are 256 levels between white and black color that determine how deep or how high a point on the surface is. The point with no detail or no up or down, will get 128 or 50 percent of the maximum number. As the color gets more black, the point gets deeper into the surface and as the color gets white, the point will get high.

What is a normal map?

Normal map is the newer version of the bump map and the data related to the bumps and dumps is fake as well. The only difference is that a bump map uses grayscale values to to provide either up or down information. A normal map uses RGB information that corresponds directly with the X, Y and Z axis in 3D space. This RGB information tells the 3D application the exact direction of the surface normals are oriented in for each and every polygon. The orientation of the surface normals, often just referred to as normals, tell the 3D application how the polygon should be shaded.

What is a displacement map?

Contrary to the normal map and the bump map, the displacement map does not create an illusion of up or down. The bumps and dumps will be created in a realistic way and if you apply it on the surface of any object, you will be able to see the ups and downs clearly if zoom onto the surface. Like the bump map, the displacement map uses the grayscale values to measure the ups and downs. The precision can vary from 8-bit to 16 or even 32-bit data. The higher the resolution, the better the end result.

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 Mappings
cd Mappings
Then, inside of the your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] 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 Mappings is the project folder’s name, and thus, we have changed the directory to Mappings. The name depends on the name you enter in the Vite plugin : cd Mappings
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 (using the mappings together):

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

import * as THREE from 'three';
import { Mesh } from 'three';
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 sphere
const geometry = new THREE.SphereGeometry(5,50,50);
const material = new THREE.MeshStandardMaterial({
     map : new THREE.TextureLoader().load('./img/aerial_rocks_02_diff_4k.jpg');
})
material.displacementMap = new THREE.TextureLoader().load './img/aerial_rocks_02_disp_1k.jpg');
material.normalMap = new THREE.TextureLoader().load('./img/aerial_rocks_02_nor_dx_1k.jpg');

const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
camera.position.z = 15;
const width = 20;
const height = 20;
const intensity = 2.5;

const rectLight = new THREE.RectAreaLight(0xffffff, intensity, width, height);
rectLight.position.set( 5, 5, 5 );
rectLight.lookAt( 0.5, 0.5, 0.5 );
scene.add( rectLight );

function animate(){
     requestAnimationFrame(animate);
     renderer.render(scene,camera);
     sphere.rotation.y += 0.003;
}
animate();


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:

To create the the above texture, we used the following script in our code. Notice the normal map and the displacement map. We have used this script in another tutorial on our blog. For understanding about more details of the code you can head over to it and read more.

const material = new THREE.MeshStandardMaterial({
     map : new THREE.TextureLoader().load('./img/aerial_rocks_02_diff_4k.jpg');
})
material.displacementMap = new THREE.TextureLoader().load './img/aerial_rocks_02_disp_1k.jpg');
material.normalMap = new THREE.TextureLoader().load('./img/aerial_rocks_02_nor_dx_1k.jpg');


We have got the texture from polyhaven.com. If you want to use the bump map instead of the displacement map and the normal map, you should rewrite the above code this way:

const material = new THREE.MeshStandardMaterial({
     map : new THREE.TextureLoader().load('./img/aerial_rocks_02_diff_4k.jpg');
})
material.bumpMap = new THREE.TextureLoader().load './img/');


Notice that you should enter the NameOfThePhoto according to the name of the bump map image that you have and do not forget to put it in the img folder that you have created in the project directory

Conclusion

In this article, we got familiar with the different kinds of mappings including the displacement map, normal map and the bump map. We used these mappings to make the texture more realistic. However, some of them only create the illusion of bumps and dumps and if you zoom in, you will understand that there are actually no ups and downs. Moreover, we worked on the script of a texture from scratch and learned how to create a texture on a sphere and add different mappings to the object. This example will help you work with different kinds of textures. We have also covered a full tutorial on this subject in another article on our blog. Make sure to check it out.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

How to Use Multiple Cameras in Three JS

In this tutorial, we will cover one of the less available projects in Three.js on the internet. And that is creating multi-camera scenes. Up to now, nearly all the projects in Three.js that we have seen have the object and scene using only one camera and the viewer was only able to see a certain animation from one view port. But, now using the method we will use in this article, we will be able to cover two or more aspects of the scene. This is wonderful! Because there are some games or animations that need more than view of the scene, and if we can see how to create multiple cameras, we can bring this wonderful feature in our projects and make it more fascinating. The scene we are going to see, is very simple. We will animate a rotating cube and our main camera will cover the moving sides of the cube and the other one will cover the top view of the rotating cube. The top camera will be shown on the top right corner of the browser page, while the main camera will cover the whole page.

Setting up the project:

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 MultiCamera
cd MultiCamera
Then, inside of the your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] 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 MultiCamera is the project folder’s name, and thus, we have changed the directory to MultiCamera. The name depends on the name you enter in the Vite plugin : cd MultiCamera
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';
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer({
     antialias : true
});
//main camera
let camera = new THREE.PerspectiveCamera(
     90,
     window.innerWidth / window.innerHeight,
     0.01,
     500
);
camera.position.set = (0, 0, 0);
camera.lookAt(0, 0, 0);
//Top camera
let Topcamera = new THREE.PerspectiveCamera(
     70,
     (window.innerWidth / 4)/(window.innerHeight / 4),
     0.01,
     500
);
Topcamera.position.set = (0, 0, 0);
Topcamera.lookAt(0, 0, 0);
camera.add(Topcamera);
scene.add(camera);

renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
//creating a cube
const geometry = new THREE.BoxGeometry(5,5,5)
const material = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
//Light source
const width = 20;
const height = 20;
const intensity = 2.5;
const rectLight = new THREE.RectAreaLight(0xffffff, intensity, 
width, height);
rectLight.position.set( 5, 5, 5 );
rectLight.lookAt( 0.5, 0.5, 0.5 );
scene.add( rectLight );
var insetWidth;
var insetHeight;
function resize (){
     camera.aspect = window.innerWidth / window.innerHeight;
     camera.updateProjectionMatrix();
     renderer.setSize(window.innerWidth, window.innerHeight);
     insetWidth = window.innerWidth / 4;
     insetHeight = window.innerHeight / 4;
     Topcamera.aspect = insetWidth / insetHeight;
     Topcamera.updateProjectionMatrix();
}
window.addEventListener("resize", resize);
function animate(){
     requestAnimationFrame(animate);
     cube.rotation.y += 0.02;

     camera.position.x = cube.position.x;
     camera.position.z = cube.position.z + 10;
     Topcamera.position.x = cube.position.x;
     Topcamera.position.y = cube.position.y + 10;
     Topcamera.position.z = cube.position.z - 10;
     Topcamera.rotation.x = -Math.PI/2; 
     renderer.setViewport(0, 0, window.innerWidth, 
     window.innerHeight);
     renderer.render(scene, camera);
     renderer.clearDepth();
     renderer.setScissorTest(true);
     renderer.setScissor(
          window.innerWidth - insetWidth -16,
          window.innerHeight - insetHeight - 16,
          insetWidth,
          insetHeight
     );
     renderer.setViewport(
          window.innerWidth - insetWidth -16,
          window.innerHeight - insetHeight - 16,
          insetWidth,
          insetHeight
     );
     renderer.render(scene, Topcamera);
     renderer.setScissorTest(false);
}
resize();
animate();


Now if we save the code, and enter the following command in the terminal: npm run dev We should see the following result:

As you can see in the above photo, the main camera has captured the main view of the rotating cube, while the top camera has covered the top view of it.

What we did in the code:

The first thing we did at the beginning was to import the necessary libraries. Then, we defined the scene, the light source, the camera, and the renderer. Afterward, we defined another camera named the Top camera with nearly the same properties. The only difference was in the position of the cameras which you can set according to your scene. Notice that we will later change the position and the rotation of the cameras in the animation function. Next, we declared the geometry, material, and finally the object using the first two parameters. Now we need two functions, first one is called resize and it is for resizing the window according to the browser size and the second one is the animation function. Inside the animation function, we write the necessary scripts for rendering the scene using the two cameras. First of all, the cube should rotate, so we wrote the rotation code for that. Then we need to determine the position of the cameras. Notice that the top camera should rotate by 90 degrees as well. Next, we should set the viewport and the scissor of the renderer. Finally, we need to add the scene and the two cameras to the renderer.

Conclusion

In this article, we managed to render a scene using two cameras in different positions with different rotations. Although this project was so simple, it has the necessary scripts and building blocks for the developers to extend and develop it. The use cases of having multiple cameras in the renderer are in the computer games, races, sport matches, animations and so on. The concept of using multiple cameras for the same scene and from different aspects provides excitement and engages the viewer or the player to whatever you have created, whether it is an event, a sports match, or a computer game. Hope you have enjoyed this tutorial. If there is anything ambiguous about the codes we have written, do not worry because we have created a tutorial video based on this article, and have published it in our channel called Arashtad.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

Three.js Realistic Shadows: A Practical Guide

In this tutorial, we want to create more realistic scenes by making the shadow effect. There are many parameters in creating a shadow of an object. One of them is the material. For instance, if you use the Mesh-basic material, you will see no shadow effects. The next important parameter is the light source. Different light sources create various types of shadows. Some of them do not generate any shadow effect on the object. Our blog has covered a complete article about the light sources in Three.js. Another element that can provide the shadow effect is the background scene. There is also another article about background scenes on our blog. Once you use the background for your scene, depending on the quality of the HDR image, the light source (for instance, the sun) will act as a light source like the point light or the rect-area light. Furthermore, we can use the shadow properties of the point light. This tutorial will test these properties and see their effects on a sphere object.

Getting started with the basics:

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 Shadows
cd Shadows
Then, inside of the your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] 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 Shadows is the project folder’s name, and thus, we have changed the directory to Shadows. The name depends on the name you enter in the Vite plugin : cd Shadows
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 { 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 light = new THREE.DirectionalLight();
light.castShadow = true;
light.shadow.mapSize.width = 512;
light.shadow.mapSize.height = 512;
light.shadow.camera.near = 0.05;
light.shadow.camera.far = 200;
scene.add(light);

const camera = new THREE.PerspectiveCamera(
     75,
     window.innerWidth / window.innerHeight,
     0.1,
     1000
)

camera.position.z = 7;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
new OrbitControls(camera, renderer.domElement);

//creating the plane
const planeGeometry = new THREE.PlaneGeometry(20, 20);
const planeMaterial = new THREE.MeshPhongMaterial({
     map : new THREE.TextureLoader().load('./img/aerial_rocks_02_diff_4k.jpg') 
});

planeMaterial.displacementMap = new THREE.TextureLoader().load('./img/aerial_rocks_02_disp_1k.jpg');
planeMaterial.normalMap = new THREE.TextureLoader().load('./img/aerial_rocks_02_nor_dx_1k.jpg');

const plane = new THREE.Mesh(planeGeometry, planeMaterial );
plane.rotateX(-Math.PI / 2);
plane.position.y = -1.75;
plane.position.z = -2;
plane.receiveShadow = true;
scene.add(plane);

//creating the torus
const torusGeometry = new THREE.TorusGeometry(1, 0.3, 16, 100);
const material = new THREE.MeshStandardMaterial();
const torus = new THREE.Mesh( torusGeometry, material);
torus.position.x = 0;
torus.position.y = 0;
torus.castShadow = true;
torus.receiveShadow = true;
scene.add(torus);

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);
     torus.rotation.x += 0.02;
     render();
     stats.update();
}

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

animate();


Now if we save the code, and enter the following command in the terminal: npm run dev We should see the following result:

Which is a rotating torus with its shadow on the texture of the plane. You can rotate around the scene and see from other angles.

You can create a new folder called img and add any texture that you want in it. Notice that in the folder, you should have the normal map, the displacement map, and the texture photo, and also edit the names in the script according to the names of the texture images. If you do not want to have the texture, you can remove the map, displacement map, and normal map from the script. We have downloaded the texture of the above scene from polyhaven.com.

Explaining the code:

The first thing we did at the beginning was to import the necessary libraries. Then, we defined the scene, the point light, the camera, and the renderer. In the point light section of the code, we set the castShadow property to true. Afterward, we set the size and the distance of the shadow. Next, we enabled the shadowMap property for the renderer and specified its type to PCFSoftShadowMap.After that, we created a plane and set its position. We also set the receiveShadow property to true, So that we can see the shadows of the objects on it. We also created a torus and did the same as we did for the plane on it, in addition to setting the castShadow and receiveShadow properties to true so that it can cast the shadow and receive the shadow of itself. In the end, we wrote the animation code for the torus.

Conclusion

In this tutorial, we worked on different shadow properties of the point light, materials, the renderer, and the camera to be able to create the shadow effect. There are two types of shadow properties for the objects. One of them is the cast shadow property which will cast the shadow of the object on the ground, other objects, or itself (not all shapes cast shadows on themselves). And the other one is the receive shadow property that lets the object receive the shadows of other objects. Moreover, the renderer has different types of shadow mapping. In this tutorial, we only used the PCFSoftShadowMap . But, there are other types which you can find the complete list from the official website of Three.js.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

How to Rotate Objects Using Transform control in Three JS

nside every 3D design software, we have the tools for translating the object, meaning we have a button for transferring the object from one point to the other. In addition to that, we have tools for rotating the object and also scaling it. These three are the essential tools for every 3D design application. But imagine a 3D app (software or web application) without orbit controls (having a 360-degree view or rotating around the object); this will result in an annoying user-interactive software everyone hates at first glance. Consequently, every 3D software design app consists of some must-have tools. These essential utilities are, transform controls, and orbit controls, and Three.js is no exception. In this article, we will start from a boilerplate project using the Vite plugin, and then we will modify the script to have all sorts of controls around the object. Some keys on the keyboard will activate the rotation, translation, and scaling tools, each separately. We will also have orbit controls to see everything clearly from all aspects.

Getting started with the basics:

We are going to get started with the simple elements of a Three js scene including the camera, the renderer, the scene, the object and the light source (if necessary). Before we do that, we’d rather use the Vite plugin to be able to easily create all the folders and file that 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 TransformControls
cd TransformControls
Then, inside of the your project folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] 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 that you want). Then select vanilla as the framework and variant. After that, enter the following commands in the terminal: cd TransformControls
npm install
Afterwards, you can enter the javascript code that 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 an sphere. Also do not forget to install Three.js package library every time create a project: npm install three

The code:

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

import * as THREE from 'three';
import {OrbitControls} from "/node_modules/three/examples/jsm/controls/OrbitControls.js";
import {TransformControls} from "/node_modules/three/examples/jsm/controls/TransformControls.js";
import Stats from "/node_modules/three/examples/jsm/libs/stats.module";

const scene = new THREE.Scene();
scene.add(new THREE.AxesHelper(5));

const camera = new THREE.PerspectiveCamera(
     75,
     window.innerWidth / window.innerHeight,
     0.1,
     1000
);

camera.position.z = 2;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshNormalMaterial({ transparent : true });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
const orbitControls = new OrbitControls(camera, renderer.domElement);
const transformControls = new TransformControls(camera, renderer.domElement);
transformControls.attach(cube);
transformControls.setMode('rotate');
scene.add(transformControls);

transformControls.addEventListener('dragging-changed', function (event) {
     orbitControls.enabled = !event.value;
});

window.addEventListener('keydown', function (event) {
     switch (event.key) {
          case 't':
               transformControls.setMode('translate');
               break;
          case 'r':
               transformControls.setMode('rotate');
               break;
          case 's':
               transformControls.setMode('scale');
               Break;
     }  
})

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();
     stats.update();
}

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

animate();


Now if we save the code, and enter the following command in the terminal: npm run dev We should see the following result:

You can rotate the cube if you click on the blue, red or green rings and move them. If you press the “t” on the keyboard, you will see:

You can move the object using the arrows given. And if you press the “s” button, you will be able to see:

You can scale the object in all the directions. Notice that in all three states you can move around the object and have orbit controls, Which will give you a perfect view.

Explaining the code:

The first thing we did at the beginning was to import the necessary libraries for the orbit controls, and the transform controls in addition to other dependency libraries. Then, we defined the scene, camera, renderer, geometry, and material just as we did in our recent tutorials on Three JS. Afterward, we defined the transform control and added the cube to it to be able to apply them to the object. We also defined the orbit controls. To activate each one of the transform controls (rotation, translation, and scaling), we added an event listener and used the switch case statement for each of the transform controls. Moreover, we added another event listener for the orbit controls so that the user can easily interact with the scene. In the end, we animated the object using the animation function.

Conclusion

n this tutorial, we implemented the transform controls, including the rotation, translation, and scaling, in addition to orbit controls which give the user the ability to move around the object and see it from all aspects. Using such a script, you can easily create a user-interactive 3D design application or even a game. As you know, one of the essential tools for every 3D user-interactive app or game is orbit controls and transform controls. Transform control lets the user rotate objects, and move and scale them in Three JS. We hope this tutorial has helped you solve the challenge that you have had in Three JS. We have covered this tutorial in a video so that you can understand this article more deeply.

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 Serivces
Drop us a message and tell us about your ideas.
Fill in the Form
Blockchain Development

How to Create Three.js Tube Efficiently

In this tutorial, we are going to design a tube with the texture of a real-world tube. The process we are going to take starts from scratch and we will cover all of what needs to be explained in order for the beginners to understand. First, we will start with the Vite plugin and then we will extend and develop the main.js file by starting from the simplest scene with cylinder, camera, point lights, material, and so on. Then we will add texture to the design and the kind of texture we will get will be retrieved by searching google for an aluminum sheet, tube normal map, or tube texture. You can find any other texture from anywhere or by any means according to your design preferences. Also, notice that here we will use the rect light for the light source but if this tube is meant to be designed for a room or another area, the appropriate light source needs to be added to the scene.

Getting started with the basics:

We are going to get started with the simple elements of a Three js scene including the camera, the renderer, the scene, the object, and the light source (if necessary). Before we do that, we’d rather use the Vite plugin to be able to easily create all the folders and files that 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 cube
cd cube
Then, inside of the glowing sphere folder, create the necessary files and folders by simply running the Vite plugin command: npm create [email protected] Then enter the name of the project. You can write glowingSphere as the name. And also the package (the name is arbitrary and you can choose anything that you want). Then select vanilla as the framework and variant. After that, enter the following commands in the terminal: cd cube
npm install
Afterward, you can enter the javascript code that 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 an sphere. Also do not forget to install Three js package library every time create a project: npm install three Now, enter the following script in the main.js file:

import * as THREE from 'three';
import { Mesh } from 'three';
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 sphere
const geometry = new THREE.SphereGeometry(5,50,50);
const material = new THREE.MeshBasicMaterial({
     color:0x3268F8
});
const sphere = new THREE.Mesh(geometry,material);
scene.add(sphere);
camera.position.z = 15;

function animate(){
     requestAnimationFrame(animate);
     renderer.render(scene,camera);
     sphere.rotation.y += 0.003;
}
animate();


The above code can be used as a boilerplate for later projects. The output of this code will be blue sphere like the below photo. But to be able to show that, you should write the following command in the terminal: npm run dev

If you want to change the sphere to cylinder, change the below script from:

const geometry = new THREE.SphereGeometry(5,50,50);


To:

const geometry = new THREE.CylinderGeometry(2, 2, 20, 32);


If you save the code, the result will be a rotating cylinder like this:

And if you want to change the material from basic mesh to standard, change the code from:

const material = new THREE.MeshBasicMaterial({
    color:0x3268F8
});


To:

const material = new THREE.MeshStandardMaterial({
    color:0x3268F8
});
material.roughness = 0.2;
material.metalness = 0.8;


And also add 1 Rect area light to the scene so that you can see the cylinder made with the standard mesh material::

const width = 20;
const height = 20;
const intensity = 10;
const rectLight = new THREE.RectAreaLight( 0xffffff, intensity, width, height);
rectLight.position.set( 5, 5, 5 );
rectLight.lookAt( 0.5, 0.5, 0.5 );
scene.add( rectLight );


Result:

Adding texture to the Cylinder:

One of the important things that makes your objects more beautiful and decorated, is adding texture to them. The process is so easy, you can google any texture that you want and download it. Then use the map property of the material and load the photo of the texture to the surface of the object by giving the address of the image. For instance, you want to add the tube texture on your+ cylinder. We google it and find this photo:

Now, we will create a new folder called img in the directory of the project and add the above texture image to that folder. Then we will add the below code under the material and save the main.js

material.map = new;
THREE.TextureLoader().load('./img/tube.jpeg');


The result will be a more realistic tube:

You can add any other texture of your choice and taste to the surface of the cylinder to make it sound like a tube depending on the kind of scene that you have and the kind of place you want to design it for. In general, to make a real-world object, you will need to get a natural texture. But that is not the whole story! You will also need to consider proper lighting, camera position, size of the texture, and so on. In some cases, you may even need to change the material or add shaders. We have provided many tutorials and articles on Youtube and on our blog so that you can get familiar with the different tricks that you can use in order to design a natural object and consequently a natural scene.

Conclusion

In this article, we have managed to introduce an easy way to create a natural tube from scratch. At first, we designed a normal object with mash basic material. Then we changed the object geometry to the cylinder. Afterward, we changed the material from basic to standard and added the Rect area light in order to simulate the light of the window. To make the cylinder look like a tube, we added the mapping property to the material, and using it, we addressed the directory of the texture that we had downloaded from Google. The texture helped us create a real-world tube. We can add many effects to the tube and for the bending tube, we can import a model of it in Three js and add the proper material, color, shader, lighting, and so on, so that in the end we would get the kind of tube that we want. We have provided many tutorials on Youtube and on our blog about creating textures, shaders, different light sources, and so on. Using a combination of all these techniques you will hopefully be able to create an even more amazing result for your taste.

Download this Article in PDF format

metaverse

Curious about What We’re Up To?

In Arashtad we provide custom services in various design and development fields. 3D websites, 3D games, metaverses, and other types of WebGL and 3D applications are just some of our expertise.

Arashtad Serivces
Drop us a message and tell us about your ideas.
Request a Quote
Blockchain Development