”;
Using Dat.GUI
It is hard to keep experimenting with the values of variables, like the cube’s position. In that case, suppose until you get something you like. 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 here 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/libs/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 initialize 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, 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 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 line, use .name(“your label”).
gui.add(cube.position, ''y'').name(''cube-y'')
You can set up min/max limits and steps for getting the slider. The following line 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, 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 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.
-
Stats − Statistics play an important role in large-scale applications.
”;