以上效果只有上下两面展好了uv,时间问题其他面没有展uv

 

threejs 版本 0.143.0

 

这个版本的几何和老版本的有区别,取消了Geomety ,取而代之的是BufferGeometry ,也没有Face3, 现在是用index 索引的方式链接面。有个困扰就是Face3里面的materialIndex在新版里面怎么实现,这里用的groups 这个属性结构是

[{start: xx, count: xx, materialIndex:xx}]

大致意思就是 从start下标开始,向后count个结束,使用materialIndex材质。注意这里的下标是index索引的下标,结合结合以下代码更好理解

代码

 

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - geometry - cube</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link type="text/css" rel="stylesheet" href="main.css">
    </head>
    <body>

        <!-- Import maps polyfill -->
        <!-- Remove this when import maps will be widely supported -->
        <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
        <script type="importmap">
            {
                "imports": {
                    "three": "../build/three.module.js",
                    "three/addons/": "./jsm/"
                }
            }
        </script>
        <script type="module">
            import * as THREE from 'three';

            let camera, scene, renderer;
            let mesh;

            init();
            animate();

            function init() {
                camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
                camera.position.z = 400;
                scene = new THREE.Scene();
                const texture = new THREE.TextureLoader().load( 'textures/crate.gif' );
                let geometry = new THREE.BufferGeometry();

                let geoData = [];
                let index = [];
                let num = 100;
                // 顶点 法线 uv
                geoData.push({position : [num, num, num], normal : [0, 1, 0], uv : [0, 0]});
                geoData.push({position : [num, num, -num], normal : [0, 1, 0], uv : [1, 0]});
                geoData.push({position : [-num, num, -num], normal : [0, 1, 0], uv : [1, 1]});
                geoData.push({position : [-num, num, num], normal : [0, 1, 0], uv : [0, 1]});
                geoData.push({position : [num, -num, num], normal : [0, 1, 0], uv : [0, 0]});
                geoData.push({position : [num, -num, -num], normal : [0, 1, 0], uv : [1, 0]});
                geoData.push({position : [-num, -num, -num], normal : [0, 1, 0], uv : [1, 1]});
                geoData.push({position : [-num, -num, num], normal : [0, 1, 0], uv : [0, 1]});
                paseData(geoData, geometry);

                // 索引
                index = [0,4,5,  0,5,1,  1,5,6,  1,6,2,  2,6,7,  2,7,3,  3,7,4,  3,4,0,  0,2,3,  0,1,2,  4,7,6,  4,6,5];
                const indexs = new Uint16Array(index);
                geometry.index = new THREE.BufferAttribute(indexs, 1);

                // 材质
                let mat = [];
                mat.push(new THREE.MeshBasicMaterial( {map:texture, color: 0xff0000, } )); // 材质0
                mat.push(new THREE.MeshBasicMaterial( {map:texture, color: 0x00ff00, } )); // 材质1
                mat.push(new THREE.MeshBasicMaterial( {map:texture, color: 0x0000ff, } )); // 材质2
                mat.push(new THREE.MeshBasicMaterial( {map:texture, color: 0xffff00, } )); // 材质3
                mat.push(new THREE.MeshBasicMaterial( {map:texture, color: 0x00ffff, } )); // 材质4
                mat.push(new THREE.MeshBasicMaterial( {map:texture, color: 0xffff00, } )); // 材质5

                // 索引(面)与材质关联
                let groups = [];
                groups.push({start: 0, count: 6, materialIndex:0}); // 0-6  index[0,4,5, 0,5,1] 用材质1
                groups.push({start: 6, count: 6, materialIndex:1}); // 6-12 index[1,5,6, 1,6,2] 用材质2
                groups.push({start: 12, count: 6, materialIndex:2});
                groups.push({start: 18, count: 6, materialIndex:3});
                groups.push({start: 24, count: 6, materialIndex:4});
                groups.push({start: 30, count: 6, materialIndex:5});

                geometry.groups = groups;

                // geometry.computeVertexNormals();

                mesh = new THREE.Mesh( geometry, mat );
                scene.add( mesh );

                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                document.body.appendChild( renderer.domElement );
                window.addEventListener( 'resize', onWindowResize );
            }

            function paseData(geoData, geometry){
                let position = [];
                let normal = [];
                let uv = [];
                geoData.forEach(e => {
                    position = position.concat(e.position);
                    normal = normal.concat(e.normal);
                    uv = uv.concat(e.uv);
                });
                geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(position), 3));
                geometry.setAttribute("normal", new THREE.BufferAttribute(new Float32Array(normal), 3));
                geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uv), 2));
            }

            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize( window.innerWidth, window.innerHeight );
            }

            function animate() {
                requestAnimationFrame( animate );
                mesh.rotation.x += 0.05;
                mesh.rotation.y += 0.01;
                renderer.render( scene, camera );
            }
        </script>
    </body>
</html>