使用Three.js在多个面上拉伸纹理

时间:2014-11-28 08:44:07

标签: three.js texture-mapping

我尝试在具有由多个面组成的自定义几何体的Object3D上应用纹理。从用户的角度来看,这应该是单个表面,并且纹理应该理想地保持边缘比率。我尝试了各种纹理设置,但到目前为止还没有运气。

顶部图片是我得到的,而最底层的图片是我想要实现的:https://dl.dropboxusercontent.com/u/20925853/combined.jpg

我已将示例代码提取到JsFiddle:http://jsfiddle.net/Immugio/Lg5vbzot/

function render() {            

        renderer.render(scene, camera);
    };       

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);       

    var light = new THREE.DirectionalLight(0xffffff);
    light.intensity = 0.5;
    light.position.set(0, 1, 1).normalize();
    scene.add(light);
    var ambient = new THREE.AmbientLight(0x777777);        
    scene.add(ambient);

    var controls = new THREE.OrbitControls(camera);
    controls.damping = 0.2;
    controls.addEventListener('change', render);     

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    THREE.ImageUtils.crossOrigin = '';
    var textureMaterial = new THREE.MeshPhongMaterial({
        map: THREE.ImageUtils.loadTexture('https://dl.dropboxusercontent.com/u/20925853/crate.jpg', null, function() {
            render();
        })
    });

    var geo = new THREE.Geometry();
    geo.vertices = [
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(0, 4, 0),
        new THREE.Vector3(4, 4, 0),
        new THREE.Vector3(4, 0, 0),

        new THREE.Vector3(1, 4, 0),
        new THREE.Vector3(1, 6, 0),
        new THREE.Vector3(3, 6, 0),
        new THREE.Vector3(3, 4, 0)
    ];
    geo.faces = [
        new THREE.Face3(0, 1, 2),
        new THREE.Face3(0, 2, 3),
        new THREE.Face3(4, 5, 6),
        new THREE.Face3(4, 6, 7)
    ];

    var faceuv = [
                new THREE.Vector2(0, 1),
                new THREE.Vector2(1, 1),
                new THREE.Vector2(1, 0),
                new THREE.Vector2(0, 0)
        ];

    geo.faceVertexUvs[0] = [];
    geo.faceVertexUvs[0][0] = [faceuv[0], faceuv[1], faceuv[2]];
    geo.faceVertexUvs[0][1] = [faceuv[0], faceuv[2], faceuv[3]];
    geo.faceVertexUvs[0][2] = [faceuv[0], faceuv[1], faceuv[2]];
    geo.faceVertexUvs[0][3] = [faceuv[0], faceuv[2], faceuv[3]];              

    geo.computeFaceNormals();
    var mesh = new THREE.Mesh(geo, textureMaterial);

    mesh.rotation.x = Math.PI / 180 * 135;
    mesh.rotation.z = Math.PI / 180 * 135;
    scene.add(mesh); 

    camera.position.z = 10;

1 个答案:

答案 0 :(得分:3)

为了拉伸纹理,您需要将UV映射到多个面上。

JsFiddle:http://jsfiddle.net/Lg5vbzot/1/

替换为以下代码

        var faceuv = [
                new THREE.Vector2(0, 0),
                new THREE.Vector2(0, 0.66),
                new THREE.Vector2(1, 0.66),
                new THREE.Vector2(1, 0),
                new THREE.Vector2(0.25, 0.66),
                new THREE.Vector2(0.25, 1),
                new THREE.Vector2(0.75, 1),
                new THREE.Vector2(0.75, 0.66)
        ];

    geo.faceVertexUvs[0] = [];
    geo.faceVertexUvs[0][0] = [faceuv[0], faceuv[1], faceuv[2]];
    geo.faceVertexUvs[0][1] = [faceuv[0], faceuv[2], faceuv[3]];
    geo.faceVertexUvs[0][2] = [faceuv[4], faceuv[5], faceuv[6]];
    geo.faceVertexUvs[0][3] = [faceuv[4], faceuv[6], faceuv[7]];