In this article, I am going to give the basics on how to create 3D graphics in the browser. In order to achieve this, we shall be using WebGL and Three.js. So, let us begin with:
What is WebGL? And what is Three.js?
Three.js is an open-source javascript library “that makes 3D in the browser easy to use”.
WebGL is the API used for rendering.
The real significance of WebGL is that the performance is very good for real-time graphics. It also has provisions for the usage of the GPU, which means that we can create games, visualizations, effects, etc., all inside the browser.
Prerequisites
- Your 3D model object should be in OBJ format
- Your textures should be in a format that Three.js should handle (png, jpg)
- An accompanying MTL file. This file is generated automatically for you by the software. The MTL file is associated with the details of textures and mentions the materials of the model you are creating.
- The latest version of Three.js library
- Detector, which detects if your browser can handle WebGL.
- OBJLoader and MTLLoader for loading your files.
- OrbitControls for controlling a camera that looks at and orbits around your model
First, download all prerequisite files and reference them in your HTML document like below
<html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My first Three.js app</title> <link rel="stylesheet" type="text/css" href="style.css"> <script src="Three.js"></script> <script src="OBJLoader.js"></script> <script src="MTLLoader.js"></script> <script src="OrbitControls.js"></script> </head> <body> <script> // Our Javascript will go here. </script> </body> </html>
Using Three.js
The following steps explain how your 3D model viewed in web browser:
- Creating the scene
- Creating a camera
- Setting up renderer
- Adding a light
- Adding a model
- Initializing orbit controls
ALSO READ: 10 Useful Tools For Laravel Development
Creating the scene
To display anything with Three.js, you are required to create three things: A scene, a camera and a renderer.
Doing so, you’ll be able to render the scene with the camera. Let’s start with a scene:
var scene = new THREE.Scene();
Creating a camera
After setting up the scene, you have to create a camera. Consider it as the viewpoint that users are looking from.
var camera = new THREE.PerspectiveCamera(65,window.innerWidth/window.innerHeight, 1,1100);
Let me explain what’s going on here. Three.js has a few different cameras, but in order to keep the code simple, I’ve used a PerspectiveCamera.
In the above code, there are four attributes: the first is the vertical field of view (from bottom to top) in degrees. Next is the aspect ratio which, as usual for all objects. The last two attributes are the near and the far clipping planes, which are used to control the rendering of objects. In our example, it means the object that is too far or too close to the camera won’t be rendered.
Setting up renderer
Once the camera is created, I am going to set up the WebGLRenderer. In addition to the WebGLRenderer, Three.js has some other renderers – like CanvasRenderer – which can be used as fallbacks for users whose browsers don’t support WebGL for some reason
var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);
As you can see, in addition to creating an instance of the renderer, we also have to set the size at which we want the renderer to display our app. In this example, I have used the width and height of the browser window to mention the size. Then, the renderer element is added to the HTML page. Also, it is to be noted that the <canvas> element is used by the renderer to draw the scene.
ALSO READ: Build A Micro-Frontend Application Using Angular Elements
Adding a light
After setting the renderer, we can do other things, such as add lighting to the scene. It is not complicated at all to append Three-point lighting to the scene you have created. We do this using directional lights. The whole point is to add more sophisticated lighting to the model.
var light = new THREE.PointLight(0xEEEEEE); light.position.set(10, 0, 10); scene.add(light); var lightAmb = new THREE.AmbientLight(0x777777); scene.add(lightAmb);
Adding a model
Both the MTLLoader and OBJLoader, do not need much explanation. All they need is a file path and a callback function. Other edits to the object are also simple. For example, if the object needs to be translated, rotated or scaled, you need to just assign a new THREE.Vector3(x, y, z) to the specific property of your object. Alternatively, you can try some of the functions listed out in the Object3D documentation.
You can safely omit the two filter settings, which I have used for the pixelated look of my model to keep the texture sharp. You can read more about texture filtering in the Three.js documentation.
var mtlLoaderChair = new THREE.MTLLoader(); mtlLoaderChair.setBaseUrl('assets/chair/'); mtlLoaderChair.setPath('assets/chair/'); mtlLoaderChair.load('chair.mtl', function (materials) { materials.preload(); materials.materials.fusta_taula.map.magFilter = THREE.NearestFilter; materials.materials.fusta_taula.map.minFilter = THREE.LinearFilter; var objLoaderChair = new THREE.OBJLoader(); objLoaderChair.setMaterials(materials); objLoaderChair.setPath('assets/chair/'); objLoaderChair.load('chair.obj', function (object) { object.position.y = -40; object.position.z = 330; object.scale.set(80,80,80); object.rotation.x = .01; scene.add(object); }); });
Initializing orbit controls
Finally, after all, has been done, we need to initialize the orbit controls. Have a look at the variables at the beginning of the source code to see what’s possible.
controls = new THREE.OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.25; controls.enableZoom = true;
Here is the full code: here
For debugging, you can get into these links: Three.js Inspector, WebGL Inspector
Conclusion
Following the above procedure, we can now see an animating 3D model in your browser. For more examples, check this.
To learn more, see Three.js.