基于 three.js 的 3D 粒子动效实现

分享创造 · jack · Created at · Last by y8520599 Replied at · 97 hits
434 1549005614


作者:个推web前端开发工程师 梁神

一、背景

粒子特效是为模拟现实中的水、火、雾、气等效果由各种三维软件开发的制作模块,原理是将无数的单个粒子组合使其呈现出固定形态,借由控制器、脚本来控制其整体或单个的运动,模拟出现真实的效果。three.js是用JavaScript编写的WebGL的第三方库,three.js提供了丰富的API帮助我们去实现3D动效,本文主要介绍如何使用three.js实现粒子过渡效果,以及基本的鼠标交互操作。(注:本文使用的关于three.js的API都是基于版本r98的。)

二、实现步骤

1. 创建渲染场景scene

scene实际上相当于一个三维空间,用于承载和显示我们所定义的一切,包括相机、物体、灯光等。在实际开发时为了方便观察可添加一些辅助工具,比如网格、坐标轴等。

scene = new THREE.Scene();
 scene.fog = new THREE.Fog(0x05050c, 10, 60);
 scene.add( new THREE.GridHelper( 2000, 1 ) ); // 添加网格

2. 添加照相机camera

THREE里面实现了几种相机:PerspectiveCamera(透视相机)、 OrthographicCamera(正交投影相机)、CubeCamera(立方体相机或全景相机)和 StereoCamera(3D相机)。本文介绍我们主要用到的 PerspectiveCamera(透视相机):

视觉效果是近大远小。

配置参数 PerspectiveCamera(fov, aspect, near, far)。

fov:相机的可视角度。

aspect:相机可视范围的长宽比。

near:相对于深度剪切面的远的距离。

far:相对于深度剪切面的远的距离。

camera = new THREE.PerspectiveCamera(45, window.innerWidth /window.innerHeight, 5, 100);
   camera.position.set(10, -10, -40);
   scene.add(camera);

3. 添加场景渲染需要的灯光

three.js里面实现的光源:AmbientLight(环境光)、DirectionalLight(平行光)、HemisphereLight(半球光)、PointLight(点光源)、RectAreaLight(平面光源)、SpotLight(聚光灯)等。配置光源参数时需要注意颜色的叠加效果,如环境光的颜色会直接作用于物体的当前颜色。各种光源的配置参数有些区别,下面是本文案例中会用到的二种光源。

let ambientLight = new THREE.AmbientLight(0x000000, 0.4);
   scene.add(ambientLight);
   let pointLight = new THREE.PointLight(0xe42107);
   pointLight.castShadow = true;
   pointLight.position.set(-10, -5, -10);
   pointLight.distance = 20;
   scene.add(pointLight);

4. 创建、导出并加载模型文件loader

创建模型,可以使用three.js editor进行创建或者用three.js的基础模型生成类进行生成,相对复杂的或者比较特殊的模型需要使用建模工具进行创建(c4d、3dmax等)。

使用three.js editor进行创建,可添加基本几何体,调整几何体的各种参数(位置、颜色、材质等)。


使用模型类生成。

let geometryCube = new THREE.BoxBufferGeometry( 1, 1, 1 );
   let materialCube = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
   let cubeMesh = new THREE.Mesh( geometryCube, materialCube );
   scene.add( cubeMesh );

导出需要的模型文件(此处使用的是 obj格式的模型文件)。

加载并解析模型文件数据。

let onProgress = function (xhr) {
       if (xhr.lengthComputable) {
           // 可进行计算得知模型加载进度
       }
   };
   let onError = function () {};
   particleSystem = new THREE.Group();
   var texture = new THREE.TextureLoader().load('./point.png');
   new THREE.OBJLoader().load('./model.obj', function (object) {
       // object 模型文件数据
   }, onProgress, onError);

5. 将导入到模型文件转换成粒子系统Points

获取模型的坐标值。

拷贝粒子坐标值到新建属性position1上 ,这个作为粒子过渡效果的最终坐标位置。

给粒子系统添加随机三维坐标值position,目的是把每个粒子位置打乱,设定起始位置。

