Three.js 旋转纹理

10
我有一个应用于网格的纹理,我可以更改其偏移量。
mesh.material.map.offset.set

我可以使用以下方法更改缩放:

mesh.material.repeat.set

我的问题是,如何在平面内旋转纹理?
示例:
原始纹理: enter image description here 旋转后的纹理: enter image description here 谢谢。
5个回答

16

使用 2D 画布作为纹理

示例:

https://dl.dropboxusercontent.com/u/1236764/temp/stackoverflow_20130525/index.html

示例代码:

var camera, scene, renderer, mesh;

var width = window.innerWidth;
var height = window.innerHeight;

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera( 30, width / height, 1, 1000 );
camera.position.z = 100;

renderer = new THREE.WebGLRenderer();
renderer.setSize( width, height );
document.body.appendChild( renderer.domElement );

var img = new Image();
img.onload = createMeshThenRender;
img.src = 'img.jpg';

function createMeshThenRender () {
    var imgWidth = imgHeight = 256;
    var mapCanvas = document.createElement( 'canvas' );
    mapCanvas.width = mapCanvas.height = 256;

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

    var texture = new THREE.Texture( mapCanvas );
    texture.needsUpdate = true;

    mesh = new THREE.Mesh(
        new THREE.PlaneGeometry( 50, 50, 1, 1 ),
        new THREE.MeshBasicMaterial( {
            map : texture
        } )
    );
    scene.add( mesh );
    renderer.render( scene, camera );
}

那真的很有帮助。直接在画布上旋转/缩放图像比使用图像要容易得多。 - JayMoretti

3

three.js没有UV编辑工具,因此您必须手动编辑geometry.faceVertexUvs或在图像编辑程序中旋转图像。我建议选择后者。

three.js r.58


2
我将不得不调整UV,但后者会破坏我正在构建的目的。 - JayMoretti

3

three.js r121

在新版本的three.js中,你可以直接设置纹理的旋转和旋转中心。

var texture = new THREE.Texture( ... );
texture.rotation = Math.PI/4;
texture.center = new Vector2d(0.5, 0.5); // center of texture.

2

three.js r85

对于那些希望在 XY 平面上(默认平面)使用 ShapeBufferGeometry 或 PlaneBufferGeometry 实际“旋转 UV” 的人来说,以下是一些帮助:

var planeGeo = new THREE.PlaneBufferGeometry(24,24);
var planeMesh = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({map: yourTexture}));
scene.add(planeMesh);
rotateUVonPlanarBufferGeometry(45, planeMesh);

function rotateUVonPlanarBufferGeometry(rotateInDeg, mesh){
  if(rotateInDeg != undefined && mesh){

    var degreeInRad = THREE.Math.degToRad(rotateInDeg);
    var tempGeo = mesh.geometry.clone();
    var geo;

    if(tempGeo instanceof THREE.BufferGeometry){
        geo = new THREE.Geometry().fromBufferGeometry(tempGeo);
    }else{
        console.log('regular geometry currently not supported in this method, but can be if code is modified, so use a buffer geometry');
        return;
    }

    // rotate the geo on Z-axis
    // which will rotate the vertices accordingly
    geo.applyMatrix(new THREE.Matrix4().makeRotationZ(degreeInRad));

    // loop through the vertices which should now have been rotated
    // change the values of UVs based on the new rotated vertices
    var index = 0;
    geo.vertices.forEach(function(v){
      mesh.geometry.attributes.uv.setXY( index, v.x, v.y );
      index++;
    });

    mesh.geometry.attributes.uv.needsUpdate = true;

  }

}

0

以上的解决方案对我来说不太好,有点过时。这个简单的解决方案对我很有效(Three.js 125)

imgData = canvasCtx.getImageData(0, 0, canvasElement.width, canvasElement.height);
texture = new THREE.DataTexture( imgData.data, canvasElement.width, canvasElement.height, THREE.SRGB );
texture.rotation = Math.PI;
texture.center = new THREE.Vector2(0.5, 0.5); // center of texture.
mymaterial = new THREE.MeshBasicMaterial({
                                map: texture,
                                alphaTest: 0.5,
                                transparent: true,
                                side: THREE.DoubleSide,
                            });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接