Skip to content

调试工具dat.gui

书接上回,在上一节中我们已经成功创建了一个基础场景及一个旋转的立方体。在解决如何让场景有立体感的问题之前,还需要掌握调试工具dat.gui的使用,这样更有利于不断的调试各种参数。

在实际开发中,经常需要调整场景中物体的各种参数,比如位置、大小、颜色等。如果每次修改参数都需要改动代码,然后重新运行,这样会非常繁琐,并且不好把握调试值。dat.gui 就是一个很好的调试工具,它可以在页面上创建一个控制面板,让我们能够实时调整这些参数。

安装依赖

首先需要安装 dat.gui 依赖:

bash
npm install dat.gui

如果是 TypeScript 开发,还需要安装类型声明:

bash
npm install @types/dat.gui

基本使用

让我们修改上一节的main.ts,添加 dat.gui 控制面板的代码:

typescript
import * as dat from "dat.gui";

// ......

// 几何体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

// 创建 GUI 对象
const gui = new dat.GUI();

// 创建控制面板
const cubeFolder = gui.addFolder("立方体");

// 添加位置控制
cubeFolder.add(mesh.position, "x", -5, 5).name("X 位置");
cubeFolder.add(mesh.position, "y", -5, 5).name("Y 位置");
cubeFolder.add(mesh.position, "z", -5, 5).name("Z 位置");

// 添加缩放控制
cubeFolder.add(mesh.scale, "x", 0.1, 5).name("X 缩放");
cubeFolder.add(mesh.scale, "y", 0.1, 5).name("Y 缩放");
cubeFolder.add(mesh.scale, "z", 0.1, 5).name("Z 缩放");

// 添加角度和颜色控制参数
const params = {
  rotationX: 0,
  rotationY: 0,
  rotationZ: 0,
  color: "#00ff00",
};

// 添加旋转控制(使用角度)
cubeFolder
  .add(params, "rotationX", 0, 180)
  .name("X 旋转(度)")
  .onChange(value => {
    mesh.rotation.x = THREE.MathUtils.degToRad(value);
  });
cubeFolder
  .add(params, "rotationY", 0, 180)
  .name("Y 旋转(度)")
  .onChange(value => {
    mesh.rotation.y = THREE.MathUtils.degToRad(value);
  });
cubeFolder
  .add(params, "rotationZ", 0, 180)
  .name("Z 旋转(度)")
  .onChange(value => {
    mesh.rotation.z = THREE.MathUtils.degToRad(value);
  });

// 添加颜色控制
cubeFolder.addColor(params, "color").name("颜色").onChange(value => {
	material.color.set(value);
});

// 默认展开文件夹
cubeFolder.open();

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  // 为了方便操作,这里注释掉更新旋转的代码
  // mesh.rotation.x += 0.01;
  // mesh.rotation.y += 0.01;
  controls.update();
  renderer.render(scene, camera);
}

// ......

拖动右上角的滑杆,可以修改对应的参数。

image-20250615115410750

position和scale的设置可以直接将mesh的position和scale对象传入。但是rotation和color的设置却不能直接传入mesh的rotation和color。

这是因为meshi.rotation 虽然也是 Euler 类型的对象,但它存储的是弧度值(radians)。如果界面上是通过角度值来控制,就需要用THREE.MathUtils.degToRad将角度值转行为弧度值再通过onChange回调赋予mesh。每次界面上值的改动都会调用onChange中的方法。

同样,这里的颜色值需要转换,是因为 dat.GUI 控件返回的颜色值是字符串格式(如 "#00ff00"),而 three.js 的材质(Material)颜色属性(material.color)是 Color 类型。 color.set 方法可以接受字符串(如 "#00ff00")、数字(如 0x00ff00)或 Color 实例,并自动转换为 Color 对象。

更多用法

dat.gui 还支持更多高级功能:

  1. 布尔值控制
typescript
// 控制显示隐藏
gui.add(mesh, "visible").name("显示/隐藏");
  1. 下拉选择
typescript
// 换材质
const materials = {
    basic: new THREE.MeshBasicMaterial({ color: "#00ff00" }),
    phong: new THREE.MeshPhongMaterial({ color: "#00ff00" }),
    standard: new THREE.MeshStandardMaterial({ color: "#00ff00" })
};
const params = {
    material: 'basic'
}
gui.add(params, "material", ["basic", "phong", "standard"])
.name("材质类型")
.onChange(value => {
    // 替换 mesh 的材质
    const oldMaterial = mesh.material;
    currentMaterial = materials[value];
    mesh.material = currentMaterial;
    // 释放旧材质资源
    oldMaterial.dispose();
});
  1. 功能按钮
typescript
gui.add({
        reset: () => {
            /* 重置逻辑 */
        },
    },
    "reset"
  )
  .name("重置");

其他更多用法,可以参考API文档