Three.js专栏(二)、从零构建:环境配置与首个3D场景实战

📅 2026/7/15 20:40:05
Three.js专栏(二)、从零构建:环境配置与首个3D场景实战
1. 环境准备从零搭建Three.js开发环境第一次接触Three.js时最让人头疼的就是环境配置。我刚开始学习时花了大半天时间才把开发环境跑起来。现在回想起来其实只需要几个简单步骤就能搞定。1.1 安装Node.js和npmThree.js的开发离不开Node.js环境。如果你还没安装可以去Node.js官网下载LTS版本。安装完成后打开终端输入以下命令检查是否安装成功node -v npm -v我建议使用nvm来管理Node.js版本这样可以在不同项目间切换版本。特别是在团队协作时能避免在我机器上能跑的问题。1.2 创建项目目录找个你喜欢的位置新建一个项目文件夹。我习惯用VSCode开发所以直接右键在终端打开mkdir threejs-starter cd threejs-starter npm init -y这个命令会生成package.json文件记录项目依赖和配置。接下来我们要安装Three.js核心库。1.3 安装Three.js现在安装Three.js非常简单只需要一行命令npm install three --save安装完成后你会在node_modules文件夹下找到three模块。我建议同时安装几个常用辅助工具npm install dat.gui stats.js --save-devdat.gui可以创建可视化控制面板stats.js能显示性能指标对调试很有帮助。2. 开发服务器配置2.1 选择开发服务器Three.js项目需要运行在服务器环境下。我测试过几种方案live-server轻量级适合快速原型开发webpack-dev-server功能强大适合复杂项目Vite启动快热更新灵敏新手我推荐用live-server安装简单npm install -g live-server2.2 配置启动脚本在package.json中添加启动命令scripts: { start: live-server --port3000, dev: vite }这样只需运行npm start就能启动开发服务器。我习惯用3000端口避免和其他服务冲突。2.3 解决常见问题第一次运行时可能会遇到跨域问题。这是因为Three.js加载资源需要正确配置CORS。解决方法是在项目根目录创建server.jsconst express require(express) const app express() app.use(express.static(public)) app.listen(3000, () console.log(Server running on port 3000))然后通过node server.js启动比live-server更灵活。3. 创建第一个3D场景3.1 HTML基础结构新建index.html文件基本结构如下!DOCTYPE html html head meta charsetutf-8 titleMy First Three.js Scene/title style body { margin: 0; } canvas { display: block; } /style /head body script src./src/main.js typemodule/script /body /html注意script标签的typemodule这是现代JavaScript的模块化写法。3.2 核心三要素场景、相机、渲染器在src/main.js中我们先创建Three.js的三大核心对象import * as THREE from three // 1. 创建场景 const scene new THREE.Scene() scene.background new THREE.Color(0x222222) // 2. 创建相机75度视野匹配窗口宽高比 const camera new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ) camera.position.z 5 // 3. 创建渲染器 const renderer new THREE.WebGLRenderer({ antialias: true }) renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement)这里有几个关键点场景是所有物体的容器透视相机模拟人眼视角渲染器将3D场景绘制到2D屏幕上3.3 添加立方体网格现在场景还是空的我们加个立方体// 创建立方体几何体 const geometry new THREE.BoxGeometry(1, 1, 1) // 创建基础材质绿色 const material new THREE.MeshBasicMaterial({ color: 0x00ff00 }) // 创建网格对象 const cube new THREE.Mesh(geometry, material) // 添加到场景 scene.add(cube)Mesh是Three.js的核心概念它结合了几何体形状和材质外观。4. 实现动画循环4.1 基本动画原理3D动画的本质就是不断更新物体属性并重绘。Three.js使用requestAnimationFrame实现流畅动画function animate() { requestAnimationFrame(animate) // 旋转立方体 cube.rotation.x 0.01 cube.rotation.y 0.01 // 渲染场景 renderer.render(scene, camera) } animate()这个循环会以显示器刷新率通常60FPS运行保证动画流畅。4.2 处理窗口大小变化当浏览器窗口调整大小时我们需要更新相机和渲染器window.addEventListener(resize, () { camera.aspect window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) })如果不做这个处理画面会变形影响视觉效果。5. 增强场景效果5.1 添加光源之前的立方体看起来是平的因为没有光影。我们添加点光源const light new THREE.PointLight(0xffffff, 1, 100) light.position.set(5, 5, 5) scene.add(light) // 改用受光影响的材质 const material new THREE.MeshPhongMaterial({ color: 0x00ff00 })现在立方体有了明暗变化看起来更立体了。5.2 显示坐标轴辅助调试时显示坐标轴很有帮助const axesHelper new THREE.AxesHelper(5) scene.add(axesHelper)红色X轴绿色Y轴蓝色Z轴。5.3 添加轨道控制器让用户可以用鼠标旋转场景import { OrbitControls } from three/examples/jsm/controls/OrbitControls const controls new OrbitControls(camera, renderer.domElement) controls.enableDamping true记得在动画循环中更新控制器function animate() { requestAnimationFrame(animate) controls.update() renderer.render(scene, camera) }6. 完整代码与优化建议6.1 完整示例代码import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 初始化场景、相机、渲染器 const scene new THREE.Scene() scene.background new THREE.Color(0x222222) const camera new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ) camera.position.z 5 const renderer new THREE.WebGLRenderer({ antialias: true }) renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement) // 添加立方体 const geometry new THREE.BoxGeometry(1, 1, 1) const material new THREE.MeshPhongMaterial({ color: 0x00ff00 }) const cube new THREE.Mesh(geometry, material) scene.add(cube) // 添加光源 const light new THREE.PointLight(0xffffff, 1, 100) light.position.set(5, 5, 5) scene.add(light) // 辅助工具 const axesHelper new THREE.AxesHelper(5) scene.add(axesHelper) const controls new OrbitControls(camera, renderer.domElement) controls.enableDamping true // 处理窗口大小变化 window.addEventListener(resize, () { camera.aspect window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) }) // 动画循环 function animate() { requestAnimationFrame(animate) cube.rotation.x 0.01 cube.rotation.y 0.01 controls.update() renderer.render(scene, camera) } animate()6.2 性能优化建议重用几何体和材质相同物体使用相同实例合理使用灯光每个灯光都会增加计算量使用性能监控添加stats.js显示帧率按需渲染静态场景可以不用每帧渲染7. 调试技巧与常见问题7.1 实用调试方法场景导出用scene.toJSON()导出场景配置控制台调试直接访问THREE对象检查属性GUI调节用dat.GUI创建参数控制面板7.2 常见错误解决黑屏问题检查相机位置和物体位置材质不显示确认是否正确添加了光源性能卡顿减少多边形数量或使用LOD8. 项目结构与扩展8.1 推荐项目结构threejs-project/ ├── public/ # 静态资源 ├── src/ │ ├── assets/ # 模型纹理 │ ├── components/ # 可复用组件 │ ├── scenes/ # 场景配置 │ └── main.js # 入口文件 ├── package.json └── index.html8.2 学习资源推荐官方文档Three.js官网示例在线编辑器Three.js官方编辑器社区论坛Stack Overflow的Three.js标签