Hi, I have a scene in OBJ format where there is one mesh object duplicated several times, (same geometry, same materials, different positions).
For optimization, I would like to merge all the instances of this mesh as a single BufferGeometry.
If the mesh has a single material the result is correct, but with multiple materials I got incorrect result.
This is the geometry data of the mesh as imported from the obj file:
1. 0: Mesh
1. castShadow: false
2. children: []
3. drawMode: 0
4. frustumCulled: true
5. geometry: BufferGeometry
1. attributes: {position: Float32BufferAttribute, normal: Float32BufferAttribute, uv: Float32BufferAttribute}
2. boundingBox: null
3. boundingSphere: null
4. drawRange: {start: 0, count: Infinity}
5. groups: Array(2)
1. 0: {start: 0, count: 78, materialIndex: 0}
2. 1: {start: 78, count: 6, materialIndex: 1}
3. length: 2
4. __proto__: Array(0)
6. index: null
7. morphAttributes: {}
8. name: ""
9. type: "BufferGeometry"
10. userData: {}
11. uuid: "C9FFD8FA-15E3-424B-9C86-1AA3D0A638F5"
12. drawcalls: (...)
13. id: 15
14. offsets: (...)
15. __proto__: EventDispatcher
6. layers: Layers {mask: 1}
7. material: (2) [MeshPhongMaterial, MeshPhongMaterial]
8. matrix: Matrix4 {elements: Array(16)}
9. matrixAutoUpdate: true
10. matrixWorld: Matrix4 {elements: Array(16)}
11. matrixWorldNeedsUpdate: false
12. name: "FLOOR_1"
[...]
This is the code I have used for merging:
function sceneTraverse(obj, fn) {
fn(obj);
if (obj.children && obj.children.length) {
obj.children.forEach(o => {
sceneTraverse(o, fn);
});
}
}
let textureLoader = new T.TextureLoader()
let loader = new T.OBJLoader()
let material_1 = new T.MeshStandardMaterial({
name: "material_1",
color: 0xffffff,
map: textureLoader.load("assets/texture1.png"),
metalness: 1.0,
roughness: 0.4
})
let material_2 = new T.MeshStandardMaterial({
name: "material_2",
color: 0xffffff,
map: textureLoader.load("assets/texture2.png"),
metalness: 0,
roughness: 0.6
})
loader.load("assets/scene.obj", obj => {
console.log(obj)
let geometries = []
sceneTraverse(obj, o => {
if (o.type && o.type === "Mesh" && o.name && o.name === "FLOOR_1") {
geometries.push(o.geometry.clone())
}
})
let mergedGeometry = T.BufferGeometryUtils.mergeBufferGeometries(geometries, true)
let mergedMesh = new T.Mesh(mergedGeometry, [material_1, material_2])
scene.add(mergedMesh)
})
This is the correct result (without merging):
This is the result I got with merging:
Any idea how to fix that?