React Three Fiber中多材质克隆Mesh的材质修改高亮问题
解决FBX克隆对象多材质高亮时的批量同步问题
问题原因
FBX加载生成的Mesh,其材质数组中的材质实例会被所有克隆体共享(Three.js默认克隆为浅拷贝)。当你直接修改mesh.material[i]的材质实例时,所有使用该材质的克隆Mesh都会同步变化,导致全部高亮。
解决方法
先为每个克隆体的Mesh创建独立的材质实例,再修改材质的颜色属性实现高亮,避免共享材质导致的批量同步问题。
修改后的代码
let mesh = LoadFBX(path).clone(); mesh.traverse((childMesh) => { if (childMesh.isMesh) { // 第一步:克隆材质,确保当前Mesh的材质独立于其他克隆体 if (Array.isArray(childMesh.material)) { // 对多材质数组中的每个材质单独克隆 childMesh.material = childMesh.material.map(mat => mat.clone()); } else { // 单材质直接克隆 childMesh.material = childMesh.material.clone(); } // 第二步:根据状态修改材质颜色 if (Array.isArray(childMesh.material)) { childMesh.material.forEach(mat => { mat.color.set(active ? 0xf000f4 : 0xffffff); }); } else { childMesh.material.color.set(active ? 0xf000f4 : 0xffffff); } } });
关键优化点
- 材质独立化:通过
mat.clone()为每个克隆Mesh生成专属的材质实例,彻底切断和其他克隆体的材质共享关系。 - 修改颜色而非替换材质:直接修改已有材质的
color属性,比创建新材质更高效,同时保留原材质的其他特性(如粗糙度、金属度、透明度等)。 - 简化逻辑:用
Array.isArray判断多材质,用forEach替代for循环,代码更简洁易读。
额外提示
如果原FBX材质有特殊属性(如纹理、法线贴图),直接修改颜色不会破坏这些属性,能保持模型原有质感的同时实现高亮效果。
内容的提问来源于stack exchange,提问作者tinytree
相关产品推荐
相关产品推荐

