1. 程式人生 > >63 Three.js 將多個網格合併成一個網格

63 Three.js 將多個網格合併成一個網格

var renderer; function initRender() { renderer = new THREE.WebGLRenderer({antialias:true}); renderer.setSize(window.innerWidth, window.innerHeight); //告訴渲染器需要陰影效果 renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 預設的是,沒有設定的這個清晰 THREE.PCFShadowMap
document.body.appendChild(renderer.domElement); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.set(0, 40, 100); camera.lookAt(new THREE.Vector3(0,0,0)); } var scene; function
initScene() {
scene = new THREE.Scene(); } //初始化dat.GUI簡化試驗流程 var gui; function initGui() { //宣告一個儲存需求修改的相關資料的物件 gui = { numberOfObjects:500, //當前場景中模型的個數 combined:false, //是否合併模型 redraw:function () { //刪除場景內現有的立方體 var
arr = []; scene.traverse(function (e) { if (e instanceof THREE.Mesh) arr.push(e); }); arr.forEach(function (value) { scene.remove(value); }); //重新生成立方體 if(gui.combined){ //合併模型,則使用merge方法合併 var geometry = new THREE.Geometry(); //merge方法將兩個幾何體物件或者Object3D裡面的幾何體物件合併,(使用物件的變換)將幾何體的頂點,面,UV分別合併. //THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead. for(var i=0; i<gui.numberOfObjects; i++){ var cube = addCube(); cube.updateMatrix(); geometry.merge(cube.geometry, cube.matrix); } scene.add(new THREE.Mesh(geometry, cubeMaterial)); } else{ //不合並模型,則直接將模型放入 for(var i=0; i<gui.numberOfObjects; i++){ scene.add(addCube()); } } } }; var datGui = new dat.GUI(); //將設定屬性新增到gui當中,gui.add(物件,屬性,最小值,最大值) //新增旋轉功能 datGui.add(gui, "numberOfObjects", 0, 20000); datGui.add(gui, "combined"); datGui.add(gui, "redraw"); gui.redraw(); } //建立立方體的方法 var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x00ff00, transparent: true, opacity: 0.8}); function addCube() { var cubeSize = 1.0; var cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize); var cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.castShadow = true; cube.position.x = -100+Math.round(Math.random()*200); cube.position.y = -100+Math.round(Math.random()*200); cube.position.z = -100+Math.round(Math.random()*200); return cube; } var light; function initLight() { scene.add(new THREE.AmbientLight(0x444444)); light = new THREE.DirectionalLight(0xffffff); light.position.set(15,50,10); //告訴平行光需要開啟陰影投射 light.castShadow = true; scene.add(light); } var sphere,cube; function initModel() { //輔助工具 var helper = new THREE.AxisHelper(50); scene.add(helper); return; //模型組 group = new THREE.Object3D(); scene.add(group); //球 var sphereGeometry = new THREE.SphereGeometry(5,200,200); var sphereMaterial = new THREE.MeshLambertMaterial({color:0xaaaaaa}); sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); sphere.position.x = -5; sphere.position.y = 5; //告訴球需要投射陰影 sphere.castShadow = true; group.add(sphere); //立方體 var cubeGeometry = new THREE.CubeGeometry(10,10,8); var cubeMaterial = new THREE.MeshLambertMaterial({color:0x00ffff}); cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.position.x = 15; cube.position.y = 5; cube.position.z = -5; //告訴立方體需要投射陰影 cube.castShadow = true; group.add(cube); //底部平面 var planeGeometry = new THREE.PlaneGeometry(100,100); var planeMaterial = new THREE.MeshStandardMaterial({color:0xaaaaaa}); var plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = - 0.5 * Math.PI; plane.position.y = -0; //告訴底部平面需要接收陰影 plane.receiveShadow = true; scene.add(plane); } //初始化效能外掛 var stats; function initStats() { stats = new Stats(); document.body.appendChild(stats.dom); } //使用者互動外掛 滑鼠左鍵按住旋轉,右鍵按住平移,滾輪縮放 var controls; function initControls() { controls = new THREE.OrbitControls( camera, renderer.domElement ); // 如果使用animate方法時,將此函式刪除 //controls.addEventListener( 'change', render ); // 使動畫迴圈使用時阻尼或自轉 意思是否有慣性 controls.enableDamping = true; //動態阻尼係數 就是滑鼠拖拽旋轉靈敏度 //controls.dampingFactor = 0.25; //是否可以縮放 controls.enableZoom = true; //是否自動旋轉 controls.autoRotate = true; controls.autoRotateSpeed = 0.5; //設定相機距離原點的最近距離 controls.minDistance = 10; //設定相機距離原點的最遠距離 controls.maxDistance = 500; //是否開啟右鍵拖拽 controls.enablePan = true; } var step = 0.02; //模型旋轉的速度 function render() { renderer.render( scene, camera ); } //視窗變動觸發的函式 function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); render(); renderer.setSize( window.innerWidth, window.innerHeight ); } function animate() { //更新控制器 render(); //更新效能外掛 stats.update(); controls.update(); requestAnimationFrame(animate); } function draw() { initRender(); initScene(); initCamera(); initLight(); initModel(); initGui(); initControls(); initStats(); animate(); window.onresize = onWindowResize; }