Three.js 中的调试助手 OrbitControls + GUI

刚开始学 Three.js 的时候,在想怎样能快速的调整正确对应的场景,而做 Three.js 的同学一定有一个共同的感受:

没有 OrbitControls,这 3D 世界根本没法转起来。
没有 GUI,这场景调参要累死。

今天我们就用一篇极其易懂的文章,帮你搞懂:

  • OrbitControls 是怎么实现"拖拽旋转缩放"的?
  • lil-gui(GUI)怎么用来实时调参?
  • 如何用它们让 Three.js 项目立刻"专业感+100%"?

OrbitControls:给摄像机加上"灵魂"

Three.js 的默认摄像机是"静止的",你必须自己写代码改变它的位置。

OrbitControls 允许相机围绕目标旋转

OrbitControls 就是帮助你"拖拽旋转、缩放、移动视角"的神器

js 复制代码
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

// 创建 OrbitControls 实例,第一个参数为 Camera 第二个为监听的对象元素
const controls = new OrbitControls(camera, renderer.domElement);

controls.enableDamping = true; // 启用阻尼效果(惯性效果)
controls.dampingFactor = 0.25; // 阻尼系数(惯性系数), 值越小越快, 越大越慢,相当于定义他的阻力大小
controls.enablePan = true; // 启用平移
controls.enableZoom = true; // 启用缩放
controls.autoRotate = false; // 启用自动旋转
controls.autoRotateSpeed = 2.0; // 自动旋转速度

function animate() {
  requestAnimationFrame(animate);
  controls.update(); // 更新轨道控制器, 这里也不要忘了哦
  renderer.render(scene, camera);
}

animate();

添加之后,移动技巧:

  • 环绕:左键鼠标 / 触摸:单指移动 (左键拖动:旋转场景)。
  • 缩放:中键鼠标,或鼠标滚轮 / 触摸:双指张开或捏合。
  • 平移:右键鼠标,或左键鼠标 + ctrl/meta/shift 键,或方向键 / 触摸:双指移动。

OrbitControls 的核心原理

OrbitControls 本质上是围绕一个"目标点 target"旋转摄像机。

更改相机的目标物体

js 复制代码
// 默认 围绕原点进行转动, 摄像机永远看向 target,并且绕它"公转"。
controls.target = new THREE.Vector3(0, 0, 0);

// 所以如果你想摄像机围绕某个物体旋转,只需要:
controls.target.copy(cube.position);

摄像机会立刻围着 cube 转。这个原理你知道之后会非常有用!(比如做模型预览某个文件、3D 配置器等)

lil-gui(GUI):实时调参

lil-gui 是交互式控制面板,其核心作用是为开发者和用户提供一个可视化的 "参数调节界面",无需手动编写 UI 代码,即可实时修改 Three.js 场景中的各种属性(如物体位置、材质颜色、光照强度等),极大提升开发效率和场景调试体验。

3D 场景最痛苦的事情是什么?

答:调整参数。尤其当你要调整灯光强度、材质 roughness、旋转角度......,每次都改代码 → 刷新页面 → 再改代码 → 再刷新......

效率痛苦指数:五颗星,所以 GUI 出现了

js 复制代码
// 引用
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";

// 使用 GUI
const gui = new GUI();

// 监听 cube.position 相关属性, 改变 cube.position.x 范围从 -5 到 5, 名称为 Cube X
gui.add(cube.position, "x", -5, 5).name("Cube X");
// 监听 cube.position 相关属性, 改变 cube.position.y 范围从 -5 到 5, 名称为 Cube Y
gui.add(cube.position, "y", -5, 5).name("Cube Y");
gui.add(cube.rotation, "y", 0, Math.PI * 2).name("Rotate Y");
// 监听 material.wireframe 属性, 名称为 Wireframe
gui.add(material, "wireframe").name("Wireframe");

效果图:

相关推荐
卡卡军18 小时前
vue3-sketch-ruler v3 升级详解:从 Vue 组件到跨框架标尺引擎
前端
还有多久拿退休金18 小时前
让看不见的 AI 动手画画——我意外造出了一个"绘图 Agent"
前端
陆枫Larry18 小时前
一次 iOS 橡皮筋弹性滚动的排查:从 absolute 到 fixed
前端
灏仟亿前端技术团队18 小时前
拆解亿级 SaaS 平台:Shopify 前端技术生态与架构避坑指南
前端
亲亲小宝宝鸭18 小时前
如何监听DOM尺寸的变化?element-resize-detector 和 resizeObserver
前端·javascript
胡志辉18 小时前
本地 AI 编码助手从 0 配起来:先选模型,再接 Ollama、VS Code、Claude Code 和 Codex
前端·后端
一颗小青松18 小时前
uniapp输入框fixed定位,导致页面顶起解决方案
前端·uni-app
孟陬18 小时前
从 Claude Code 187 种说“正在处理”的方式看一流公司的用户体验
前端·claude·bun
一楼的猫18 小时前
从工具链视角对比:番茄作家助手 vs 第三方写作辅助方案
java·服务器·开发语言·前端·学习·chatgpt·ai写作
掘金一周18 小时前
想换一辆电车,JYM有什么推荐 | 沸点周刊 5.21
前端·人工智能·后端