ThreeJS 粒子系统中, THREE.Points 是用来创建点的类, 也用来批量管理粒子, 基于几何体的顶点来渲染每个粒子. 这个类的构造函数有两个参数, geometry(几何体) 和 material(材质), 几何体参数用来设置粒子的位置坐标, 而材质参数用来设置粒子的外观. 下面利用 ThreeJS 的粒子系统来实现雪花飘落动画.
1. 寻找素材
1) 背景图片
选择一张雪景图片作为背景图
2) 雪花图片
为了让动画效果更好, 使用两种不同形状的雪花实现雪花飘落效果.
2. html 部分
网页中添加 canvas 画布所在的元素
<div id="snowBackground"></div>
3. JS 部分
1) 初始化渲染器, 场景, 摄像机
- var width = 550; // 画布的宽度
- var height = 366; // 画布的高度
- // 渲染器
- var renderer = new THREE.webGLRenderer({
- antialias:true
- });
- renderer.setSize(width, height);
- // 将 canvas 添加到指定元素
- var element = document.getElementById('snowBackground');
- element.appendChild(renderer.domElement);
- // 场景
- var scene = new THREE.Scene();
- // 正交投影摄像机
- var camera = new THREE.PerspectiveCamera(45, width/height, 2, 500);
- camera.position.set(0, 0, 40); // 摄像机位置
- // 照相机默认沿 z 轴负方向观察, 通过设置 lookAt 的位置可以改变观察的方向
- camera.lookAt(new THREE.Vector3(0, 0, 0));
- scene.add(camera);
2) 利用平面几何体添加背景
- // 平面几何体
- var planeGeometry = new THREE.PlaneBufferGeometry( width, height);
- planeGeometry.translate(0, 0, -400); // 平面几何体位置
- // 背景纹理
- var planeTexture = new THREE.TextureLoader().load('./snow_bg.jpg');
- // 背景材料
- var planeMaterial = new THREE.MeshBasicMaterial({
- map: planeTexture
- });
- // 背景网格
- var plane = new THREE.Mesh(planeGeometry, planeMaterial);
- // 将背景添加到场景
- scene.add(plane);
3) 利用 THREE.Points 增加雪花粒子
由于使用了两种雪花形状, 每一个形状需要创建一个 THREE.Points 对象
- var typeNum = 2; // 雪花种类
- var range = 50; // 雪花出现范围
- // 雪花纹理
- var texture = new THREE.TextureLoader().load('./snowflake.png');
- // 使用图片纹理材质
- var materials = [];
- for (var i = 0; i <typeNum; i++) {
- var material = new THREE.PointsMaterial({
- size: 2,
- map: texture, // 纹理
- transparent: true, // 透明
- opacity: 1, // 透明度
- depthTest: false, // 可以去掉 texture 的黑色背景
- blending: THREE.AdditiveBlending // 融合模式
- });
- material.map.offset = new THREE.Vector2(1/typeNum * i, 0);
- material.map.repeat = new THREE.Vector2(1/typeNum, 1);
- materials.push(material);
- }
- // 通过自定义几何体设置粒子位置
- var geoms = [];
- for (var k = 0; k < typeNum; k++) {
- var geom = new THREE.Geometry();
- for (var i = 0; i < 100; i++) {
- // 随机生成雪花的位置
- var v = new THREE.Vector3(
- Math.random() * range - range/2,
- Math.random() * range - range/2,
- Math.random() * range - range/2
- );
- // 随机生成雪花分别沿 x,y,z 轴方向移动速度
- v.velocityY = 0.1 + Math.random() / 5;
- v.velocityX = (Math.random() - 0.5) / 3;
- v.velocityZ = (Math.random() - 0.5) / 3;
- // 添加顶点
- geom.vertices.push(v);
- }
- geoms.push(geom);
- }
- // 点云
- var clouds = [];
- for (var i = 0; i < typeNum; i++) {
- var points = new THREE.Points(geoms[i], materials[i]);
- clouds.push(points)
- scene.add(points);
- }
4) 利用 requestAnimationFrame 实现动画
- (function animate () {
- clouds.forEach(function (points, i) {
- var vertices = points.geometry.vertices;
- vertices.forEach(function (v, idx) {
- // 计算位置
- v.y = v.y - (v.velocityY);
- v.x = v.x - (v.velocityX);
- v.z = v.z - (v.velocityZ);
- // 边界检查
- if (v.y <= -range/2) v.y = range / 2;
- if (v.x <= -range/2 || v.x>= range/2) v.x = v.x * -1;
- if (v.z <= -range/2 || v.z>= range/2) v.velocityZ = v.velocityZ * -1;
- });
- // 重要: 渲染时需要更新位置 (如果没有设为 true, 则无法显示动画)
- points.geometry.verticesNeedUpdate = true;
- });
- renderer.render(scene, camera);
- requestAnimationFrame(animate);
- })();
这里推荐一下我的前端学习交流圈: 784783012, 里面都是学习前端的从最基础的 HTML+CSS+JS[炫酷特效, 游戏, 插件封装, 设计模式] 到移动端 HTML5 的项目实战的学习资料都有整理, 送给每一位前端小伙伴. 最新技术, 与企业需求同步. 好友都在里面学习交流, 每天都会有大牛定时讲解前端技术!
点击: 加入 http://u6.gg/eUpjy
来源: http://www.qdfuns.com/article/51769/f4ece1adc4e1c9b5aa62ba085962a773.html