圆柱面上的三个多个图像

时间:2018-02-02 01:47:21

标签: javascript three.js

我试图使用three.js在旋转圆柱体的外侧(不是顶部或底部)显示多个图像。我能够显示1张图像,但我的目标是并排显示几张图像。我在材质数组中添加了3个纹理,但只显示了第一个纹理。任何帮助表示赞赏。

<html>
<head>
    <title>My first three.js app</title>
    <span>Test</span>
    <style>
        body { margin: 0; }
        canvas { width: 100%; height: 100% }
    </style>
</head>
<body>
    <script src="js/three.js"></script>
    <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.1, 1000 );
        camera.position.y = 24;

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

        var diameter = 20;
        var geometry = new THREE.CylinderGeometry( diameter, diameter, 15, 32 );

        var texture1 = new THREE.TextureLoader().load( 'images/image1.jpg' );
        var texture2 = new THREE.TextureLoader().load( 'images/image2.jpg' );
        var texture3 = new THREE.TextureLoader().load( 'images/image3.png' );

        texture1.wrapS = THREE.RepeatWrapping;
        //texture.wrapT = THREE.RepeatWrapping;
        //texture.repeat.set( 1, 4 );

        var materials = [];
        materials.push(new THREE.MeshBasicMaterial({ map: texture1 }));
        materials.push(new THREE.MeshBasicMaterial({ map: texture2 }));
        materials.push(new THREE.MeshBasicMaterial({ map: texture3 }));

        var cylinder = new THREE.Mesh( geometry, materials );
        cylinder.position.y = 25;
        scene.add( cylinder);

        camera.position.z = 40;


        function render() {
            requestAnimationFrame(render);
            //cylinder.rotation.z += 0.05;
          cylinder.rotation.y += 0.005;
            renderer.render(scene, camera);
        }
        render();
    </script>
</body>

2 个答案:

答案 0 :(得分:0)

您想要将三个纹理应用于圆柱体。

如果您不想将纹理合并到单个纹理中,一个简单的解决方案是渲染三个圆柱体楔形,每个楔形都有自己的纹理。使用如下模式:

var group = new THREE.Group();
scene.add( group );

var geometry = new THREE.CylinderBufferGeometry( 5, 5, 10, 16, 1, false, 0, 2 * Math.PI / 3 ); // 1/3 cylinder wedge

var endCapMaterial = new THREE.MeshBasicMaterial();

// mesh
mesh = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { map: texture1 } ), endCapMaterial, endCapMaterial ] );
mesh.rotation.set( 0, 0, 0 );
group.add( mesh );

mesh = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { map: texture2 } ), endCapMaterial, endCapMaterial ] );
mesh.rotation.set( 0, 2 * Math.PI / 3, 0 );
group.add( mesh );

mesh = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { map: texture3 } ), endCapMaterial, endCapMaterial ] );
mesh.rotation.set( 0, 4 * Math.PI / 3, 0 );
group.add( mesh );

three.js r.89

答案 1 :(得分:0)

另一种方法是使用geometry.faces[i].materialIndex属性为几何体的每个面指定纹理。在这种情况下,您应该使用三个倍数的径向段数(如果您有3个纹理)。

&#13;
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
<html>
<head>
    <title>My first three.js app</title>
    <style>
        body { margin: 0; overflow:hidden;}
        canvas { width: 100%; height: 100% }
    </style>
</head>
<body>
<script>
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.1, 1000 );
    camera.position.y = 24;

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

    var diameter = 20;
    var radialSegments = 33;
    var geometry = new THREE.CylinderGeometry( diameter, diameter, 15, radialSegments );
    
    var img1 = "http://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX9108127.jpg";
    var img2 = "http://d2gg9evh47fn9z.cloudfront.net/thumb_COLOURBOX8923432.jpg";
    var img3 = "http://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX19377428.jpg";

    var texture1 = new THREE.TextureLoader().load( img1 );
    var texture2 = new THREE.TextureLoader().load( img2 );
    var texture3 = new THREE.TextureLoader().load( img3 );

    THREE.DefaultLoadingManager.onLoad = function () {
        var materials = [];
        materials.push(new THREE.MeshBasicMaterial({ map: texture1 }));
        materials.push(new THREE.MeshBasicMaterial({ map: texture2 }));
        materials.push(new THREE.MeshBasicMaterial({ map: texture3 }));
        var l = geometry.faces.length;
        for (var i = 0; i < l; i++) {
            if (geometry.faces[i].normal.y !== 0) {
                // these are caps
                geometry.faces[i].materialIndex = 0;
            } else {
                // each segment has 2 faces
                geometry.faces[i].materialIndex = Math.floor(i * 3 / (radialSegments * 2));
            }
        }

        var cylinder = new THREE.Mesh( geometry, materials);
        cylinder.position.y = 25;
        scene.add( cylinder);

        camera.position.z = 40;

        function render() {
            requestAnimationFrame(render);
            cylinder.rotation.y += 0.005;
            renderer.render(scene, camera);
        }
        render();
    }
</script>
</body>
&#13;
&#13;
&#13;