You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何使用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'); 

当前效果截图

datGUI Color Picker


解决方案

问题出在你只是添加了颜色选择器,但没有监听颜色变化并同步到立方体材质上,而且还重复创建了dat.GUI实例(原代码里已经有datGUI了),咱们可以把颜色控制整合到同一个GUI实例里,步骤如下:

  1. 在原有的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]; 
} 
  1. 在已有的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(); // 默认打开文件夹,方便操作
  1. 后续如果要给多个几何体加颜色控制,只需要在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

火山引擎 最新活动