- Three.js Tutorial
- Three.js - Home
- Three.js - Introduction
- Three.js - Installation
- Three.js - Hello Cube App
- Three.js - Renderer and Responsiveness
- Three.js - Responsive Design
- Three.js - Debug and Stats
- Three.js - Cameras
- Three.js - Controls
- Three.js - Lights & Shadows
- Three.js - Geometries
- Three.js - Materials
- Three.js - Textures
- Three.js - Drawing Lines
- Three.js - Animations
- Three.js - Creating Text
- Three.js - Loading 3D Models
- Three.js - Libraries and Plugins
- Three.js Useful Resources
- Three.js - Quick Guide
- Three.js - Useful Resources
- Three.js - Discussion
Three.js - Responsive Design
On resizing the screen, you can observe that the scene is not responsive. Making a web page responsive generally refers to the page displaying well on different sized displays from desktops to tablets to phones. In this chapter, you can see how to solve some fundamental problems of your Three.js app.
Automatically resize the output when the browser size changes
When you resize the browser, we have to notify the Three.js to know how wide the <canvas> element should be. For the camera, we need to update the aspect property, which holds the aspect ratio of the screen, and for the renderer, we need to change its size.
window.addEventListener('resize', () => { // update display width and height width = window.innerWidth height = window.innerHeight // update camera aspect camera.aspect = width / height camera.updateProjectionMatrix() // update renderer renderer.setSize(width, height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) renderer.render(scene, camera) })
Example
The above code gives responsiveness to your Three.js project.
resize-browser.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Three.js – Resizing browser</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: -applesystem, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } html, body { height: 100vh; width: 100vw; } #threejs-container { position: block; width: 100%; height: 100%; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.js"></script> </head> <body> <div id="threejs-container"></div> <script type="module"> // Adding responsiveness for Three.js // sizes let width = window.innerWidth let height = window.innerHeight const gui = new dat.GUI() // scene const scene = new THREE.Scene() scene.background = new THREE.Color(0x262626) // camera const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 100) camera.position.set(0, 0, 10) // cube const geometry = new THREE.BoxGeometry(2, 2, 2) const material = new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true }) const cube = new THREE.Mesh(geometry, material) scene.add(cube) // responsiveness window.addEventListener('resize', () => { width = window.innerWidth height = window.innerHeight camera.aspect = width / height camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) renderer.render(scene, camera) }) // renderer const renderer = new THREE.WebGL1Renderer() renderer.setSize(width, height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) // animation function animate() { requestAnimationFrame(animate) cube.rotation.x += 0.005 cube.rotation.y += 0.01 renderer.render(scene, camera) } // rendering the scene const container = document.querySelector('#threejs-container') container.append(renderer.domElement) renderer.render(scene, camera) animate() </script> </body> </html>
Output
When you execute the code, it will produce the following output −
Now, resize the browser. Due to the responsive design, the object will always reposition itself at the center of the browser.
Anti-aliasing
The aliasing effect is the appearance of jagged edges or "jaggies" (also known as stair-stepped lines) on edges and objects (rendered using pixels).
Example
antialiasing.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Three.js - Anti-aliasing</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: -applesystem, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } html, body { height: 100vh; width: 100vw; } #threejs-container { position: block; width: 100%; height: 100%; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.js"></script> </head> <body> <div id="threejs-container"></div> <script type="module"> // Adding anti-aliasing to Three.js app for removing jaggies // sizes let width = window.innerWidth let height = window.innerHeight const gui = new dat.GUI() // scene const scene = new THREE.Scene() scene.background = new THREE.Color(0x262626) // camera const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 100) camera.position.set(0, 0, 10) // cube const geometry = new THREE.BoxGeometry(2, 2, 2) const material = new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true }) const cube = new THREE.Mesh(geometry, material) scene.add(cube) // responsiveness window.addEventListener('resize', () => { width = window.innerWidth height = window.innerHeight camera.aspect = width / height camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) renderer.render(scene, camera) }) // renderer - anti-aliasing const renderer = new THREE.WebGLRenderer({ antialias: true }) renderer.physicallyCorrectLights = true renderer.setSize(width, height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) // animation function animate() { requestAnimationFrame(animate) cube.rotation.x += 0.005 cube.rotation.y += 0.01 renderer.render(scene, camera) } // rendering the scene const container = document.querySelector('#threejs-container') container.append(renderer.domElement) renderer.render(scene, camera) animate() </script> </body> </html>
Output
Aliasing in our Hello cube app looks like this.
We can turn on anti-aliasing by setting antialias property of the WebGLRenderer to true. By default, it is false. Here, we set the antialias parameter to true −
const renderer = new WebGLRenderer({ antialias: true }) renderer.physicallyCorrectLights = true
After antialiasing, it looks smooth without jaggies like the one below.
The property physicallyCorrectLights tells Three.js whether to use physically correct lighting mode. Default is false. Setting it to true helps increase the detail of the object.