在Three.js中,使用多种材料合并几何体

6
我想使用两个网格来创建一棵松树,一个用于树干,另一个用于灌木丛。这是我所做的:
var pine_geometry = new THREE.Geometry();

var pine_texture_1 = THREE.ImageUtils.loadTexture('./res/textures/4.jpg');
var pine_geometry_1 = new THREE.CylinderGeometry(25, 25, 50, 6);
var pine_material_1 = new THREE.MeshBasicMaterial({
  map : pine_texture_1
});

var pine_1 = new THREE.Mesh(pine_geometry_1);
pine_1.position.x = x;
pine_1.position.y = y + 25;
pine_1.position.z = z;

pine_1.updateMatrix();
pine_geometry.merge(pine_1.geometry, pine_1.matrix);

var pine_texture_2 = THREE.ImageUtils.loadTexture('./res/textures/5.jpg');
var pine_geometry_2 = new THREE.CylinderGeometry(0, 70, 250, 8);
var pine_material_2 = new THREE.MeshBasicMaterial({
  map : pine_texture_2
});

var pine_2 = new THREE.Mesh(pine_geometry_2);
pine_2.position.x = x;
pine_2.position.y = y + 175;
pine_2.position.z = z;

pine_2.updateMatrix();
pine_geometry.merge(pine_2.geometry, pine_2.matrix);

var pine = new THREE.Mesh(pine_geometry, new THREE.MeshFaceMaterial([pine_material_1, pine_material_2]));
pine.geometry.computeFaceNormals();
pine.geometry.computeVertexNormals();

Game.scene.add(pine);

松树的位置摆放得很好,但整个合并后的形状只使用了一个材质而不是两个(整个形状被第一个材料覆盖),我希望在合并时每个网格都有其各自的材质。
我做错了什么?有什么想法吗?

MeshFaceMaterial已被移除,请使用Array代替。 - sohnryang
2个回答

9
经过长时间的研究,我发现我在 Geometry 对象的 "merge" 方法中缺少了一个额外的参数,最后一个参数是网格必须从材料数组中拥有的材料索引,例如:0-> 'materials' 数组中的第一个材料...以此类推。
因此,我的最终代码如下:
pine_geometry.merge(pine_1.geometry, pine_1.matrix, 0);

var pine_texture_2 = THREE.ImageUtils.loadTexture('./res/textures/5.jpg');
var pine_geometry_2 = new THREE.CylinderGeometry(0, 70, 250, 8);
var pine_material_2 = new THREE.MeshBasicMaterial({
  map : pine_texture_2
});

var pine_2 = new THREE.Mesh(pine_geometry_2);
pine_2.position.x = x;
pine_2.position.y = y + 175;
pine_2.position.z = z;

pine_2.updateMatrix();
pine_geometry.merge(pine_2.geometry, pine_2.matrix, 1);

(请注意我为每个合并添加的最后数字。)
然而,我想澄清,这种做法仅适用于处理来自同一类型的各种几何体,例如在这种情况下,我们正在合并两个CylinderGeometry,但是如果我们想要合并一个圆柱体和一个立方体,并且添加MeshFaceMaterial,则不会被正确识别,控制台将抛出“无法从未定义的地方读取属性映射/属性”,尽管如此,我们仍然可以合并两个几何体,但不能提供多种材料(这是我犯的可怕错误)。
希望对任何人有所帮助。

我正在尝试做这件事,但是出现了错误three.js:20820 Uncaught TypeError: Cannot read property 'visible' of undefined。有什么解决办法吗? - arpo

3

这里是一个通用的函数,用于合并带有材质的网格。您还可以指定是否要将其返回为缓冲几何体。

function _mergeMeshes(meshes, toBufferGeometry) {

    var finalGeometry,
        materials = [],
        mergedGeometry = new THREE.Geometry(),
        mergeMaterial,
        mergedMesh;

    meshes.forEach(function(mesh, index) {
        mesh.updateMatrix();
        mesh.geometry.faces.forEach(function(face) {face.materialIndex = 0;});
        mergedGeometry.merge(mesh.geometry, mesh.matrix, index);
        materials.push(mesh.material);
    });

    mergedGeometry.groupsNeedUpdate = true;
    mergeMaterial = new THREE.MeshFaceMaterial(materials);

    if (toBufferGeometry) {
        finalGeometry = new THREE.BufferGeometry().fromGeometry(mergedGeometry);
    } else {
        finalGeometry = mergedGeometry;
    }

    mergedMesh = new THREE.Mesh(finalGeometry, mergeMaterial);
    mergedMesh.geometry.computeFaceNormals();
    mergedMesh.geometry.computeVertexNormals();

    return mergedMesh;

}

var mergedMesh = _mergeMeshes([trunkMesh, treeTopMesh], true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接