three.js merging geometry with ShaderMaterials-Collection of common programming errors

I have a project built on a tileset, which I currently map to CubeGeometries via a number of ShaderMaterials.

When the cubes are rendered, there is bleeding and flickering around the edges of the cubes. Also, it seems to be an awfully bad way to do it, performance-wise.

So I looked up THREE.GeometryUtils.merge that apparently merges my cubes to one geometry, vertices and all.

Is it possible to make the merged mesh keep the materials I used on each of the cubes? Is there a better way to accomplish what I’m trying to do?

Edit: This is an example of what is not working.

http://jsfiddle.net/CpQ77/3/

var shaderMat1 = new THREE.ShaderMaterial({
    fragmentShader: document.getElementById("red-fragment").innerText,
    vertexShader: document.getElementById("vertex").innerText
});
var shaderMat2 = new THREE.ShaderMaterial({
    fragmentShader: document.getElementById("blue-fragment").innerText,
    vertexShader: document.getElementById("vertex").innerText
});

var cube1 = new THREE.Mesh(new THREE.CubeGeometry(64, 64, 64), new THREE.MeshFaceMaterial([shaderMat1, shaderMat1, shaderMat1, shaderMat1, shaderMat1, shaderMat1]));
cube1.position.x = 0;
cube1.position.y = 300;

var cube2 = new THREE.Mesh(new THREE.CubeGeometry(64, 64, 64), new THREE.MeshFaceMaterial([shaderMat2, shaderMat2, shaderMat2, shaderMat2, shaderMat2, shaderMat2]));
cube2.position.x = 64;
cube2.position.y = 300;

var geo = new THREE.Geometry();
THREE.GeometryUtils.merge(geo, cube1);
THREE.GeometryUtils.merge(geo, cube2);

var mergedMesh = new THREE.Mesh(geo, new THREE.MeshFaceMaterial());

scene.add(mergedMesh);

It gives an error saying, “Uncaught TypeError: Cannot read property ‘map’ of undefined”, when trying to use the MeshFaceMaterial as used in a couple of places around the web.

I can’t figure out what I’m missing though.

Edit2: One workaround I found was to loop through all the faces of the new geometry, and applying a materialIndex to it before calling geometry.mergeVertices().

  1. Thanks for this post, the comments were helpful in finding a solution. Instead of supplying the materials array to the Geometry, you should supply it as the only argument to MeshFaceMaterial. Here’s an example in CoffeeScript: materials = [] for i in [0…6] texture = window[“texture_” + i] # This is a Texture that has already been loaded materials.push new THREE.MeshBasicMaterial( color : color map : texture ) size = 1 geometry = new THREE.CubeGeometry size, size, size cube = new THREE.Mesh geometry, new THREE.MeshFaceMaterial materials cube.position.x = x cube.position.y = y cube.position.z = z scene.add cube return cube