nba小熊

admin · 2009-08-01

  

  粒子动画 这个词专家恐怕时时听到,那甚么是粒子动画呢?

  粒子是指原子、份子等构成物体的最小单元。正在 2D 中,这类最小单元是像素,正在 3D 中,最小单元是极点。

  粒子动画不是指物体自己的动画,而是指这些根基单元的动画。由于是构成物体的单元的动画,以是会有打坏重组的成效。

  本文咱们就来研习下 3D 的粒子动画,做一个群星送福的成效:

  图片思绪分解

  3D 宇宙中,物体是由极点组成,3 个极点组成一个三角形,而后给三角形贴上分别的纹理,云云便是一个三维模子。

  

  也便是说,3D 模子是由极点肯定的众少体(Geometry),贴上分别的纹理(Material)所组成的物体(Mesh 等)。

  以后,把 3D 物体增添参预景(Scene)中,筑设一个相机(Camera)角度去视察,而后用陪衬器(Renderer)一帧帧陪衬出来,这便是 3D 陪衬流程。

  3D 物体是由极点组成,那让这些极点动起来便是粒子动画了,由于根基粒子动了,天然就会有打坏重组的成效。

  正在群星送福成效中,咱们由群星打坏重构成了福字,现实上便是群星的极点活动到了福字的极点,由一个 3D 物体变为了另一个 3D 物体。

  那末群星的极点从那边来的?福字的极点又若何来呢?

  群星的极点实在是随机天生的分别位子的点,正在这些点上贴上星星的贴图,便是群星成效。

  福字的极点是加载的一个 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,width/height,0.1,1000);

 

  相机分为透视相机平安行相机,咱们这里用的透视相机,也便是近大远小的透视成效。要指定可能看到的视线角度(45)、宽高比(width/height)、遐迩限制(0.1 到 1000)这 3 种参数。

  调解下相机的位子和视察宗旨:

  

camera.position.set(100,0,400);camera.lookAt(scene.position);

 

  而后是陪衬器:

  

constrenderer=newTHREE.WebGLRenderer();renderer.setSize(width,height);document.body.appendChild(renderer.domElement);

 

  陪衬器要经由过程 requestAnimationFrame 来一帧帧的陪衬:

  

functionrender(){renderer.render(scene,camera);requestAnimationFrame(render);}render();

 

  盘算劳动告终,接上去便是绘制星空、福字这两种 3D 物体,再有杀青粒子动画了。

   绘制星空

  星空不是正方体、圆柱体这类划定规矩的众少体,而是由少许随机的极点组成的,这类随意的众少体操纵缓冲众少体 BufferGeometry 创筑。

  为啥这类由随意极点组成的众少体叫缓冲众少体呢?

  由于极点正在被 GPU 陪衬以前是放正在缓冲区 buffer 中的,以是这类指定一堆极点的众少体就被叫做 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:star});

 

  极点有了,材质有了,便可能创筑 3D 物体了(这里的 3D 物体是 Points)。

  

constpoints=newTHREE.Points(geometry,material);scene.add(points);

 

  看下陪衬的成效:

  

  静态的没 3D 的感触,咱们让每一帧转一下,改下 render 逻辑:

  

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<startPositions.count;i++){consttween=newTWEEN.Tween(positions);tween.to({[i*3]:0,[i*3+1]:0,[i*3+2]:0},3000*Math.random());tween.easing(TWEEN.Easing.Exponential.In);tween.delay(3000);tween.onUpdate(()=>{startPositions.needsUpdate=true;});tween.start();}

 

  每一个点都有 x、y、z 坐标,也便是下标为 i三、i3+1、i*3+2 的值,咱们指定从群星的肇始位子活动到 0,0,0 的位子。

  而后指定了时候函数为加快(Easing.Exponential.In),3000 ms 后初阶推广动画。

  每一帧陪衬的时刻要挪用下 Tween.update 来筹算最新的值:

  

functionrender(){TWEEN.update();renderer.render(scene,camera);scene.rotation.y+=0.001;requestAnimationFrame(render);}

 

  每一帧正在绘制的时刻都市挪用 onUpdate 的回调函数,咱们正在回调函数里把 positions 的 needsUpdate 筑设为 true,便是报告 tween.js 正在这一帧要更新为新的数值再陪衬了。

  第一个粒子动画告终!

  来看下成效(我把这个成效叫做万象天引):

  

  总共的星星粒子都聚合到了一个点,这便是粒子动画典范的打坏重组感。

  接上去,只须把粒子活动到福字的极点便是咱们要做的群星送福成效了。

  福字模子的极点断定不行随机,自身画也不实际,这类日常都是正在筑模软件里画好,而后导入到 Three.js 来陪衬,

  我找了云云一个福字的 3D 模子:

  

  模子是 fbx 样子的,操纵 FBXLoader 加载:

  

constloader=newTHREE.FBXLoader();loader.load(./obj/fu.fbx,function(object){constdestPosition=object.children[0].geometry.getAttribute(position);});

 

  回调参数便是从 fbx 模子加载的 3D 物体,它是一个 Group(众个 3D 物体的集结),掏出第 0 个元素的 geometry 属性,便是对应的众少体。

  云云,咱们就拿到了目的的极点位子。

  把粒子动画的闭幕位子改为福字的极点便可能了:

  

constcur=i%destPosition.count;tween.to({[i*3]:destPosition.array[cur*3],[i*3+1]:destPosition.array[(cur*3+1)],[i*3+2]:destPosition.array[(cur*3+2)]},3000*Math.random());

 

  倘使初阶极点位子较量众,逾越的部份从 0 的位子再来,以是要取余。

  大功成功!

  这便是咱们思要的粒子成效:

  图片

  完备代码上传到了 github:https://github.com/QuarkGluonPlasma/threejs-exercize

   总结

  粒子动画是构成物体的根基单元的活动,对 3D 来讲便是极点的活动。

  咱们要杀青群星送福的粒子动画,也便是从群星的极点活动到福字的极点。

  群星的极点可能随机天生,操纵 BufferGeometry 创筑对应的众少体。福字则是加载创筑好的 3D 模子,拿到此中的极点位子。

  有了初阶、闭幕位子,便可能杀青粒子动画了,过程当中的 x、y、z 值操纵动画库 Tween.js 来筹算,可能指定加快、加速等时候函数。

  粒子动画有种打坏重组的感触,可能用来做少许很炫的成效。剖析了甚么是粒子动画、粒子动画中动的是甚么,就算是发端把握了。

  我摘下漫天繁星,给专家送一份福分,新的一年一同加油!

文章推荐:

nba2k18传奇版

cba2k巨星时刻

nba2k11没声音

大赢家篮球比分