dat.GUIを使用して、開発時の3Dオブジェクトの編集を行いやすくする
今回、THREE.jsを使用した3Dオブジェクトやpixi.jsを使用した2Dオブジェクトなどの開発時に利用したdat.GUIについてのやり方を紹介します。
今回使用するもの
NPM
version: 0.123.0
version: 0.7.7
CDN
https://cdnjs.cloudflare.com/ajax/libs/three.js/r123/three.min.js
https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js
完成形
const scene = new THREE.Scene(); scene.background = new THREE.Color( 0x000000 ); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); 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.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); camera.position.z = 5; const datGUIObj = { positionZ: 5, rotateXSpped: 0.01, rotateYSpped: 0.01, cubeWireframe: true, backColor: { red: 0, green: 0, blue: 0 }, cubeColor: { red: 0, green: 1, blue: 0 } }; const gui = new dat.GUI(); gui.add(datGUIObj, 'positionZ', 0, 10); gui.add(datGUIObj, 'rotateXSpped', 0, 0.1); gui.add(datGUIObj, 'rotateYSpped', 0, 0.1); gui.add(datGUIObj, 'cubeWireframe'); const backGUI = gui.addFolder('Back Color'); backGUI.add(datGUIObj.backColor, 'red', 0, 1).name('Red').step(0.01) backGUI.add(datGUIObj.backColor, 'green', 0, 1).name('Green').step(0.01) backGUI.add(datGUIObj.backColor, 'blue', 0, 1).name('Blue').step(0.01) const colorGUI = gui.addFolder('Cube Color'); colorGUI.add(datGUIObj.cubeColor, 'red', 0, 1).name('Red').step(0.01) colorGUI.add(datGUIObj.cubeColor, 'green', 0, 1).name('Green').step(0.01) colorGUI.add(datGUIObj.cubeColor, 'blue', 0, 1).name('Blue').step(0.01) colorGUI.open() const animate = function () { requestAnimationFrame( animate ); cube.material.wireframe = datGUIObj.cubeWireframe; scene.background.r = datGUIObj.backColor.red; scene.background.g = datGUIObj.backColor.green; scene.background.b = datGUIObj.backColor.blue; cube.material.color.r = datGUIObj.cubeColor.red; cube.material.color.g = datGUIObj.cubeColor.green; cube.material.color.b = datGUIObj.cubeColor.blue; camera.position.z = datGUIObj.positionZ; cube.rotation.x += datGUIObj.rotateXSpped; cube.rotation.y += datGUIObj.rotateYSpped; renderer.render( scene, camera ); }; animate();
実装手順
1. ベースのプログラムを反映
今回は以下のリンクの一番下にあるコードを使用します。
<!DOCTYPE html> <html> <head> <title>My first three.js app</title> <style> body { margin: 0; } </style> </head> <body> <script src="js/three.js"></script> <script> const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); 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.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); camera.position.z = 5; const animate = function () { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); }; animate(); </script> </body> </html>
上記のコードをコピーすると以下のような状態になります。
2. dat.GUIの反映
// npmでインストールした場合 import * as dat from 'dat.gui'; // これから要素の変更を行うための大枠 const datGUIObj = {} // ここでdat.GUIのメニューを表示 const gui = new dat.GUI();
これで右上に Close Controls
が表示されます。(現時点ではメニュー項目は一切ないです。)
3. 各種パラメータの追加
回転する速度の調整
const datGUIObj = { rotateXSpped: 0.01, rotateYSpped: 0.01, }; gui.add(datGUIObj, 'rotateXSpped', 0, 0.1); gui.add(datGUIObj, 'rotateYSpped', 0, 0.1); const animate = function () { requestAnimationFrame( animate ); cube.rotation.x += datGUIObj.rotateXSpped; cube.rotation.y += datGUIObj.rotateYSpped; renderer.render( scene, camera ); };
カメラの位置の修正
const datGUIObj = { positionZ: 5, }; gui.add(datGUIObj, 'positionZ', 0, 10); const animate = function () { requestAnimationFrame( animate ); camera.position.z = datGUIObj.positionZ; renderer.render( scene, camera ); };
ワイヤーフレームのON, OFF設定
const datGUIObj = { cubeWireframe: true, }; gui.add(datGUIObj, 'cubeWireframe'); const animate = function () { requestAnimationFrame( animate ); cube.material.wireframe = datGUIObj.cubeWireframe; renderer.render( scene, camera ); };
色の変更
const datGUIObj = { cubeColor: { red: 0, green: 1, blue: 0 } }; // dat.GUiを使用して、まとまりを作成したい場合、「gui.addFolder」を使用する const colorGUI = gui.addFolder('Cube Color'); colorGUI.add(datGUIObj.cubeColor, 'red', 0, 1).name('Red').step(0.01) colorGUI.add(datGUIObj.cubeColor, 'green', 0, 1).name('Green').step(0.01) colorGUI.add(datGUIObj.cubeColor, 'blue', 0, 1).name('Blue').step(0.01) colorGUI.open() // デフォルトで開いておきたい場合 const animate = function () { requestAnimationFrame( animate ); cube.material.color.r = datGUIObj.cubeColor.red; cube.material.color.g = datGUIObj.cubeColor.green; cube.material.color.b = datGUIObj.cubeColor.blue; renderer.render( scene, camera ); };
three.jsで色の変更を行いたい場合、 cube.material.color.r
などで色の情報を取得することができる。
背景色追加・変更
// ここで背景の初期値の設定を行う(設定を行わないと色のオブジェクトを取得することができない) scene.background = new THREE.Color( 0x000000 ); const datGUIObj = { backColor: { red: 0, green: 0, blue: 0 } }; const backGUI = gui.addFolder('Back Color'); backGUI.add(datGUIObj.backColor, 'red', 0, 1).name('Red').step(0.01) backGUI.add(datGUIObj.backColor, 'green', 0, 1).name('Green').step(0.01) backGUI.add(datGUIObj.backColor, 'blue', 0, 1).name('Blue').step(0.01) const animate = function () { requestAnimationFrame( animate ); const backGUI = gui.addFolder('Back Color'); backGUI.add(datGUIObj.backColor, 'red', 0, 1).name('Red').step(0.01) backGUI.add(datGUIObj.backColor, 'green', 0, 1).name('Green').step(0.01) backGUI.add(datGUIObj.backColor, 'blue', 0, 1).name('Blue').step(0.01) renderer.render( scene, camera ); };
詰まった場所
アニメーションフレームワーク内でないとdat.GUI上で変更を行なっても反映されない
three.jsの場合、requestAnimationFrame
でループする関数の中に入れないと反応しません。
- NG例
let changeValue // ここの値をdatGUIで変えたい場合 const Obj = { hoge: 'fuga' } gui.add(Obj, 'hoge'); changeValue = Obj.hoge
- OK例
let changeValue // ここの値をdatGUIで変えたい場合 const Obj = { hoge: 'fuga' } gui.add(Obj, 'hoge'); // gui.addは右上に表示を行うもののため、animationフレームワークの外に出す。 const animate = function () { requestAnimationFrame( animate ); changeValue = Obj.hoge };