【问题标题】:Rotating textures using canvas with Three.js使用带有 Three.js 的画布旋转纹理
【发布时间】:2013-11-28 16:52:39
【问题描述】:

我想用 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 函数吗?

谢谢!

【问题讨论】:

    标签: javascript canvas three.js


    【解决方案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 回调中重新渲染场景。

    【讨论】:

      猜你喜欢
      • 2013-05-19
      • 1970-01-01
      • 2013-09-22
      • 1970-01-01
      • 2021-01-08
      • 2012-11-25
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多