Three.js技术问题:如何将多个GLTF模型合并为单个对象?
解决Three.js合并几何体减少渲染调用的问题
我明白你想通过合并几何体来减少场景的draw call,而不是仅仅用THREE.Group做逻辑分组——确实,Group只是结构上的整理,不会减少渲染次数。你遇到的问题主要是BufferGeometryUtils的导入方式和使用方法在新版Three.js里已经更新了,老教程的写法确实过时了,我来一步步帮你修正:
1. 纠正导入方式
新版Three.js(r125+之后)的BufferGeometryUtils不再导出一个整体的构造函数,而是将各个工具函数单独导出。你需要直接导入mergeBufferGeometries函数,而且路径要注意是jsm/utils/下的文件:
import { mergeBufferGeometries } from '../jsm/utils/BufferGeometryUtils.js';
2. 注意传入的是BufferGeometry,不是Mesh
你之前把cube1、cube2(这些是THREE.Mesh对象)直接push到数组里,这是错误的——mergeBufferGeometries需要的是几何体对象(BufferGeometry),而不是整个网格。你应该取每个Mesh的geometry属性:
// 收集三个立方体的几何体 const geometries = [ cube1.geometry, cube2.geometry, cube3.geometry ];
3. 正确合并并创建新网格
mergeBufferGeometries返回的是合并后的BufferGeometry,你需要用它创建一个新的Mesh(还要确保三个立方体用的是相同的材质,否则合并后材质会混乱):
// 合并几何体,第二个参数可选,默认true表示合并顶点属性(如法线、UV等) const mergedGeometry = mergeBufferGeometries(geometries, true); // 创建新的网格,使用原来的材质(比如取cube1的材质) const mergedCube = new THREE.Mesh(mergedGeometry, cube1.material); // 添加到场景 scene.add(mergedCube);
额外注意事项
- 如果你的三个立方体材质不同,不能用这种合并方式,否则只能保留一种材质。这种情况下推荐使用
THREE.InstancedMesh,它可以共享同一个几何体和材质,同时让每个实例有独立的位置、旋转和缩放,同样能大幅减少draw call。 - 合并前如果几何体有修改(比如缩放、旋转),记得先调用
geometry.applyMatrix4()或者确保变换已经应用到几何体上,否则合并后的位置可能不符合预期。 - 如果合并时报错,检查每个几何体的顶点属性是否一致(比如是否都有法线、UV),如果不一致可以把第二个参数设为
false,但这样可能会丢失部分属性。
内容的提问来源于stack exchange,提问作者Vardan Betikyan
相关产品推荐
相关产品推荐

