35

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

sohnryang
  • 725
  • 2
  • 13
  • 27
OJay
  • 4,763
  • 3
  • 26
  • 47

1 Answers1

39

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

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • Magic!! I wondered why the three.js documentation didn't have 7 parameters for the CubeGeometry constructor. Cheers – OJay Jul 02 '13 at 20:27
  • 7
    how ironic that the migration wiki link is itself rotted :P – erik258 Jan 06 '17 at 17:38
  • @WestLangley This does not work with object loaded using GLTFLoader – CodeDezk Sep 17 '19 at 07:34
  • @CodeDezk A mesh needs to be set up with specific locations for the materials, an arbitrary model from some other source might not have that like BoxGeometry does. You may need to open a separate question for it. – Don McCurdy Feb 27 '20 at 16:14