以上效果只有上下兩面展好了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>
浙公網安備 33010602011771號