let color = new THREE.Color('#ffffff');
   let material = new THREE.PointsMaterial({
       size: 0.2,
       map: texture,
       depthTest: false,
       transparent: true
   });
    particleSystem= new THREE.Group();
   let allCount = 0
   for (let i = 0; i < object.children.length; i++) {
       let name = object.children[i].name
       let _attributes = object.children[i].geometry.attributes
           let count = _attributes.position.count
           _attributes.positionEnd = _attributes.position.clone()
           _attributes.position1 = _attributes.position.clone()
           for (let i = 0; i < count * 3; i++) {
                _attributes.position1.array[i]= Math.random() * 100 - 50
           }
           let particles = new THREE.Points(object.children[i].geometry, material)
           particleSystem.add(particles)
           allCount += count
    }
   particleSystem.applyMatrix(new THREE.Matrix4().makeTranslation(-5, -5,-10));

6. 通过tween动画库实现粒子坐标从position到position1点转换

利用 TWEEN 的缓动算法计算出各个粒子每一次变化的坐标位置,从初始位置到结束位置时间设置为2s(可自定义),每次执行计算之后都需要将attributes的position属性设置为true,用来提醒场景需要更新,在下次渲染时,render会使用最新计算的值进行渲染。

let pos = {
       val: 1
   };
   tween = new TWEEN.Tween(pos).to({
       val: 0
   }, 2500).easing(TWEEN.Easing.Quadratic.InOut).onUpdate(callback);
   tween.onComplete(function () {
       console.log('过渡完成complete')
   })
   tween.start();
   function callback() {
       let val = this.val;
       let particles = particleSystem.children;
       for (let i = 0; i < particles.length; i++) {
           let _attributes = particles[i].geometry.attributes
           let name = particles[i].name
           if (name.indexOf('_') === -1) {
                let positionEnd =_attributes.positionEnd.array
                let position1 =_attributes.position1.array
                let count =_attributes.position.count
                for (let j = 0; j < count *3; j++) {
                    _attributes.position.array[j] = position1[j] *val + positionEnd[j] * (1 - val)
                }
           }
           _attributes.position.needsUpdate = true // 设置更新
       }
    }

7. 添加渲染场景render

创建容器。

定义render渲染器,设置各个参数。

将渲染器添加到容器里。

自定义的渲染函数 render,在渲染函数里面我们利用 TWEEN.update 去更新模型的状态。

调用自定义的循环动画执行函数 animate,利用requestAnimationFrame方法进行逐帧渲染。

let container = document.createElement('div');
    document.body.appendChild(container);
   renderer = new THREE.WebGLRenderer({
       antialias: true,
       alpha: true
   });
   renderer.setPixelRatio(window.devicePixelRatio);
   renderer.setClearColor(scene.fog.color);
    renderer.setClearAlpha(0.8);
   renderer.setSize(window.innerWidth, window.innerHeight);
   container.appendChild(renderer.domElement); // 添加webgl渲染器

   function render() {
       particleSystem.rotation.y += 0.0001;
       TWEEN.update();
       particleSystem.rotation.y += (mouseX + camera.rotation.x) * .00001;
       camera.lookAt(new THREE.Vector3(-10, -5, -10))
       controls.update();
       renderer.render(scene, camera);
    }
   function animate() { // 开始循环执行渲染动画
       requestAnimationFrame(animate);
       render();
    }

8. 添加鼠标操作事件实现角度控制

我们还可以添加鼠标操作事件实现角度控制,其中winX、winY分别为window的宽高的一半,当然具体的坐标位置可以根据自己的需求进行计算,具体的效果如下图所示。


document.addEventListener('mousemove', onDocumentMouseMove, false);
   function onDocumentMouseMove(event) {
       mouseX = (event.clientX - winX) / 2;
       mouseY = (event.clientY - winY) / 2;
    }

三、优化方案

1. 减少粒子数量

随着粒子数量的增加,需要的计算每个粒子的位置和大小将会非常耗时,可能会造成动画卡顿或出现页面假死的情况,所以我们在建立模型时可尽量减少粒子的数量,能够有效提升性能。

在以上示例中,我们改变导出模型的精细程度,可以得到不同数量的粒子系统,当粒子数量达到几十万甚至几百万的时候,在动画加载时可以感受到明显的卡顿现象,这主要是由于fps比较低,具体的对比效果如下图所示,左边粒子数量为30万,右边粒子数量为6万,可以明显看出左边跳帧明显,右边基本保持比较流畅的状态。

2. 采用GPU渲染方式

编写片元着色器代码,利用webgl可以为canvas提供硬件3D加速,浏览器可以更流畅地渲染页面。目前大多数设备都已经支持该方式,需要注意的是在低端的设备上由于硬件设备原因,渲染的速度可能不及基于cpu计算的方式渲染。

