1. 3D 格式对比
| 格式 | 加载器 | 特点 | 推荐场景 |
|---|---|---|---|
| GLTF / GLB | GLTFLoader | Web 原生标准,含材质/动画/骨骼 | 首选,几乎所有场景 |
| OBJ | OBJLoader | 简单纯几何,无动画无材质标准 | 简单几何体导入 |
| FBX | FBXLoader | Autodesk 格式,含动画但体积大 | 来自 Maya/3ds Max 的资产 |
| STL | STLLoader | 3D 打印常用,纯几何无材质 | 工程/CAD 模型 |
2. GLTFLoader 加载 .gltf / .glb
GLTF(GL Transmission Format)是 Khronos 组织的 Web 3D 传输标准,被誉为"3D 界的 JPEG"。.gltf 是 JSON 文本格式,.glb 是二进制单文件格式(推荐,体积更小)。
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// ── Promise 封装(推荐)──
function loadModel(url) {
const loader = new GLTFLoader();
return new Promise((resolve, reject) => {
loader.load(
url,
(gltf) => resolve(gltf),
(progress) => {
const pct = (progress.loaded / progress.total * 100).toFixed(0);
console.log(`加载进度: ${pct}%`);
},
(err) => reject(err)
);
});
}
// 使用
const gltf = await loadModel('/models/helmet.glb');
// gltf 对象包含:
// gltf.scene — 根 Group(包含所有 Mesh)
// gltf.scenes — 所有场景
// gltf.animations — AnimationClip 数组
// gltf.cameras — 相机数组
scene.add(gltf.scene);
// 调整位置/旋转/缩放
gltf.scene.position.set(0, 0, 0);
gltf.scene.scale.setScalar(0.01); // 模型单位可能是 cm,缩放到 m
// 遍历模型中的所有 Mesh
gltf.scene.traverse((child) => {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
// 修改材质
child.material.envMapIntensity = 1.5;
}
});
3. Draco 压缩解码器
Draco 是 Google 开发的 3D 网格压缩算法,可将 GLTF 模型体积压缩 80-90%。压缩后的模型加载时需要 Draco 解码器:
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
// 1. 创建 DRACOLoader,指向解码器 WASM 文件路径
// 复制 node_modules/three/examples/jsm/libs/draco/ 到 public/draco/
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
dracoLoader.preload(); // 预加载解码器(可选,提前加载)
// 2. 将 DRACOLoader 注入 GLTFLoader
const gltfLoader = new GLTFLoader();
gltfLoader.setDRACOLoader(dracoLoader);
// 之后正常加载即可,压缩与非压缩模型都支持
const gltf = await new Promise((res, rej) =>
gltfLoader.load('/models/compressed.glb', res, undefined, rej)
);
4. OBJLoader 与 MTL 材质文件
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
// 先加载材质,再加载 OBJ
const mtlLoader = new MTLLoader();
const materials = await new Promise((res) =>
mtlLoader.load('/models/car.mtl', res)
);
materials.preload();
const objLoader = new OBJLoader();
objLoader.setMaterials(materials);
const object = await new Promise((res) =>
objLoader.load('/models/car.obj', res)
);
scene.add(object);
5. 模型优化:Instancing(实例化渲染)
当需要渲染大量相同几何体时(如草地、树林、建筑群),使用 InstancedMesh 一次 Draw Call 渲染所有实例:
// 一次 Draw Call 渲染 1000 棵树
const count = 1000;
const treeGeo = new THREE.ConeGeometry(0.3, 1, 8);
const treeMat = new THREE.MeshStandardMaterial({ color: 0x228822 });
const instancedMesh = new THREE.InstancedMesh(treeGeo, treeMat, count);
instancedMesh.castShadow = true;
const dummy = new THREE.Object3D();
const matrix = new THREE.Matrix4();
for (let i = 0; i < count; i++) {
// 随机位置
dummy.position.set(
(Math.random() - 0.5) * 100,
0,
(Math.random() - 0.5) * 100
);
// 随机旋转和缩放
dummy.rotation.y = Math.random() * Math.PI * 2;
dummy.scale.setScalar(0.5 + Math.random() * 1.5);
dummy.updateMatrix();
// 设置第 i 个实例的变换矩阵
instancedMesh.setMatrixAt(i, dummy.matrix);
}
instancedMesh.instanceMatrix.needsUpdate = true; // 通知 GPU 更新
scene.add(instancedMesh);
6. LOD(细节层次)
LOD 根据相机距离自动切换高/中/低精度模型,兼顾近景质量和远景性能:
const lod = new THREE.LOD();
// 为不同距离设置不同精度的模型
const highDetail = new THREE.Mesh(new THREE.SphereGeometry(1, 64, 32), mat);
const midDetail = new THREE.Mesh(new THREE.SphereGeometry(1, 16, 8), mat);
const lowDetail = new THREE.Mesh(new THREE.SphereGeometry(1, 8, 4), mat);
lod.addLevel(highDetail, 0); // 0~5m 内用高精度
lod.addLevel(midDetail, 5); // 5~15m 中精度
lod.addLevel(lowDetail, 15); // 15m 外低精度
scene.add(lod);
// ⚠️ LOD 需要在渲染循环中更新
function animate() {
requestAnimationFrame(animate);
lod.update(camera); // 根据相机距离自动切换 Level
renderer.render(scene, camera);
}
7. 免费 3D 资源推荐
- Sketchfab 最大的 3D 模型社区,大量免费/CC 授权模型,支持直接下载 GLB 格式。适合各种题材的高质量模型。
- Poly Pizza 免版权的低多边形风格 3D 模型库,全部 CC0 授权,可直接用于商业项目,非常适合游戏和卡通风格。
- glTF-Sample-Models Khronos 官方 glTF 示例模型库(github.com/KhronosGroup/glTF-Sample-Models),包含 BoomBox、Helmet 等测试标准模型。
- Mixamo Adobe 的免费角色动画库,提供数百个角色动画(idle/walk/run/attack),下载 FBX 格式后可转为 GLTF。
模型优化工具:
• gltf-transform(gltf-transform.donmccurdy.com)— 命令行工具,压缩、优化、转换 GLTF
• Three.js Editor(threejs.org/editor)— 在线预览和检查模型
• Blender + GLTF 导出— 免费 3D 建模软件,导出带压缩的 GLB
本章小结:Web 3D 首选 GLTF/GLB 格式 + GLTFLoader;生产环境加上 Draco 压缩减少体积;大量相同物体用 InstancedMesh;远景用 LOD 降低多边形数。这三个优化手段能让复杂场景性能提升数倍。