Three.JS 粒子系統實現雪花飄落動畫花飄落動畫

ThreeJS 粒子系統中,THREE.Points是用來創建點的類,也用來批量管理粒子,基於幾何體的頂點來渲染每個粒子。這個類的構造函數有兩個參數,geometry(幾何體)和material(材質),幾何體參數用來設置粒子的位置座標,而材質參數用來設置粒子的外觀。下面利用ThreeJS的粒子系統來實現雪花飄落動畫。

1. 尋找素材

1) 背景圖片

選擇一張雪景圖片作為背景圖

Three.JS 粒子系統實現雪花飄落動畫花飄落動畫

2) 雪花圖片

為了讓動畫效果更好,使用兩種不同形狀的雪花實現雪花飄落效果。

Three.JS 粒子系統實現雪花飄落動畫花飄落動畫

2. HTML部分

網頁中添加canvas畫布所在的元素


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);
})();

十五年編程經驗,今年1月整理了一批2019年最新WEB前端教學視頻,不論是零基礎想要學習前端還是學完在工作想要提升自己,這些資料都會給你帶來幫助,從HTML到各種框架,幫助所有想要學好前端的同學,學習規劃、學習路線、學習資料、問題解答。只要關注我的頭條號,後臺私信我【前端】兩個字,即可免費獲取。


分享到:


相關文章: