“粒子动画”是大家可能经常听到的一个名词,那么什么是粒子动画呢?粒子是指物体的最小单位,例如原子和分子。在2D中,这个最小单位是一个像素,而在3D中,这个最小单位是一个顶点。粒子动画不是指物体本身的动画,而是指这些基本单元的动画。因为是组成物体的单位的动画,所以会有打散重组的效果。本篇学习3D粒子动画制作星星加持效果:思路分析在3D世界中,一个物体是由顶点组成的,3个顶点组成一个三角形,然后在三角形上粘贴不同的贴图,即一个3D模型。也就是说,3D模型是由顶点确定的几何体(Geometry),贴上不同的贴图(Material)构成的物体(Mesh等)。之后,将3D物体添加到场景(Scene)中,设置一个摄像机(Camera)角度进行观察,然后使用渲染器(Renderer)逐帧渲染。这就是3D渲染过程。3D物体是由顶点组成的,所以移动这些顶点就是粒子动画,因为基本粒子在移动的时候,自然会产生打散重组的效果。在“星辰送福”效果中,我们将星辰打散重组为“福”字。事实上,星星的顶点移动到了“福”字的顶点,从一个三维物体变成了另一个三维物体。那么星星的顶点从何而来呢?“福”字的顶点是怎么来的?星星的顶点实际上是在不同位置随机生成的点。在这些点上贴上星图就是星图效果。角色Fu的顶点是一个加载的3D模型,解析得到它的顶点数据。有了两个3D物体的顶点数据,即动画的起始坐标和结束坐标,通过不断修改每个顶点的x、y、z属性就可以实现粒子动画。这里不计算x、y、z属性值的变化,而是使用一些动画库来计算。支持加减速等时间功能。Three.js的动画库是Tween.js。简而言之,3D粒子动画就是顶点的x,y,z属性的变化,会使用动画库来计算中间属性值。从一个物体的顶点位置移动到另一个物体的顶点位置,会产生打散重组的效果,这也是粒子动画的魅力所在。思路清晰了,接下来我们来详细写代码。代码实现上面提到,3D渲染需要一个场景(Scene)来管理所有的3D对象,一个摄像机(Camera)来从不同的角度观察,还有一个渲染器(Renderer)来逐帧渲染。这部分是基础代码,先写这部分:创建场景:constscene=newTHREE.Scene();创建一个摄像头:constwidth=window.innerWidth;constheight=window.innerHeight;constcamera=newTHREE.PerspectiveCamera(45,宽度/高度,0.1,1000);相机分为透视相机和平行相机。我们这里使用的透视相机就是近大远小的透视效果。需要指定三个参数:视角(45)、纵横比(宽度/高度)和远近范围(0.1到1000)。调整相机的位置和观察方向:camera.position.set(100,0,400);camera.lookAt(场景。位置);然后是渲染器:constrenderer=newTHREE.WebGLRenderer();renderer.setSize(width,height);document.body.appendChild(renderer.domElement);渲染器需要通过requestAnimationFrame逐帧渲染:functionrender(){renderer.render(scene,camera);requestAnimationFrame(render);}render();准备工作完成,接下来就是绘制两个3D对象星空和祝福字符,并实现粒子动画。绘制星空星空并不是立方体、圆柱体等规则的几何体,而是由一些随机的顶点组成的。这个任意几何是使用缓冲区几何BufferGeometry创建的。为什么把这种由任意顶点组成的几何体称为缓冲区几何体呢?因为顶点在被GPU渲染之前就放在bufferbuffer中,所以这种指定一堆顶点的几何图形被称为BufferGeometry。我们创建30000个随机顶点:constvertices=[];for(leti=0;i<30000;i++){constx=THREE.MathUtils.randFloatSpread(2000);consty=THREE.MathUtils.randFloatSpread(2000);constz=THREE。MathUtils.randFloatSpread(2000);vertices.push(x,y,z);}这里使用Three.js提供的工具MathUtils生成0到2000的随机值。然后用这些顶点创建一个BufferGeometry:constgeometry=newTHREE.BufferGeometry();geometry.setAttribute('position',newTHREE.Float32BufferAttribute(vertices,3));为BufferGeometry对象设置顶点位置,指定3个值(x,y,z)为一个坐标。然后在这些顶点上创建材质(Material),也就是星星的贴图:conststar=newTHREE.TextureLoader().load('img/star.png');constmaterial=newTHREE.PointsMaterial({size:10,map:星星});有了顶点和材质,就可以创建3D对象(这里的3D对象是Points)。constpoints=newTHREE.Points(几何,材料);场景。添加(点);看渲染效果:静态没有3D感,我们让每一帧旋转,改变渲染逻辑:functionrender(){renderer.render(scene,camera);scene.rotation.y+=0.001;requestAnimationFrame(render);}再来看看:3D星空的感觉!接下来我们来做粒子动画:3D粒子动画3D粒子动画是顶点的动画,也就是x,y,z的变化。我们先实现一个最简单的效果,让星星移动到0、0、0的位置:起点坐标就是星星原来的位置,可以通过getAttribute('position')获取。动画过程使用tween.js计算:conststartPositions=geometry.getAttribute('position');for(leti=0;i
