- Three.js - Discussion
- Three.js - Useful Resources
- Three.js - Quick Guide
- Three.js - Libraries and Plugins
- Three.js - Loading 3D Models
- Three.js - Creating Text
- Three.js - Animations
- Three.js - Drawing Lines
- Three.js - Textures
- Three.js - Materials
- Three.js - Geometries
- Three.js - Lights & Shadows
- Three.js - Controls
- Three.js - Cameras
- Three.js - Debug and Stats
- Three.js - Responsive Design
- Three.js - Renderer and Responsiveness
- Three.js - Hello Cube App
- Three.js - Installation
- Three.js - Introduction
- Three.js - Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Three.js - Debug & Stats
Using Dat.GUI
It is hard to keep experimenting with the values of variables, pke the cube’s position. In that case, suppose until you get something you pke. It s a kind of slow and overwhelming process. Luckily, there is already a good solution available that integrates great with Three.js, dat.GUI. It allows you to create a fundamental user interface component that can change variables in your code.
Installation
To use dat.GUI in your project, download it
and add the <script> tag to the HTML file.<script type= text/javascript src= path/to/dat.gui.min.js ></script>
Or you can use CDN, add the following <script> tag inside your HTML.
<script src="https://cdnjs.cloudflare.com/ajax/pbs/dat-gui/0.7.7/dat.gui.js"></script>
If you are using Three.js in a node app, install the npm package - dat.GUI and import it into your JavaScript file.
npm install dat.gui
OR
yarn add dat.gui import * as dat from dat.gui
Usage
First, you should initiapze the object itself. It creates a widget and displays it on the screen top rightcorner.
const gui = new dat.GUI()
Then, you can add the parameter you want to control and the variable. For example, the following code is to control the y position of the cube.
gui.add(cube.position, y )
Example
Try adding other position variables. Refer to this working code example.
cube.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 - Position GUI</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: -applesystem, BpnkMacSystemFont, 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/pbs/three.js/r128/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/pbs/dat-gui/0.7.7/dat.gui.js"></script> </head> <body> <span id="threejs-container"></span> <script type="module"> // Adding UI to debug and experimenting different values // UI const gui = new dat.GUI() // sizes let width = window.innerWidth let height = window.innerHeight // 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 }) gui.add(material, wireframe ) const cube = new THREE.Mesh(geometry, material) scene.add(cube) gui.add(cube.position, x ) gui.add(cube.position, y ) gui.add(cube.position, z ) // 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
You can customize the label displayed using the name attribute. To change the label on the variable pne, use .name("your label").
gui.add(cube.position, y ).name( cube-y )
You can set up min/max pmits and steps for getting the spder. The following pne allow values from 1 to 10, increasing the value by 1 at a time.
gui.add(cube.position, y ).min(1).max(10).step(1) // or gui.add(cube.position, y , 1, 10, 1)
If there are many variables with the same name, you may find it difficult to differentiate among them. In that case, you can add folders for every object. All the variables related to an object be in one folder.
// creating a folder const cube1 = gui.addFolder( Cube 1 ) cube1.add(redCube.position, y ).min(1).max(10).step(1) cube1.add(redCube.position, x ).min(1).max(10).step(1) cube1.add(redCube.position, z ).min(1).max(10).step(1) // another folder const cube2 = gui.addFolder( Cube 2 ) cube2.add(greenCube.position, y ).min(1).max(10).step(1) cube2.add(greenCube.position, x ).min(1).max(10).step(1) cube2.add(greenCube.position, z ).min(1).max(10).step(1)
Example
Now, check the following example.
gui-folders.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 - More variables</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: -applesystem, BpnkMacSystemFont, 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/pbs/three.js/r128/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/pbs/dat-gui/0.7.7/dat.gui.js"></script> </head> <body> <span id="threejs-container"></span> <script type="module"> // Adding folders to distinguish between variables // controls const gui = new dat.GUI() // sizes let width = window.innerWidth let height = window.innerHeight // 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) const camFolder = gui.addFolder( Camera ) camFolder.add(camera.position, z ).min(10).max(60).step(10) // cube const geometry = new THREE.BoxGeometry(2, 2, 2) const material = new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true }) const cubeColor = { color: 0xffffff } const materialFolder = gui.addFolder( Material ) materialFolder.add(material, wireframe ) materialFolder.addColor(cubeColor, color ).onChange(() => { // callback material.color.set(cubeColor.color) }) materialFolder.open() const cube = new THREE.Mesh(geometry, material) scene.add(cube) const cubeFolder = gui.addFolder( Cube ) // for position const posFolder = cubeFolder.addFolder( position ) posFolder.add(cube.position, x , 0, 5, 0.1) posFolder.add(cube.position, y , 0, 5, 0.1) posFolder.add(cube.position, z , 0, 5, 0.1) posFolder.open() // for scale const scaleFolder = cubeFolder.addFolder( Scale ) scaleFolder.add(cube.scale, x , 0, 5, 0.1).name( Width ) scaleFolder.add(cube.scale, y , 0, 5, 0.1).name( Height ) scaleFolder.add(cube.scale, z , 0, 5, 0.1).name( Depth ) scaleFolder.open() cubeFolder.open() // 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
You can also add some callback functions. onChange is triggered once the value is changed.
gui.add(cube.position, y ).onChange(function () { // refresh based on the new value of y console.log(cube.position.y) })
Let s see another example of changing color using dat.gui and callbacks.
// parameter const cubeColor = { color: 0xff0000, } gui.addColor(cubeColor, color ).onChange(() => { // callback cube.color.set(cubeColor.color) })
The above callback onChange notifies Three.js to change the cube color when the color from cubeColor changes.
We are going to use this dat.gui a lot from now. Make sure you get used to it by experimenting with the "Hello Cube!" app.
− Statistics play an important role in large-scale apppcations.