Search code examples
three.jstexture-mapping

Texture mapping from one Face4 to two Face3 on Three.js


I am playing with Three.js. I am working on a project that uses an old version of Three.js. I'm trying to replace the old library with the new one (r71). Everything is going well except the texture mapping.

In the old project we use the Face4 which is deprecated and have been removed in the newest version of Three.js. So I have created two Face3 instead of just one Face4. Now the question is: how can I make one texture to cover both Face3 as they were like a single Face4?

Old pseudo-code using Face4

numberOfFaces = 10;

function createMyGeometry(){
var geometry = new THREE.Geometry();
...

for (var i = 0; i < numberOfFaces; i++) {
    var face = new THREE.Face4(v1.index, v2.index, v3.index, v4.index, [v1.clone(), v2.clone(), v3.clone(), v4.clone()]);
    face.centroid.add(v1).add(v2).add(v3).add(v4).divideScalar(4);
    face.normal = face.centroid.clone().normalize();
    face.materialIndex = matIdx;
    geometry.faces.push(face);
    geometry.faceVertexUvs[0].push([uv1.clone(), uv2.clone(), uv3.clone(), uv4.clone()]);
}
...
return geometry;
}

for (var i = 0; i < numberOfFaces; i++) {
var texture = THREE.ImageUtils.loadTexture("MyImage"+ i + '.jpg');
var material  = new THREE.MeshBasicMaterial();  
material.map   = texture;
material.side  = THREE.FrontSide;
materials.push(material);
}
materials = new THREE.MeshFaceMaterial(materials);
myGeometry = new THREE.Mesh(createMyGeometry(), materials);
scene.add(myGeometry);

Pseudo-code using Face3

numberOfFaces = 10;

function createMyGeometry(){
var geometry = new THREE.Geometry();
...

for (var i = 0; i < numberOfFaces; i++) {
        var face1 = new THREE.Face3(v1.index, v2.index, v3.index, [v1.clone(), v2.clone(), v3.clone()]);
        var face2 = new THREE.Face3(v1.index, v3.index, v4.index, [v1.clone(), v3.clone(), v4.clone()]);
        face1.materialIndex = matIdx;
        face2.materialIndex = matIdx;
        geometry.faces.push(face1);
        geometry.faces.push(face2);
        geometry.faceVertexUvs[0].push([uv1.clone(), uv2.clone(), uv3.clone(), uv4.clone()]);
}
...
return geometry;
}
for (var i = 0; i < numberOfFaces; i++) {
var texture = THREE.ImageUtils.loadTexture("MyImage"+ i + '.jpg');
var material  = new THREE.MeshBasicMaterial();  
material.map   = texture;
material.side  = THREE.FrontSide;
materials.push(material);
}
materials = new THREE.MeshFaceMaterial(materials);
myGeometry = new THREE.Mesh(createMyGeometry(), materials);
scene.add(myGeometry);

Solution

  • You should just do the same thing with vertex uvs as with vertices.

    For example:

     geometry.faceVertexUvs[0].push([uv1.clone(), uv2.clone(), uv3.clone()]);
     geometry.faceVertexUvs[0].push([uv1.clone(), uv3.clone(), uv4.clone()]);