如何使用dat.GUI修改Three.js几何体颜色?
问题:dat.GUI颜色选择器无法绑定立方体颜色
我用Three.js实现了一个带旋转控制的简单立方体渲染效果,已经通过dat.GUI完成了旋转参数的控制。现在想添加颜色修改功能,后续还要给更复杂的几何体实现多元素颜色修改,但是我添加了颜色选择GUI后,没法把它和立方体的颜色绑定起来,求帮忙解决!
原立方体渲染代码
$(function(){ var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, .1, 500); var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(0xdddddd); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; renderer.shadowMapSoft = true; var axis = new THREE.AxisHelper(10); scene.add (axis); var grid = new THREE.GridHelper(50, 5); var color = new THREE.Color("rgb(255,0,0)"); grid.setColors(color, 0x000000); scene.add(grid); var cubeGeometry = new THREE.BoxGeometry(5, 5, 5); var cubeMaterial = new THREE.MeshLambertMaterial({color:0x80ff}); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); var planeGeometry = new THREE.PlaneGeometry(30,30,30); var planeMaterial = new THREE.MeshLambertMaterial({color:0xffffff}); var plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -.5*Math.PI; plane.receiveShadow = true; scene.add(plane); cube.position.x += 0.001; cube.position.y = 2.5; cube.position.z = 2.5; scene.add(cube); var spotLight = new THREE.SpotLight(0xffffff); spotLight.castShadow = true; spotLight.position.set (15,30,50); scene.add(spotLight); camera.position.x = 40; camera.position.y = 40; camera.position.z = 40; camera.lookAt(scene.position); var guiControls = new function(){ this.rotationX = 0.001; this.rotationY = 0.001; this.rotationZ = 0.001; } var datGUI = new dat.GUI(); datGUI .add(guiControls, 'rotationX', -30*Math.PI/180, 30*Math.PI/180); datGUI .add(guiControls, 'rotationY', -30*Math.PI/180, 30*Math.PI/180); datGUI .add(guiControls, 'rotationZ', -30*Math.PI/180, 30*Math.PI/180); render(); function render() { cube.rotation.x = guiControls.rotationX; cube.rotation.y = guiControls.rotationY; cube.rotation.z = guiControls.rotationZ; requestAnimationFrame(render); renderer.render(scene,camera); } $("#webGL-container").append(renderer.domElement); renderer.render(scene,camera); });
我添加的颜色选择代码
var gui = new dat.GUI(); var folder = gui.addFolder('folder'); var params = {}; params.color = [255, 0, 255]; folder.addColor(params, 'color');
当前效果截图

解决方案
问题出在你只是添加了颜色选择器,但没有监听颜色变化并同步到立方体材质上,而且还重复创建了dat.GUI实例(原代码里已经有datGUI了),咱们可以把颜色控制整合到同一个GUI实例里,步骤如下:
- 在原有的
guiControls对象里添加颜色属性,用RGB数组对应立方体初始颜色(0x80ff转成RGB是[128, 255, 255]):
var guiControls = new function(){ this.rotationX = 0.001; this.rotationY = 0.001; this.rotationZ = 0.001; // 添加立方体颜色属性 this.cubeColor = [128, 255, 255]; }
- 在已有的
datGUI上添加颜色选择器,并通过onChange回调同步颜色到立方体材质:
// 创建颜色控制文件夹,归类相关控件 var colorFolder = datGUI.addFolder('颜色控制'); colorFolder.addColor(guiControls, 'cubeColor') .name('立方体颜色') .onChange(function(newColor) { // 将RGB数组转成Three.js支持的0-1范围值,同步到材质 cube.material.color.setRGB( newColor[0]/255, newColor[1]/255, newColor[2]/255 ); }); colorFolder.open(); // 默认打开文件夹,方便操作
- 后续如果要给多个几何体加颜色控制,只需要在
guiControls里添加对应颜色属性,重复上述步骤,把回调里的cube.material换成对应几何体的材质即可。
修改后GUI部分的完整代码如下:
var guiControls = new function(){ this.rotationX = 0.001; this.rotationY = 0.001; this.rotationZ = 0.001; this.cubeColor = [128, 255, 255]; } var datGUI = new dat.GUI(); // 旋转控制项 datGUI.add(guiControls, 'rotationX', -30*Math.PI/180, 30*Math.PI/180); datGUI.add(guiControls, 'rotationY', -30*Math.PI/180, 30*Math.PI/180); datGUI.add(guiControls, 'rotationZ', -30*Math.PI/180, 30*Math.PI/180); // 颜色控制项 var colorFolder = datGUI.addFolder('颜色控制'); colorFolder.addColor(guiControls, 'cubeColor').name('立方体颜色').onChange(function(newColor) { cube.material.color.setRGB(newColor[0]/255, newColor[1]/255, newColor[2]/255); }); colorFolder.open();
这样调整后,你在dat.GUI里选择颜色时,立方体的颜色就会实时同步更新啦!
内容的提问来源于stack exchange,提问作者fonsi




