Appearance
调试工具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);
}
// ......
拖动右上角的滑杆,可以修改对应的参数。
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 还支持更多高级功能:
- 布尔值控制:
typescript
// 控制显示隐藏
gui.add(mesh, "visible").name("显示/隐藏");
- 下拉选择:
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();
});
- 功能按钮:
typescript
gui.add({
reset: () => {
/* 重置逻辑 */
},
},
"reset"
)
.name("重置");
其他更多用法,可以参考API文档。