irpas技术客

Three.js案例从0到1(3)复杂的计算组合生成几何体_pocean2012

irpas 8323

1. 重构初始化,结构性更好

主程序

function init(event) { console.log("main js start. ") createScene(); createLights(); createSea(); animate(); } window.addEventListener('load', init, false);

创建场景和灯光分开

function createScene() { HEIGHT = window.innerHeight; WIDTH = window.innerWidth; scene = new THREE.Scene(); aspectRatio = WIDTH / HEIGHT; fieldOfView = 60; nearPlane = 1; farPlane = 10000; camera = new THREE.PerspectiveCamera( fieldOfView, aspectRatio, nearPlane, farPlane ); scene.fog = new THREE.Fog(0xf7d9aa, 100, 950); camera.position.x = 0; camera.position.z = 200; camera.position.y = 100; renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setSize(WIDTH, HEIGHT); renderer.shadowMap.enabled = true; container = document.getElementById('world'); container.appendChild(renderer.domElement); window.addEventListener('resize', handleWindowResize, false); } // LIGHTS var ambientLight, hemisphereLight, shadowLight; function createLights() { hemisphereLight = new THREE.HemisphereLight(0xaaaaaa, 0x000000, .9) shadowLight = new THREE.DirectionalLight(0xffffff, .9); shadowLight.position.set(150, 350, 350); shadowLight.castShadow = true; shadowLight.shadow.camera.left = -400; shadowLight.shadow.camera.right = 400; shadowLight.shadow.camera.top = 400; shadowLight.shadow.camera.bottom = -400; shadowLight.shadow.camera.near = 1; shadowLight.shadow.camera.far = 1000; shadowLight.shadow.mapSize.width = 2048; shadowLight.shadow.mapSize.height = 2048; scene.add(hemisphereLight); scene.add(shadowLight); }

加入了屏幕调整自适应

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

sea和plane的创建实例

// 创建实例化sea函数 function createSea() { sea = new Sea(); sea.mesh.position.y = -600; scene.add(sea.mesh); }

动画效果

