2013-11-15 2 views
1

Я хочу повернуть текстуру, появляющуюся на одной грани куба, с помощью Three.js.Вращающиеся текстуры с использованием холста с помощью Three.js

Поскольку этот куб создается несколько раз с различными текстурами, я использую функцию, которая создает материал и сетку с параметром текстуры.

Однако мне нужна эта текстура для поворота на 90 °, и я нашел, что лучший способ - создать холст, поместить текстуру внутрь, повернуть его и использовать этот холст в качестве текстуры сетки. Я пытался добиться этого с помощью этого кода: Three.js Rotate Texture, но, к сожалению, я всегда получаю черную текстуру.

Вот моя функция:

function createCube(pos, texture) { 
    var img = new Image(); 
    img.src = texture; 

    var imgWidth = imgHeight = img.width; 
    var mapCanvas = document.createElement('canvas'); 
    mapCanvas.width = mapCanvas.height = img.width; 

    // document.body.appendChild(mapCanvas); 
    var ctx = mapCanvas.getContext('2d'); 
    ctx.translate(imgWidth/2, imgHeight/2); 
    ctx.rotate(Math.PI/2); 
    ctx.translate(-imgWidth/2, -imgHeight/2); 
    ctx.drawImage(img, 0, 0, imgWidth, imgHeight); 

    var texture = new THREE.Texture(mapCanvas); 
    texture.needsUpdate = true; 
    var materials = [ 
       //Left side (posx) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }), 
       //Right side (negx) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }), 
       //Top side (posy) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }), 
       //Bottom side (negy) 
       new THREE.MeshLambertMaterial({ 
        color: 0xffffff, 
        map: texture 
       }), 
       //Front side (posz) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }), 
       //Back side (negz) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }) 
    ]; 

    cube = new THREE.Mesh(new THREE.CubeGeometry(100, 2, 100, 1, 1, 1), new THREE.MeshFaceMaterial(materials)); 

    ... 

    return cube; 

} 

Может быть, может быть связано с текстурой еще не загружен, когда добавляется к холсту? Я удалил img.onLoad (от Three.js Rotate Texture), потому что я не знал, как использовать этот обратный вызов внутри многократно вызываемой функции ... Кроме того, эта функция, чтобы вернуть сетку, могу ли я сделать это с помощью функции extern .onLoad?

Спасибо!

ответ

1

Ваша догадка о том, что «из-за текстуры, еще не загруженной при добавлении к холсту», определенно правильна.

Вам просто нужно повторно включить обратный вызов, который требует некоторого переупорядочения вашего кода. Должно работать несколько, как это (непроверенные, но должны сделать идею понятной, если не работать сразу):

function createCube(pos, texture) { 
    var img = new Image(); 

    var imgWidth = imgHeight = img.width; 
    var mapCanvas = document.createElement('canvas'); 
    mapCanvas.width = mapCanvas.height = img.width; 

    var texture = new THREE.Texture(mapCanvas); 


    img.onload = function() { 


     // document.body.appendChild(mapCanvas); 
     var ctx = mapCanvas.getContext('2d'); 
     ctx.translate(imgWidth/2, imgHeight/2); 
     ctx.rotate(Math.PI/2); 
     ctx.translate(-imgWidth/2, -imgHeight/2); 
     ctx.drawImage(img, 0, 0, imgWidth, imgHeight); 

     texture.needsUpdate = true; 


    } 

    var materials = [ 
       //Left side (posx) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }), 
       //Right side (negx) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }), 
       //Top side (posy) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }), 
       //Bottom side (negy) 
       new THREE.MeshLambertMaterial({ 
        color: 0xffffff, 
        map: texture 
       }), 
       //Front side (posz) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }), 
       //Back side (negz) 
       new THREE.MeshLambertMaterial({ 
        color: 0x1a0e05 
       }) 
    ]; 

    img.src = texture; 

    cube = new THREE.Mesh(new THREE.CubeGeometry(100, 2, 100, 1, 1, 1), new THREE.MeshFaceMaterial(materials)); 

    ... 

    return cube; 

} 

Вы должны иметь рендеринга петлю, или в качестве альтернативы, повторно визуализировать сцену в OnLoad обратного вызова тоже.

+0

Это сработало очень хорошо, спасибо вам большое! – risk

Смежные вопросы