四、总结

综上所述,实现粒子动效的关键在于计算、维护每个粒子的位置状态,而three.js提供了较为便利的方法,可以用于渲染整个粒子场景。当粒子数量极为庞大时,想要实现较为流畅的动画效果需要注意优化代码、减少计算等,也可以通过提升硬件配置来达到效果。本文中的案例为大家展示了3D粒子动效如何实现,大家可以根据自己的实际需求去制作更炫酷的动态效果。

共收到 1 条回复
7689 1554726947
y8520599 · #1 ·

台北外送茶賴8520599台北外約茶莊無套茶莊外約學生妹處女幼齒嫩妹18歲台北叫小姐台北一夜情無套茶選妃論壇:http://www.pp09520.com/forum.php
台北新北新竹台中彰化台南高雄約無套處女巨乳奶水人妻敢玩肛交中出+賴8520599買3送1送半價

營業時間:為早上10:00至凌晨02:00
外送地區:台北/新北/林口/新竹/台中/南投/彰化/高雄/台南
@.約旅館旅館(自選)避免惹麻煩回家~安全隱私
@.全套服務(特別服務可喬)
@.看照約妹~自己看到妹妹滿意現金消費維護客人消費權利~可打槍換人
交易方式:不刷卡~不轉帳~不買點數~一律現金~無定金 ~
約會地點:住家~飯店~汽旅~外約~商旅~酒店
PS.偏遠地區需加兩百-四百車資不等;給大家帶來不便請諒^^
加入全台灣外送茶賴8520599帳號即可享受2000現金優惠唷^^
妹妹類型:學生-護士-空姐-設計師-調酒師-夜店正妹-幼教老師
T臺麻豆-鋼管舞辣妹-跑pub正妹-【台灣本土各行各業正妹兼職】
特別類型:中(日.巴.荷.韓.俄)混血/空姐/麻豆/二線/三線藝人······

水蜜桃茶坊論壇更新咯:www.pp09520.com
點擊論壇註冊回覆可看更多MM諮詢
學生妹–3p正妹網站:http://skdskjdsjhskjd.blogspot.com
無套口爆肛交敢玩巨乳正妹網址:http://5201314ht511.blogspot.com
北中南正妹網址:http://dfdajfkdjjf.blogspot.com

好消息 報班一批無套正妹(送絲襪或2次半價)賴8520599
3.5K 卡卡 160 23 E 無套吹 舌吻 【台中】
3.5K 曉月 161 21 C 無套吹 69 可3P 【高雄】
3.5K 雨欣 160 22 D 無套吹 69 口爆 【彰化】
3K 小隻 158 23 D 無套吹 69 【高雄】
4.5K 漫珍 164 22 D 無套做 69 舌吻 【高雄】
6K 蜜雪兒162 23 D 無套吹 LG 可3P 【台中】
4.5K 小可 165 25 D 無套做 舌吻 【台北】
5K 艾雲 168 22 D 無套吹 深喉嚨 69【台中】
4K 靈兒 155 23 c 無套吹 69 KISS 【高雄】
3.5K 可兒 170 23 C 無套吹 殘廢澡 69【彰化】
8K 琪琪 166 19 E 無套吹 奶砲 【台北】
3.5K 蜜語 168 23 C 無套吹 可3P 【台中】
3.5K 小小 163 24 D 無套做 69 口爆 【台南】
5K 漫漫 165 21 D 無套吹 69 口爆 【新竹】

本週主推三位獨家王牌正妹 ’

“大奶系列”(都可折扣2000) 賴8520599/SKype:bjai699
1號:喲西 162 E 22 47 性感火辣 前凸后?
2號:舒拉 156 D 19 45 可?小隻馬 喜?露奶
3號:菲娜 164 F 23 48 大奶 可舔 可揉 乳交
4號:尼西 161 H 25 51 外貌協會性感火辣
5號:XiXi 163 G 24 48 爆乳中泰混血兒

“無套淫蕩尺度大系列”(都可折扣2000) 賴8520599/SKype:bjai699
1號:瑞兒 160 E 24 49 淫蕩爆乳健身教練
2號:曉梓 159 34E 23 49 性感火辣爆乳麻辣教師
3號:莫妮卡 160 D 24 49 氣質美腿淫蕩秘書
4號:阿妹 159 E 25 49 淫蕩風騷奶水人妻
5號:心琪 165 F 49 肚皮舞教練妖嬈火辣