function animate() { requestAnimationFrame(animate); //海浪效果 sea.mesh.rotation.z += .005; renderer.render(scene, camera); };

完成效果

2. 建立复杂模型,用模型组合成飞机,并实例化

// 创建飞机模型 AirPlane = function() { this.mesh = new THREE.Object3D(); // 创建机舱 var geomCockpit = new THREE.BoxGeometry(60, 50, 50, 1, 1, 1); var matCockpit = new THREE.MeshPhongMaterial({ color: Colors.red, shading: THREE.FlatShading }); var cockpit = new THREE.Mesh(geomCockpit, matCockpit); cockpit.castShadow = true; cockpit.receiveShadow = true; this.mesh.add(cockpit); // 创建引擎 var geomEngine = new THREE.BoxGeometry(20, 50, 50, 1, 1, 1); var matEngine = new THREE.MeshPhongMaterial({ color: Colors.white, shading: THREE.FlatShading }); var engine = new THREE.Mesh(geomEngine, matEngine); engine.position.x = 40; engine.castShadow = true; engine.receiveShadow = true; this.mesh.add(engine); // 创建机尾 var geomTailPlane = new THREE.BoxGeometry(15, 20, 5, 1, 1, 1); var matTailPlane = new THREE.MeshPhongMaterial({ color: Colors.red, shading: THREE.FlatShading }); var tailPlane = new THREE.Mesh(geomTailPlane, matTailPlane); tailPlane.position.set(-35, 25, 0); tailPlane.castShadow = true; tailPlane.receiveShadow = true; this.mesh.add(tailPlane); // 创建机翼 var geomSideWing = new THREE.BoxGeometry(40, 8, 150, 1, 1, 1); var matSideWing = new THREE.MeshPhongMaterial({ color: Colors.red, shading: THREE.FlatShading }); var sideWing = new THREE.Mesh(geomSideWing, matSideWing); sideWing.castShadow = true; sideWing.receiveShadow = true; this.mesh.add(sideWing); // 创建螺旋桨 var geomPropeller = new THREE.BoxGeometry(20, 10, 10, 1, 1, 1); var matPropeller = new THREE.MeshPhongMaterial({ color: Colors.brown, shading: THREE.FlatShading }); this.propeller = new THREE.Mesh(geomPropeller, matPropeller); this.propeller.castShadow = true; this.propeller.receiveShadow = true; // 创建螺旋桨的桨叶 var geomBlade = new THREE.BoxGeometry(1, 100, 20, 1, 1, 1); var matBlade = new THREE.MeshPhongMaterial({ color: Colors.brownDark, shading: THREE.FlatShading }); // 创建机翼 var blade = new THREE.Mesh(geomBlade, matBlade); blade.position.set(8, 0, 0); blade.castShadow = true; blade.receiveShadow = true; this.propeller.add(blade); this.propeller.position.set(50, 0, 0); this.mesh.add(this.propeller); }; // 实例化飞机函数 function createPlane() { airplane = new AirPlane(); airplane.mesh.scale.set(.25, .25, .25); airplane.mesh.position.y = 100; scene.add(airplane.mesh); }

主场景添加飞机模型,动画添加螺旋桨转动效果

function init(event) { console.log("main js start. ") createScene(); createLights(); createSea(); createPlane(); animate(); }

?animate添加

airplane.propeller.rotation.x += 0.3;

运行效果:

?

?3. 由立方体组合成云朵,云朵变化组成天空效果

用立方体组合创建云朵,用到了随机生成

// 创建云 Cloud = function() { // 创建一个空的容器放置不同形状的云 this.mesh = new THREE.Object3D(); this.mesh.name = "cloud"; // 创建一个正方体 // 这个形状会被复制创建云 var geom = new THREE.BoxGeometry(20, 20, 20); // 创建材质;一个简单的白色材质就可以达到效果 var mat = new THREE.MeshPhongMaterial({ color: Colors.white, }); // 随机多次复制几何体 var nBlocs = 3 + Math.floor(Math.random() * 3); for (var i = 0; i < nBlocs; i++) { // 通过复制几何体创建网格 var m = new THREE.Mesh(geom.clone(), mat); // 随机设置每个正方体的位置和旋转角度 m.position.x = i * 15; m.position.y = Math.random() * 10; m.position.z = Math.random() * 10; m.rotation.z = Math.random() * Math.PI * 2; m.rotation.y = Math.random() * Math.PI * 2; // 随机设置正方体的大小 var s = .1 + Math.random() * .9; m.scale.set(s, s, s); // 允许每个正方体生成投影和接收阴影 m.castShadow = true; m.receiveShadow = true; // 将正方体添加至开始时我们创建的容器中 this.mesh.add(m); } }

创建天空

// 创建天空 Sky = function() { this.mesh = new THREE.Object3D(); this.nClouds = 20; this.clouds = []; var stepAngle = Math.PI * 2 / this.nClouds; for (var i = 0; i < this.nClouds; i++) { var c = new Cloud(); this.clouds.push(c); var a = stepAngle * i; var h = 750 + Math.random() * 200; c.mesh.position.y = Math.sin(a) * h; c.mesh.position.x = Math.cos(a) * h; c.mesh.position.z = -400 - Math.random() * 400; c.mesh.rotation.z = a + Math.PI / 2; var s = 1 + Math.random() * 2; c.mesh.scale.set(s, s, s); this.mesh.add(c.mesh); } } // 创建实例 function createSky() { sky = new Sky(); sky.mesh.position.y = -600; scene.add(sky.mesh); }

形成动画效果

//天空效果 sky.mesh.rotation.z += .01;

动画效果

?

?完整例子下载

three.js从0到1实操案例,完整目录,直接可用-Javascript文档类资源-CSDN下载

?


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #1 #initevent