上面说过,《你的性格主导色》活动中我最感兴趣的部分是通过Three.js实现穿越云层的动效。据作者介绍,每朵云的位置是随机出现的,效果很好,下图是我实现的版本。网上Demo先说说实现穿云动态效果的基本思路:把一堆64*64的平面图形沿Z轴均匀放置,这些平面的X、Y坐标是随机的(很像下图中的桶装土豆切片)把上面的所有图形合并成一个大图形,将大图形和贴片材质(云)生成一个网格,并将网格放到场景中。动态效果就是从远处沿着Z轴慢慢移动相机,就像会有穿过云层的效果。首先,官方文档提供了创建场景的快速入门。阅读后,您可以更好地理解以下内容。下面介绍Three.js中的基本概念。仅供我新手理解。如果大家有好的文档或者分享,请帮忙指路。Scene场景是一个空间,用来存放我们要渲染的内容。最简单的用法就是场景可以添加一个网格,然后渲染它。//初始化场景varscene=newTHREE.Scene();//其他代码...//添加对象到场景scene.add(mesh);//渲染场景renderer.render(scene,camera);这里说的是下一个场景的坐标规则:原点是画布的平面中心,Z轴垂直于X、Y轴,正向朝向我们。我这里把Z轴线旋转了,不然我们看不到,如下图:代码:constscene=newTHREE.Scene();varcamera=newTHREE.PerspectiveCamera(70,window.innerWidth/window.innerHeight,1,1000);camera.position.set(0,0,100);constrenderer=newTHREE.WebGLRenderer();renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);//线段1,红色,从原点到X轴40constpoints=[];points.push(newTHREE.Vector3(0,0,0));points.push(newTHREE.Vector3(40,0,0));constgeometry1=newTHREE.BufferGeometry()。setFromPoints(points);varmaterial1=newTHREE.LineBasicMaterial({color:'red'});varline1=newTHREE.Line(geometry1,material1);//线段2,蓝色,从原点到Y轴40points.length=0;points.push(newTHREE.Vector3(0,0,0));points.push(newTHREE.Vector3(0,40,0));constgeometry2=newTHREE.BufferGeometry()。硒tFromPoints(points);varmaterial2=newTHREE.LineBasicMaterial({color:'blue'});varline2=newTHREE.Line(geometry2,material2);//线段3,绿色,从原点到Z轴40分。length=0;points.push(newTHREE.Vector3(0,0,0));points.push(newTHREE.Vector3(0,0,40));constgeometry3=newTHREE.BufferGeometry().setFromPoints(点);varmaterial3=newTHREE.LineBasicMaterial({color:'green'});varline3=newTHREE.Line(geometry3,material3);//做一个旋转,否则看不到Z轴上的直线line3.rotateX(Math.PI/8);line3.rotateY(-Math.PI/8);scene.add(line1,line2,line3);renderer.render(场景,相机);相机场景中的物体想要成为我们所看到的,即渲染,就需要相机“看到”。通过上面的坐标系图,我们知道,同一个物体,用不同的相机观察角度,肯定会呈现出不同的画面。最常用的是这里使用的一种。透视相机可以穿透物体,这里用它来穿透云层,效果出众。//初始化相机camera=newTHREE.PerspectiveCamera(70,pageWidth/pageHeight,1,1000);//最后场景和相机一起渲染,我们可以看到场景中的物体renderer.render(scene,相机);材质材质很好理解。在初始示例中,MeshBasicMaterial用于为立方体添加颜色。材质的使用方法是将材质和图形一起生成网格。这里我们使用了更复杂的纹理材质。//纹理材质constmaterial=newTHREE.ShaderMaterial({//这里的值是传递给着色器的制服:{map:{type:'t',value:texture},fogColor:{type:'c',值:fog.color},fogNear:{类型:'f',值:fog.near},fogFar:{类型:'f',值:fog.far}},vertexShader:vShader,fragmentShader:fShader,透明:真的});图形和网格Three.js默认提供了很多几何图形,即各种Geometry,它们的基类是BufferGeometry。图形是可以合并的,像这里就是克隆很多同一个平面的图形,通过修改它们各自的位置,产生合并后形成大云朵的效果。一开始以为图形和网格是一个概念,后来才知道材质和图形可以生成网格,网格可以放到场景中。//使用上面合并的形状和材质生成一个网格mesh=newTHREE.Mesh(mergedGeometry,material);将场景和相机渲染到目标元素,并生成画布。如果是静态场景,那么渲染就完成了。但是如果是移动场景,这里就需要使用一个原生函数requestAnimationFrame。函数动画(){requestAnimationFrame(动画);renderer.render(scene,camera);}上面的代码是一个渲染循环,一般屏幕上的频率是60HZ,在高刷新屏幕上刷新率会提高,也就是会给用户很好的刷新经验,我们不需要自己使用setInterval来控制。并且当用户切换到其他标签时,会暂停刷新,既不会浪费用户宝贵的处理器资源,也不会消耗电池寿命。揭秘的过程其实很有趣也很曲折。《你的性格主导色》事件的前端代码我捡了起来,但是里面有很多云的动效相关的代码被压缩了,看不懂。该怎么办?然后去three.js找官方的例子。找了半天,只找到一个像下图这样的:经过各种搜索,终于在three.js的讨论区找到了这个穿云特效,也就是三。js作者很久以前写的例子。拿到云动画效果的源码后,对比了一下感觉imyzf也应该借鉴一下这个例子。发现源码中three.js的版本有点落后。源码里的版本是55,最新的是131,版本差距有点大。上面的一些类和API都没有了。下面介绍不同的部分:三.Geometry首先,这个类在最新版本中已经没有了。该类用于将多个平面图形组合成一个图形。观察下面的代码,55版本先生成一个Geometry,然后生成一个平面网格,调整网格的坐标,将网格与Geometry合并(我不明白图形是如何与网格合并的,而且是同一个网格,我猜合并时生成了一个新的网格)。//初始化一个基本图形geometry=newTHREE.Geometry();//初始化一个64*64平面varplane=newTHREE.Mesh(newTHREE.PlaneGeometry(64,64));for(vari=0;i<8000;i++){//调整平面图案的位置和旋转角度等plane.position.x=Math.random()*1000-500;plane.position.y=-Math.random()*数学。随机()*200-15;平面.position.z=i;plane.rotation.z=Math.random()*Math.PI;plane.scale.x=plane.scale.y=Math.random()*Math.random()*1.5+0.5;//平面合并到基础图形THREE.GeometryUtils.merge(geometry,plane);}查询最新文档发现所有图形的基类BufferGeometry都提供了clone方法,平面图形自然可用被克隆出来了。//平面形状constgeometry=newTHREE.PlaneGeometry(64,64);常量几何=[];for(vari=0;i
