Three.js合并Geometry后如何保留各部分的独立材质?
解决方法
你当前的问题是合并几何体后仅传入了单一材质,Three.js 支持通过*材质分组(Material Groups)*为合并后的 BufferGeometry 不同部分分配独立材质,修改方案如下:
核心逻辑
合并几何体时记录每个子几何体的顶点起始位置与数量,为合并后的 BufferGeometry 添加对应分组,最后实例化 Mesh 时传入材质数组而非单一材质即可。
适配你的代码的修改版本
const globalMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); const texture = THREE.ImageUtils.loadTexture( "http://127.0.0.1:8080/pin_png/img_gps_dasloop_online.png" ); texture.minFilter = THREE.LinearFilter; const workerMaterial = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide, }); const planeGeometry = new THREE.PlaneGeometry(1, 1); const textGeometry = new THREE.TextGeometry(`Id : ${dbId}`, { font: "monaco", size: 1, height: 0, curveSegments: 3, }); textGeometry.computeBoundingBox(); const workerIdMesh = new THREE.Mesh(textGeometry, globalMaterial); const workerMesh = new THREE.Mesh(planeGeometry, workerMaterial); // 记录两个几何体的顶点数量,用于后续分组 const planeVertexCount = planeGeometry.attributes.position.count; const textVertexCount = textGeometry.attributes.position.count; let offset = 0; // Merging const modelGeometry = new THREE.Geometry(); modelGeometry.merge(workerMesh.geometry, workerMesh.matrix); modelGeometry.merge(workerIdMesh.geometry, workerIdMesh.matrix); modelGeometry.computeVertexNormals(); const workerBufferGeometry = new THREE.BufferGeometry().fromGeometry( modelGeometry ); // 添加材质分组:参数分别为 起始顶点偏移、顶点数量、对应材质索引 workerBufferGeometry.clearGroups(); workerBufferGeometry.addGroup(offset, planeVertexCount, 0); // 0对应材质数组第0位workerMaterial offset += planeVertexCount; workerBufferGeometry.addGroup(offset, textVertexCount, 1); // 1对应材质数组第1位globalMaterial // 传入材质数组,顺序和分组的索引对应 this.humanModel = new THREE.Mesh(workerBufferGeometry, [workerMaterial, globalMaterial]);
注意事项
- 如果你使用的是 Three.js r125+ 版本,
Geometry已被官方弃用,建议直接使用BufferGeometry的merge方法合并几何体,分组逻辑和上述一致 - 如果子几何体包含索引,分组参数需要换成索引起始位置和索引数量,而非顶点数量
内容的提问来源于stack exchange,提问作者surya kumara
相关产品推荐
相关产品推荐

