Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three.js cube with different texture on each face

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

like image 415
OJay Avatar asked Jul 02 '13 05:07

OJay


1 Answers

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

like image 109
WestLangley Avatar answered Oct 18 '22 07:10

WestLangley