未加星标

[webGL学习]基于three.js构建WebGL实例第六讲

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二03 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

[webGL学习]基于three.js构建WebGL实例第六讲

今天我们继续webGL的课程。 今天我们开始另一个主题,我们将使用sprites和纹理动画。 如果你不知道,sprites只是图像,可以附加到对象上。 这些sprites图像总是与我们的相机正交。 Three.js为sprites - THREE.SpriteMaterial提供了一个库,以及一个特殊的一些方法 - THREE.Sprite。 在本教程中,我们还将学习如何使用sprites播放动画。

创建主要的webGL 场景

首先我们创建一个script.js文件,代码如下

var lesson8 = { scene: null, camera: null, renderer: null, container: null, controls: null, clock: null, stats: null, anim1: null, anim2: null, // animations animReady1: false, animReady2: false, init: function() { // initialization // create main scene this.scene = new THREE.Scene(); this.scene.fog = new THREE.FogExp2(0xcce0ff, 0.0003); var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; // prepare perspective camera var VIEW_ANGLE = 60, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 1000; this.camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); this.scene.add(this.camera); this.camera.position.set(100, 0, 0); this.camera.lookAt(new THREE.Vector3(0,0,0)); // prepare webgl renderer this.renderer = new THREE.WebGLRenderer({ antialias:true }); this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); this.renderer.setClearColor(this.scene.fog.color); this.renderer.shadowMapEnabled = true; this.renderer.shadowMapSoft = true; // prepare container this.container = document.createElement('div'); document.body.appendChild(this.container); this.container.appendChild(this.renderer.domElement); // events THREEx.WindowResize(this.renderer, this.camera); // prepare controls (OrbitControls) this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement); this.controls.target = new THREE.Vector3(0, 0, 0); this.controls.maxDistance = 3000; // prepare clock this.clock = new THREE.Clock(); // prepare stats this.stats = new Stats(); this.stats.domElement.style.position = 'absolute'; this.stats.domElement.style.left = '50px'; this.stats.domElement.style.bottom = '50px'; this.stats.domElement.style.zIndex = 1; this.container.appendChild( this.stats.domElement ); // add lights this.scene.add( new THREE.AmbientLight(0x606060) ); var dirLight = new THREE.DirectionalLight(0xffffff); dirLight.position.set(200, 200, 1000).normalize(); this.camera.add(dirLight); this.camera.add(dirLight.target); // display skybox this.addSkybox(); // display animated objects this.addAnimatedObjects(); }, addSkybox: function() { // define path and box sides images var path = 'skybox/'; var sides = [ path + 'sbox_px.jpg', path + 'sbox_nx.jpg', path + 'sbox_py.jpg', path + 'sbox_ny.jpg', path + 'sbox_pz.jpg', path + 'sbox_nz.jpg' ]; // load images var scCube = THREE.ImageUtils.loadTextureCube(sides); scCube.format = THREE.RGBFormat; // prepare skybox material (shader) var skyShader = THREE.ShaderLib["cube"]; skyShader.uniforms["tCube"].value = scCube; var skyMaterial = new THREE.ShaderMaterial( { fragmentShader: skyShader.fragmentShader, vertexShader: skyShader.vertexShader, uniforms: skyShader.uniforms, depthWrite: false, side: THREE.BackSide }); // create Mesh with cube geometry and add to the scene var skyBox = new THREE.Mesh(new THREE.BoxGeometry(500, 500, 500), skyMaterial); skyMaterial.needsUpdate = true; this.scene.add(skyBox); } }; // animate the scene function animate() { requestAnimationFrame(animate); render(); update(); } // update controls and stats function update() { var delta = lesson8.clock.getDelta(); lesson8.controls.update(delta); lesson8.stats.update(); } // Render the scene function render() { if (lesson8.renderer) { lesson8.renderer.render(lesson8.scene, lesson8.camera); } } // Initialize lesson on page load function initializeLesson() { lesson8.init(); animate(); } if (window.addEventListener) window.addEventListener('load', initializeLesson, false); else if (window.attachEvent) window.attachEvent('onload', initializeLesson); else window.onload = initializeLesson;

这段代码创建了渲染器,摄像头,控制装置,照明,统计数据和天空盒一个基本的场景。类似的代码你已经在前面前面的课程中看到的.

Sprites

如前所述,子画面是与我们的相机正交(垂直)的(二维)图像。 现在让我们使用以下函数将sprites添加到场景中:

addAnimatedObjects: function() { var texture1 = new THREE.ImageUtils.loadTexture('images/sprite1.png', undefined, function() { var material1 = new THREE.SpriteMaterial( { map: texture1, useScreenCoordinates: false, side:THREE.DoubleSide, transparent: true } ); var mesh1 = new THREE.Sprite(material1); mesh1.position.set(0, 0, -40); mesh1.scale.set(64, 64, 1.0); lesson8.scene.add(mesh1); }); var texture2 = new THREE.ImageUtils.loadTexture('images/sprite2.png', undefined, function() { var material2 = new THREE.SpriteMaterial( { map: texture2, useScreenCoordinates: false, transparent: true } ); var mesh2 = new THREE.Sprite(material2); mesh2.position.set(0, 0, 40); mesh2.scale.set(24, 46, 1.0); lesson8.scene.add(mesh2); }); }

此代码加载两个图片(sprite1.png和sprite2.png)。 在加载这两个图像之后,我们创建两个sprite材质和Sprite对象,并将它们添加到我们的场景中。 如果现在运行代码,您将在我们的场景中看到两个二维图像。 你可能已经注意到,图像是按照原样绘制 - 我们看到很多小图像(瓷砖) - 这些图像文件被拍摄,因为我们将使用这些瓷砖做动画的事实。

Texture Animation function TileTextureAnimator(texture, hTiles, vTiles, durationTile) { // current tile number this.currentTile = 0; // duration of every tile this.durationTile = durationTile; // internal time counter this.currentTime = 0; // amount of horizontal and vertical tiles, and total count of tiles this.hTiles = hTiles; this.vTiles = vTiles; this.cntTiles = this.hTiles * this.vTiles; texture.wrapS = texture.wrapT = THREE.RepeatWrapping; texture.repeat.set(1 / this.hTiles, 1 / this.vTiles); this.update = function(time) { this.currentTime += time; while (this.currentTime > this.durationTile) { this.currentTime -= this.durationTile; this.currentTile++; if (this.currentTile == this.cntTiles) { this.currentTile = 0; } var iColumn = this.currentTile % this.hTiles; texture.offset.x = iColumn / this.hTiles; var iRow = Math.floor(this.currentTile / this.hTiles); texture.offset.y = iRow / this.vTiles; } }; }

“TileTextureAnimator”函数调整原始图像以显示动画。 它在从第一个到最后一个图像的图像的图像之间切换。 这是在指定的时间间隔。 每个瓦片在一定的持续时间内可见,在它转向另一个瓦片之后。 现在让我们更新我们之前添加的’addAnimatedObjects’函数:

addAnimatedObjects: function() { var texture1 = new THREE.ImageUtils.loadTexture('images/sprite1.png', undefined, function() { lesson8.anim1 = new TileTextureAnimator(texture1, 8, 8, 100); var material1 = new THREE.SpriteMaterial( { map: texture1, useScreenCoordinates: false, side:THREE.DoubleSide, transparent: true } ); var mesh1 = new THREE.Sprite(material1); mesh1.position.set(0, 0, -40); mesh1.scale.set(64, 64, 1.0); lesson8.scene.add(mesh1); lesson8.animReady1 = true; }); var texture2 = new THREE.ImageUtils.loadTexture('images/sprite2.png', undefined, function() { lesson8.anim2 = new TileTextureAnimator(texture2, 9, 8, 100); var material2 = new THREE.SpriteMaterial( { map: texture2, useScreenCoordinates: false, transparent: true } ); var mesh2 = new THREE.Sprite(material2); mesh2.position.set(0, 0, 40); mesh2.scale.set(24, 46, 1.0); lesson8.scene.add(mesh2); lesson8.animReady2 = true; }); }

第一个sprite图像在行中包含8个图块,总共8个行,第二个图像包含行中的9个图块。 每个图块将可见100ms。 最后,在main’update’函数中,我们需要放置以下代码:

if (lesson8.animReady1) { lesson8.anim1.update(1000 * delta); } if (lesson8.animReady2) { lesson8.anim2.update(1000 * delta); } 结束

未完继续

源码下载请关注我的微信公众号


[webGL学习]基于three.js构建WebGL实例第六讲

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: WebGL微信数据
分页:12
转载请注明
本文标题:[webGL学习]基于three.js构建WebGL实例第六讲
本站链接:http://www.codesec.net/view/482167.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(34)