THREE.js克隆对象属性联动问题:如何实现属性独立的克隆?
解决Three.js克隆OBJ对象后顶点颜色同步变化的问题
你推测的没错——Three.js中Object3D.clone()默认是浅克隆:克隆后的对象会共享原始对象的几何体(BufferGeometry)和材质引用,多个克隆体共用同一个几何体实例时,修改其中一个的顶点属性(比如颜色)会直接影响所有关联对象。
要实现完全独立的克隆,关键是让每个克隆体拥有独立的几何体副本,有两种可行方式:
方案一:克隆后手动创建独立几何体
在克隆原始对象后,遍历克隆体的所有Mesh,为每个Mesh克隆几何体:
// 递归克隆对象层级 const clonedTunnel = tunnels[0].clone(true); // 遍历克隆体,为每个Mesh创建独立几何体 clonedTunnel.traverse(titem => { if (titem.isMesh) { // 克隆几何体,生成独立实例 titem.geometry = titem.geometry.clone(); } }); // 后续修改位置、颜色等操作只影响当前克隆体 tunnels.push(clonedTunnel);
方案二:提前处理原始对象的几何体
在OBJ加载完成后,先为原始对象的Mesh克隆几何体,确保后续克隆时能基于独立副本生成:
oload.load("objects/tunnel1.obj", function(data) { tunnels[0] = data; tunnels[0].traverse(function(titem) { if(titem.isMesh) { if(titem.name.toUpperCase().indexOf("INNER")>-1) { titem.material = new THREE.MeshBasicMaterial({map: wnewtex, vertexColors: true}); // 提前克隆几何体,让原始对象使用独立实例 titem.geometry = titem.geometry.clone(); } } }); });
之后再调用.clone(true)克隆对象时,每个克隆体的Mesh会继承这个独立几何体的引用,修改颜色时不会互相干扰。
修正代码中的变量错误
你的代码里存在一处变量名错误:item.geometry.attributes.position.count应该改为titem.geometry.attributes.position.count,否则会导致无法正确获取顶点数量。
修改后的完整示例片段(以leveldata=23为例)
else if(leveldata[x][y] == 23) { // 克隆对象并创建独立几何体 const clonedTunnel = tunnels[0].clone(true); clonedTunnel.traverse(titem => { if (titem.isMesh) { titem.geometry = titem.geometry.clone(); } }); // 设置位置和旋转 clonedTunnel.position.set(-x*2, newh, (height-y-1)*2); clonedTunnel.rotation.set(0, Math.PI/2, 0); // 修改顶点颜色 clonedTunnel.traverse(function(titem) { if(titem.isMesh) { if(titem.name.toUpperCase().indexOf("INNER")>-1) { const vertexCount = titem.geometry.attributes.position.count; titem.geometry.setAttribute("color", new THREE.BufferAttribute(new Float32Array(vertexCount*3), 3)); const colort = titem.geometry.attributes.color.array; for(let v2 = 0; v2 < vertexCount*3; v2+=3) { colort[v2] = 1; colort[v2+1] = 0; colort[v2+2] = 0; } titem.geometry.attributes.color.needsUpdate = true; } } }); tunnels.push(clonedTunnel); scene.add(clonedTunnel); }
内容的提问来源于stack exchange,提问作者Edward
相关产品推荐
相关产品推荐