“小隻馬系列”(都可折扣2000) 賴8520599/SKype:bjai699
1號:奶昔 156 C 18 45 可愛清純超級甜美
2號:琳達 158 D 21 48 電眼性感好像棉花糖一樣
3號:鹿鹿 157 B+ 19 46 眉清目秀幼齒學生妹
4號:可兒 160 C 22 48 外貌協會性感火辣
5號:邵婷 159 E 19 48 中泰混血兒性感火辣

“火辣妖嬈風系列”(都可折扣2000) 賴8520599/SKype:bjai699
1號:如如 163 34E 23 49 夜店女王稱霸全場
2號:倩倩 162 E 21 49 性感火辣外貌學生
3號:兔兔 165 D 21 49外貌協會性感嫩模特
4號:蓮心 159 E 24 49 氣質性感火辣美容師
5號:筆筆 160 D+ 21 49 氣質女主播
………………………………………………….
[成為新星VIP的15大好康]

1.可享受每次約妹八折優待
2.論壇看照無需回覆
3.外國妹 韓國 日本 歐美 混血等
4.需要加車資地方一律免車資
5.享受各種特殊服務的妹妹
6.看影片選妹妹
7.優質選妃 一次性過去三個
8.加節可直接折扣2-3K
9.可約住家 外約 賴8520599/SKype:bjai699
10.可享受多P服務 3P-5P
11.優先得知優惠諮詢
12.每月都可抽獎一次
13.想要無套妹妹無需加錢 賴8520599/SKype:bjai699
14.可讓妹妹陪吃飯 逛街等 事先講
15.1000以下旅館費用可抵押

OL=讓你嘗試老闆與秘書的魚水之歡
人妻=別人的老婆總是比自家的好 賴8520599/SKype:bjai699
護士=總覺得護士的淫蕩無人能比
小三=永遠的狐狸精的魅力無人能比
幼教=溫柔體貼的服務讓你舒舒服服 賴8520599/SKype:bjai699
空姐=征服高貴氣質的空姐是一種驕傲
麻豆=讓你爆發獅子的性能力讓她為你服務 賴8520599/SKype:bjai699
學生=體驗回歸到年輕校園時的情竇初開電玩美女=讓你回歸到古代的怡紅院
你想要都會用心安排喔.讓各位茶友們滿意.享受更多優質服務

全台灣外送茶活動大優惠: 賴8520599/SKype:bjai699
選妃網站:http://www.pp09520.com
1.消費一次不管金額大小免房費 免車資 送絲襪
2.消費金額5k送絲襪+免車資+3000優惠卷+9折會員卡
3.消費金額8k送絲襪+原味內褲消費第二節直接半價
3.消費金額10k送超級VIP(永久7折)免費試車10k小模+免費進入約炮群
4.消費金額15k送黃金VIP(永久半價)免費試車15k小模2小時無線次數

【包夜套餐】 賴8520599/SKype:bjai699
1.買六節【6小時-免費送2H】送3000抵用卷
2.買九節【9小時-免費送3H】送5000抵用卷+半價*2
3.買十二節【12小時-免費送4H】+永久半價+黃金VIP

【加時套餐】 賴8520599/SKype:bjai699
1.兩節送一節/兩節送兩節/三節送一節/三節送兩節
2.喝茶續杯半價 賴8520599/SKype:bjai699
3.還可約姐妹花母女雙胞胎3P妹妹喲
【北中南套餐都可以挑選,詳情諮詢我喲】

