32
votes

I'm trying to create a three.js cube with different textures on each face.

Basically a dice. This is in my sandbox environment, so should just product a rotating cube with dice images (1-6) on each side. Once done I intend to use this for a browser base game. This example I have only tested in Chrome, although contemplating changing it to a canvas renderer for additional browser support.

Had a look at a few questions here on SO and a substantial amount of other googling, and though I had the answer (seemed reasonably simple actually) but I simply cannot get it to work.

I am reasonably new to three.js, but not JavaScript.

Pages I used for reference are

SO - three.js cube with different texture on each face

SO - three.js cube with different texture faces

evanz - Test three.js cube

and enriquemorenotent.com - three.js building a cube with different materials on each face

My Code

var camera, scene, renderer, dice;

init();
animate();

function init() {
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.set(110, 110, 250);
    camera.lookAt(scene.position);
    scene.add(camera);


    var materials = [
       new THREE.MeshLambertMaterial({
           map: THREE.ImageUtils.loadTexture('/Content/Images/dice-1-hi.png')
       }),
       new THREE.MeshLambertMaterial({
           map: THREE.ImageUtils.loadTexture('/Content/Images/dice-2-hi.png')
       }),
       new THREE.MeshLambertMaterial({
           map: THREE.ImageUtils.loadTexture('/Content/Images/dice-3-hi.png')
       }),
       new THREE.MeshLambertMaterial({
           map: THREE.ImageUtils.loadTexture('/Content/Images/dice-4-hi.png')
       }),
       new THREE.MeshLambertMaterial({
           map: THREE.ImageUtils.loadTexture('/Content/Images/dice-5-hi.png')
       }),
       new THREE.MeshLambertMaterial({
           map: THREE.ImageUtils.loadTexture('/Content/Images/dice-6-hi.png')
       })
    ];
    dice = new THREE.Mesh(
        new THREE.CubeGeometry(562, 562, 562, 1, 1, 1, materials),
        new THREE.MeshFaceMaterial());
    scene.add(dice);

}

function animate() {
    requestAnimationFrame(animate);
    dice.rotation.x += .05;
    dice.rotation.y += .05;
    dice.rotation.z += .05;
    renderer.render(scene, camera);
}

The error I am getting is

Uncaught TypeError: Cannot read property 'map' of undefined 

from three.js line 19546 (not the min version) WHichi is the bufferGuessUVType(material) function - material is undefined. Which leads me to believe something is not right in one/all of my material definitions.

Using three.js r58.

There is really no HTML or CSS, just the JS at this point

I can quite happily get a cube rotating with the same image on all six sides but not with different images. The images are just the images of a dice dots, 1 - 6.

Given a bit more time I could do a fiddle if required

1

1 Answers

36
votes

EDIT: THREE.MultiMaterial has been deprecated. You can now pass the materials array directly into the constructor. Like so:

dice = new THREE.Mesh( new THREE.BoxGeometry( 562, 562, 562, 1, 1, 1 ), materials );

scene.add( dice );

Be careful of copying old examples from the net.

Always check the Migration Wiki for help upgrading to the current version.

three.js r.85