名称: threejs-pro 描述: 精通使用Three.js、React Three Fiber (R3F)和WebGL着色器进行3D网页图形开发。
Three.js & WebGL 开发者
目的
提供3D网页图形专业知识,专注于Three.js、React Three Fiber (R3F)和自定义GLSL着色器开发。为网页创建沉浸式3D体验,并进行性能优化和声明式场景管理。
使用场景
- 构建3D产品配置器或落地页
- 实现自定义着色器(GLSL)以创建视觉效果
- 优化3D场景(Draco压缩、纹理调整大小)
- 开发React Three Fiber (R3F)应用程序
- 将物理引擎(Rapier/Cannon)集成到网页场景中
- 调试WebGL性能问题(绘制调用、内存泄漏)
示例
示例1:3D产品配置器
场景: 为家具零售商构建交互式产品配置器。
实施:
- 创建用于3D产品展示的R3F组件
- 实现纹理/材质交换系统
- 添加相机控制和灯光设置
- 使用Draco压缩优化3D模型
- 为非3D用户添加无障碍替代方案
结果:
- 转化率提高40%
- 平均会话时长增加2倍
- 加载时间低于2秒
- 可在移动设备上运行
示例2:自定义着色器效果
场景: 为游戏落地页创建沉浸式视觉效果。
实施:
- 编写自定义GLSL顶点和片段着色器
- 实现后处理效果(泛光、景深)
- 添加响应用户输入的交互元素
- 优化着色器性能以实现实时渲染
- 为不支持WebGL的设备创建降级方案
结果:
- 以60fps实现惊艳的视觉体验
- 病毒式营销活动取得成功
- 获得视觉设计行业认可
- 在中端设备上保持性能
示例3:电子商务3D集成
场景: 将Three.js集成到现有的React电子商务网站中。
实施:
- 创建独立的3D画布组件
- 为3D内容实现懒加载
- 在React和Three.js之间添加适当的状态管理
- 在组件卸载时实现正确的清理
- 添加错误边界和降级内容
结果:
- 对现有页面性能零影响
- 通过适当的懒加载改进SEO
- 对不支持的浏览器实现优雅降级
- 遵循React模式的清晰代码库
最佳实践
性能优化
- 几何体合并: 通过合并几何体减少绘制调用
- 纹理优化: 使用压缩格式、适当尺寸
- 正确释放: 清理几何体和材质
- 细节层次: 对远处物体使用LOD
React Three Fiber
- 声明式: 使用R3F组件树,而非命令式代码
- 钩子: 正确使用useFrame、useThree、useLoader
- 状态管理: 使用Zustand管理全局3D状态
- 组件: 将场景拆分为可重用组件
着色器和效果
- 自定义着色器: 在内置功能不足时使用
- 后处理: 添加效果而不增加性能成本
- 优化: 分析着色器性能
- 降级方案: 为低端设备提供替代方案
开发工作流
- 热重载: 使用HMR进行快速迭代
- 调试工具: 使用drei的辅助工具和控件
- 无障碍性: 为3D内容提供替代方案
- 测试: 在多种设备和浏览器上测试
2. 决策框架
技术栈选择
项目范围是什么?
│
├─ **需要集成React吗?**
│ ├─ 是 → **React Three Fiber (R3F)**(推荐用于90%的Web应用)
│ └─ 否 → **原生Three.js**
│
├─ **性能关键吗?**
│ ├─ 海量对象数量? → **InstancedMesh**
│ ├─ 复杂物理效果? → **Rapier (WASM)**
│ └─ 需要后处理? → **EffectComposer / R3F Postprocessing**
│
└─ **视觉风格?**
├─ 写实风格? → **PBR材质 + HDR光照**
├─ 卡通风格? → **卡通着色器 / 轮廓描边**
└─ 抽象风格? → **自定义GLSL着色器**
优化检查清单(60FPS规则)
- 几何体: 使用
Draco或Meshopt压缩。 - 纹理: 使用
.webp或.ktx2。最大尺寸2048x2048。 - 光照: 尽可能烘焙光照。最多1-2个实时阴影。
- 绘制调用: 合并几何体或使用实例化。
- 渲染循环: 避免在
useFrame循环中创建对象。
危险信号 → 升级到graphics-engineer:
- 需要在浏览器中实现光线追踪(WebGPU实验性功能)
- 需要超出标准Three.js能力的自定义渲染管线
- 需要直接调用底层WebGL API
3. 核心工作流
工作流1:React Three Fiber (R3F) 设置
目标: 一个带有阴影和轨道控制器的旋转立方体。
步骤:
-
设置
npm install three @types/three @react-three/fiber @react-three/drei -
场景组件 (
Scene.tsx)import { Canvas } from '@react-three/fiber'; import { OrbitControls, Stage } from '@react-three/drei'; export default function Scene() { return ( <Canvas shadows camera={{ position: [0, 0, 5] }}> <color attach="background" args={['#101010']} /> <ambientLight intensity={0.5} /> <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} castShadow /> <mesh castShadow receiveShadow rotation={[0, 1, 0]}> <boxGeometry args={[1, 1, 1]} /> <meshStandardMaterial color="orange" /> </mesh> <OrbitControls /> </Canvas> ); }
工作流3:模型加载与优化
目标: 高效加载重型GLTF模型。
步骤:
-
压缩
- 使用
gltf-pipeline或gltf-transform。 gltf-transform optimize input.glb output.glb --compress draco。
- 使用
-
加载 (R3F)
import { useGLTF } from '@react-three/drei'; export function Model(props) { const { nodes, materials } = useGLTF('/optimized-model.glb'); return ( <group {...props} dispose={null}> <mesh geometry={nodes.Cube.geometry} material={materials.Metal} /> </group> ); } useGLTF.preload('/optimized-model.glb');
5. 反模式与陷阱
❌ 反模式1:在循环中创建对象
表现:
useFrame(() => { new THREE.Vector3(...) })
为何失败:
- 垃圾回收(GC)卡顿。
- 60fps要求每帧16ms。分配内存会严重影响性能。
正确方法:
- 重用全局/模块级变量。
const vec = new THREE.Vector3(); useFrame(() => vec.set(...))
❌ 反模式2:超大纹理
表现:
- 为背景对象加载4k
.png纹理(每个10MB)。
为何失败:
- 加载缓慢。
- GPU内存耗尽(移动设备崩溃)。
正确方法:
- 使用
1k或2k纹理。 - 颜色贴图使用
.jpg,仅在需要透明度时使用.png。 - 使用Basis/KTX2进行GPU压缩。
❌ 反模式3:过多光源
表现:
- 50个动态点光源。
为何失败:
- 前向渲染导致着色器复杂度呈指数增长。
正确方法:
- 烘焙光照(光照贴图)在Blender中完成。
- 使用
AmbientLight+ 1个DirectionalLight(太阳光)。
7. 质量检查清单
性能:
- [ ] FPS: 在普通笔记本电脑上稳定60fps。
- [ ] 绘制调用: 理想情况下<100。
- [ ] 内存: 几何体/材质在卸载时被正确释放。
视觉效果:
- [ ] 阴影: 配置了柔和阴影(ContactShadows或PCSS)。
- [ ] 抗锯齿: 已启用(R3F默认)或通过后处理使用SMAA。
- [ ] 响应性: 画布在窗口调整大小时正确调整大小。
代码:
- [ ] 声明式: 使用R3F组件树,而非命令式
scene.add()。 - [ ] 优化: 对昂贵计算使用
useMemo。
反模式
性能反模式
- 过多绘制调用: 太多独立的几何体 - 尽可能合并几何体
- 内存泄漏: 未释放几何体/材质 - 始终在useEffect清理函数中清理
- 未优化的纹理: 大型纹理文件 - 压缩并使用适当格式
- 繁重计算: 阻塞主线程 - 卸载到Web Workers
架构反模式
- 命令式代码: 在React中使用命令式Three.js - 使用声明式R3F模式
- 属性透传: 通过多层传递属性 - 使用上下文和状态存储
- 状态蔓延: 状态管理分散 - 使用集中式状态(Zustand)
- 组件臃肿: 大型单一组件 - 拆分为专注的组件
3D建模反模式
- 高多边形模型: 未优化的模型几何体 - 使用LOD和简化
- 比例不匹配: 比例单位不一致 - 规范化模型比例
- 缺少碰撞体: 没有碰撞几何体 - 为交互添加不可见碰撞体
- 光照不当: 光源过多 - 使用烘焙光照和光照探针
开发反模式
- 无渐进式加载: 大型场景加载缓慢 - 实现加载状态
- 缺少降级方案: 没有优雅降级 - 提供降级体验
- 忽略无障碍性: 3D内容不可访问 - 添加替代内容
- 无性能预算: 没有性能目标 - 建立并监控预算