全台灣台北外送茶瀨 賴8520599/SKype:bjai699大台北外送茶 新北外送茶 林口龜山外送茶 松山外送茶 土城外送茶 新莊外送茶 板橋外送茶 西門町一夜情 三重外送茶 台灣吃魚喝茶論壇魚訊論壇茶訊論壇 外約茶莊本土妹妹短期兼職下海 現金消費 不買點數 不轉賬 無定金 一律現金消費 正妹選妃論壇:http://www.pp09520.com/forum.php 台中外送茶瀨 賴8520599/SKype:bjai699彰化外送茶 南投外送茶 高雄外送茶 台南外送茶 楠梓外送茶 正妹選妃論壇:http://www.pp09520.com/forum.php 大台北叫小姐 台北援交妹 新北叫小姐 台北一夜情 新北一夜情 台中找小姐台中一夜情 彰化一夜情彰化找小姐 台南找小姐台南一夜情 高雄找小姐高雄一夜情 正妹選妃論壇:http://www.pp09520.com/forum.phpS性愛服務:口交愛愛按摩殘廢澡無套BJ全程無套愛愛肛交中出口爆內射毒龍吞精一條龍服務全套 旅館愛愛方便隱私出差洽公贊 正妹選妃論壇:http://www.pp09520.com/forum.php 外約學生妹爆乳處女 外約單親媽媽奶水人妻 空姐麻豆車展藝人 預防詐騙手段吃魚喝茶論壇 加賴8520599即可看主頁無碼真人自慰 可以視訊選妹還有處女 嬌點外送美眉各大旅館飯店舒壓 外送茶終極攻略全台外送茶推薦!茶莊、價格、外約、到府 … – 援交、魚訊 百媚外約|外送茶-叫小姐-全套服務 平價 – 台中外送茶 台中外約彙整- 遇見LIVE外送茶莊-優質外約 台中約炮彙整- 遇見LIVE外送茶莊-優質外約 洪爺外送茶-洪爺porn 台北台中新竹外送茶坊茶莊推薦~援-交LINE茶訊 外送茶流程 男人頂天立地 就是要舒壓解氣 | 加LINE:8520599 全新CK嚴選 | 優質茶莊 定點0外送茶0紓壓? LOVERS外約網 | 任君挑選? 頂級外送茶、定點樓鳳外約 啪啪Call 外約 外送茶 美人魚性福茶莊-外送茶-叫小姐 外送茶坊推薦 – line茶訊 新竹叫茶【紫萱】清純學生妹 – 台中外送茶 『94愛G8』優質外約外送茶- | 約炮-叫小姐-全套-給你性福的夜晚,外約地區 全新CK嚴選 | 優質茶莊 定點0外送茶0紓壓? 台南美女外送茶白皙正妹和來台灣學中文的精壯大屌黑人無套做愛自拍 …留言板/ 正妹選妃論壇:http://www.pp09520.com/forum.php大臺灣狐狸頂級外送茶留言板 LOVERS外約網 | 任君挑選 | 全方位服務瀨8520599 男人頂天立地 就是要舒壓解氣 | 加LINE:8520599 舒壓 益智遊戲- 遊戲天堂 女生遊戲- 遊戲天堂 遊戲世界正妹選妃:http://www.pp09520.com/forum.php Facebook遊戲論壇:: :: 遊戲基地gamebase 巴哈姆特電玩資訊站 魔方手機遊戲論壇-手機遊戲玩家分享八卦討論區- 多玩游瀨8520599 多玩游 ,多交朋友! – 正妹選妃論壇:http://www.pp09520.com/forum.php成人園地≡ – SOGO論壇 中文色情,成人,自拍,偷拍,正妹選妃論壇:http://www.pp09520.com/forum.php 情色網站大全- 成人网站- 色情网 4U 成人論壇- 華人最大情色娛樂討論區- 成人貼圖中心-深夜區-瀨8520599 卡提諾論壇-CK101.COM 成人分享(未滿18歲請勿進入)正妹選妃論壇:http://www.pp09520.com/forum.php – 大眾論壇HK-PUB Forum – 港澳台人氣討論 色情瀨8520599 – 主頁| Facebook 極度震撼色情論壇 – Xuite日誌正妹選妃論壇:http://www.pp09520.com/forum.php – 隨意窩 141JJ成人網站導航、色情網站導航、福利導航 141JJ成人網站導航、色情網站導航、福利導航- 采精小蝴蝶11部合集04 ChinaLove?是優質約會交友網站 |正妹選妃論壇:http://www.pp09520.com/forum.php 八百萬多成員,全國找尋男女朋友 交友討論 – J2h論壇正妹選妃論壇:http://www.pp09520.com/forum.php line交友論壇相關網站 – 背包客棧 全台灣台北外送茶瀨8520599 台北外約茶莊無套茶莊外約空姐台灣本土妹短期兼職下海一律現金消費旅館愛愛爆乳奶水人妻無套內射肛交中出口爆吞精外約學生妹處女洋妞台北外送茶台中外約學生妹高雄外送茶 選妃論壇:http://www.pp09520.com/forum.php 吃魚喝茶論壇魚訊論壇茶訊論壇 賴8520599/SKype:bjai699

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up