threejs基础教程:从零开始构建你的第一个3D旋转立方体
1. 为什么选择Three.js入门3D开发第一次接触3D开发时我被各种专业术语吓到了——顶点着色器、光线追踪、法线贴图...直到发现Three.js这个宝藏库。它就像给WebGL套了个友好外壳让普通前端开发者也能轻松创建3D效果。记得我最早用Three.js做的项目是个电商平台的商品展示页当那个3D模型在网页上旋转起来时团队里所有人都惊呼原来网页还能这样玩Three.js最大的优势在于隐藏了WebGL的复杂性。你不用理解图形学矩阵运算也能通过简单的API创建场景。比如要画个立方体传统WebGL可能需要上百行代码而Three.js只要三行const geometry new THREE.BoxGeometry() const material new THREE.MeshBasicMaterial({color: 0x00ff00}) const cube new THREE.Mesh(geometry, material)这个库特别适合以下场景网页中的3D产品展示比如汽车配置器数据可视化中的立体图表简单的网页游戏开发教育类交互演示我建议初学者从旋转立方体开始因为立方体包含3D开发所有核心概念几何体、材质、网格调试方便六个面颜色不同更容易观察旋转动画能立即验证3D坐标系理解是否正确2. 五分钟搭建开发环境新手常在这里卡壳其实Three.js对环境要求非常宽松。最近帮同事调试时发现现代浏览器基本都支持连手机浏览器都能运行。下面分享两种最常用的配置方式2.1 纯HTML方案最快上手创建空白HTML文件直接引入CDN版本的Three.js!DOCTYPE html html head meta charsetutf-8 title我的第一个3D立方体/title stylebody { margin: 0; }/style /head body script srchttps://cdn.jsdelivr.net/npm/three0.132.2/build/three.min.js/script script // 代码将写在这里 /script /body /html注意生产环境建议下载three.min.js到本地避免CDN不可用导致项目瘫痪2.2 工程化方案推荐如果用Vue/React等框架通过npm安装更规范npm install three # TypeScript项目额外安装类型声明 npm install types/three --save-dev实测发现工程化方案在以下场景更有优势需要代码提示和类型检查项目体积较大需要tree-shaking要配合其他3D相关库使用3. 构建3D场景的核心三要素第一次创建场景时我总记不住这三个对象的顺序。后来发现可以用拍电影来类比场景(Scene)- 相当于拍摄场地相机(Camera)- 导演的取景器渲染器(Renderer)- 负责最终成像的摄影机3.1 创建基础场景const scene new THREE.Scene() scene.background new THREE.Color(0xf0f0f0) // 设置浅灰色背景Scene就像个透明容器默认没有背景色。我习惯先设置背景色这样调试时更容易区分场景边界。3.2 配置透视相机相机类型中最常用的是PerspectiveCamera透视相机模拟人眼视角const camera new THREE.PerspectiveCamera( 75, // 视野角度(FOV) window.innerWidth / window.innerHeight, // 宽高比 0.1, // 近裁面(near) 1000 // 远裁面(far) ) camera.position.z 5 // 相机向后移动5个单位这四个参数新手最容易搞混FOV值越小视野越窄类似长焦镜头效果宽高比一定要用窗口实际宽高比否则图像会变形近/远裁面超出这个范围的物体不会被渲染3.3 初始化WebGL渲染器const renderer new THREE.WebGLRenderer({ antialias: true }) renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement) // 处理窗口大小变化 window.addEventListener(resize, () { camera.aspect window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) })这里有个实用技巧添加antialias: true参数可以消除模型边缘锯齿。记得要处理resize事件否则浏览器窗口变化会导致场景变形。4. 创建会旋转的彩色立方体4.1 几何体与材质立方体需要两个核心组件// 创建立方体几何体(长宽高各为1) const geometry new THREE.BoxGeometry(1, 1, 1) // 创建基础材质显示为绿色 const material new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: false // 是否显示线框 }) // 将两者组合成网格(Mesh) const cube new THREE.Mesh(geometry, material) scene.add(cube)常见踩坑点忘记将mesh添加到scene中材质颜色值要用十六进制格式0x开头相机位置太近导致立方体显示不全4.2 添加旋转动画动画原理是利用requestAnimationFrame实现循环渲染function animate() { requestAnimationFrame(animate) // 旋转立方体 cube.rotation.x 0.01 cube.rotation.y 0.01 renderer.render(scene, camera) } animate()想让旋转更平滑可以改用时间增量控制转速let clock new THREE.Clock() function animate() { const delta clock.getDelta() // 获取上一帧耗时 cube.rotation.x delta * Math.PI / 2 // 每秒转90度 cube.rotation.y delta * Math.PI / 2 renderer.render(scene, camera) requestAnimationFrame(animate) }4.3 进阶美化技巧想让立方体更生动试试这些修改// 使用标准材质并添加光照 const material new THREE.MeshStandardMaterial({ color: 0x00ff00, roughness: 0.4, metalness: 0.7 }) // 添加平行光 const light new THREE.DirectionalLight(0xffffff, 1) light.position.set(1, 1, 1) scene.add(light) // 添加环境光 scene.add(new THREE.AmbientLight(0x404040))5. 调试与性能优化5.1 实用调试技巧初学者常遇到这些问题立方体不显示检查相机位置和朝向画面卡顿降低渲染分辨率试试颜色异常确认材质类型与灯光匹配推荐安装Three.js官方调试工具import { OrbitControls } from three/examples/jsm/controls/OrbitControls const controls new OrbitControls(camera, renderer.domElement) controls.enableDamping true // 添加阻尼效果5.2 性能优化建议当场景变复杂时需要注意重用几何体和材质对静态物体使用matrixAutoUpdate false合理设置相机裁面距离使用dispose()方法释放资源// 性能对比示例 const lowResRenderer new THREE.WebGLRenderer({ powerPreference: low-power }) lowResRenderer.setSize(window.innerWidth/2, window.innerHeight/2, false)6. 完整代码与扩展学习最终完整代码如下!DOCTYPE html html head title3D旋转立方体/title stylebody { margin: 0; }/style /head body script srchttps://cdn.jsdelivr.net/npm/three0.132.2/build/three.min.js/script script // 初始化场景 const scene new THREE.Scene() scene.background new THREE.Color(0xf0f0f0) // 设置相机 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.MeshStandardMaterial({ color: 0x00ff00, roughness: 0.4 }) const cube new THREE.Mesh(geometry, material) scene.add(cube) // 添加光照 const light new THREE.DirectionalLight(0xffffff, 1) light.position.set(1, 1, 1) scene.add(light) scene.add(new THREE.AmbientLight(0x404040)) // 动画循环 function animate() { requestAnimationFrame(animate) cube.rotation.x 0.01 cube.rotation.y 0.01 renderer.render(scene, camera) } animate() // 响应式处理 window.addEventListener(resize, () { camera.aspect window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) }) /script /body /html掌握基础后可以继续探索加载复杂3D模型GLTFLoader实现阴影效果添加粒子系统使用着色器自定义材质记得第一次成功运行这个立方体时我盯着它转了整整五分钟。这种即时可见的成就感正是Three.js最吸引我的地方。建议你在完成基础版本后尝试修改参数观察变化——比如把BoxGeometry的宽度改为2或者给立方体六个面设置不同颜色这些实践能帮你快速建立3D空间感。