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

分享创造 · jack · Created at · Last by nini9595 Replied at · 335 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粒子动效如何实现,大家可以根据自己的实际需求去制作更炫酷的动态效果。

共收到 3 条回复
1Floor Deleted
2Floor Deleted
7842 1560847929
nini9595 · #3 ·

[size=4]#超級紅牌報班嚕!
#現在可約  
#也接受預約
長腿辣媽今日返臺
想要多跟幾個男人做愛
D奶翹臀想玩強姦 跟想當你的小母狗

無套內射(需要提前講不講就做帶套)
後門進入(尺寸過大不配合)
口爆吞精(味道很重不配合)
奶泡(可抓奶頭上下摩擦)
跟你不只是床上 沙發 地上都可以
你要的都配合 還有你想不到的也都給你
你也不要吝嗇把你的精子全部給他吧
楊錢錢 167.D.27歲[/size]

140608dbrvrz7l7xl1nrxn.jpg.thumb

[size=4]甜美小女孩的胸部真不小~ 
繁星 160cm Dcup 20歲 45kg 
童顏巨乳 超級悶騷 床上超好會搖 
她說喜歡濕濕的插進去 
喜歡吃“乳液”喜歡撒嬌 
易出水會潮吹的小妹妹 短期兼職 想被幹“壞掉
#如果VIP約住家 大廳 廚房 浴室 床上都可以配合哦[/size]

![143646e0zvvg3dtv06sq08.jpg.thumb](https://sugobbs.ccddnn.net/forum/201906/16/143646e0zvvg3dtv06sq08.jpg.thumb.jpg?ohI)

![143649pwqwwg57r5egxyyz.jpg.thumb](https://sugobbs.ccddnn.net/forum/201906/16/143649pwqwwg57r5egxyyz.jpg.thumb.jpg?ohI)

![143656j8vsrweepv4xsfxg.jpg.thumb](https://sugobbs.ccddnn.net/forum/201906/16/143656j8vsrweepv4xsfxg.jpg.thumb.jpg?ohI)

![143653l088q3u3v0wgvanq.jpg.thumb](https://sugobbs.ccddnn.net/forum/201906/16/143653l088q3u3v0wgvanq.jpg.thumb.jpg?ohI)

[size=4]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
小星星優質外送茶聯絡方式:【籟nini9595】【Skype:bjx778】
【Kakao:5280888】【Telegram:nini9595】【官網:http://www.5280344.com】
★*消費價格:北部4.5K起跳 中部3k起跳 南部3k起跳 
★*外送地點:旅館 酒店 汽旅 vip可住家 外約
★*外送方式:現金交易 不轉帳 不刷卡 不買點數 不勉強消費可退換
★*年齡18~50歲〈正派經營、一律現金、絕.無.欺.騙〉
★*身高【150~176】=胸圍【A-B-C-D-E-F-H-G】 
★*各類型的美女應有盡有,一律台灣美女、配合度及服務更是100%
★*依照您所需要的條件安排、現金消費、不加收任何費用、保證可換
★*新茶多、貨源足、素質優、安全隱密、絕不催趕《絕對是您最佳的選擇
★*全套服務:愛愛、口交、哈拉、洗澡 還要特別服務哦

●●營業時間:中午12:00---凌晨1:30【凌晨請提前預約】365天全年無休 隨時歡迎你們的關顧
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
小星星外送茶活動大優惠: 籟nini9595  sy:bjx778
1.消費一次不管金額大小免房費 免車資 送絲襪
2.消費金額8k送絲襪+免車資+3000優惠卷+9折會員卡
3.消費金額10k送絲襪+原味內褲消費第二節直接半價
3.消費金額20k送超級VIP(永久7折)免費試車10k小模+免費進入約炮群
4.消費金額30k送黃金VIP(永久半價)免費試車15k小模2小時無線次數
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
【包夜套餐】  籟nini9595  sy:bjx778
1.買六節【6小時-免費送2H】送3000抵用卷
2.買九節【9小時-免費送3H】送5000抵用卷+半價*2
3.買十二節【12小時-免費送4H】+永久半價+黃金VIP
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
【加時套餐】 籟nini9595  sy:bjx778
1.兩節送一節/兩節送兩節/三節送一節/三節送兩節
2.喝茶續杯半價
3.還可約姐妹花母女雙胞胎3P妹妹喲
【北中南套餐都可以挑選,詳情諮詢我喲】
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
台灣外送茶選妃官網【http://www.5280344.com/forum.php
平價茶【3-7k】【http://www.5280344.com/forum.php?mod=forumdisplay&fid=71
優質茶【7-12k】【http://www.5280344.com/forum.php?mod=forumdisplay&fid=70
高檔茶【12-80k】【http://www.5280344.com/forum.php?mod=forumdisplay&fid=69
台北外送茶選妃官網【http://www.5280344.com/forum.php?mod=forumdisplay&fid=39
台中外送茶選妃官網【http://www.5280344.com/forum.php?mod=forumdisplay&fid=40
高雄外送茶選妃官網【http://www.5280344.com/forum.php?mod=forumdisplay&fid=41
新竹外送茶選妃官網【http://www.5280344.com/forum.php?mod=forumdisplay&fid=47
彰化外送茶選妃官網【http://www.5280344.com/forum.php?mod=forumdisplay&fid=48
台南外送茶選妃官網【http://www.5280344.com/forum.php?mod=forumdisplay&fid=49
台灣北中南優惠茶單【http://www.5280344.com/forum.php?mod=forumdisplay&fid=50
真實客評售後區【http://www.5280344.com/forum.php?mod=forumdisplay&fid=45
吃魚喝茶新手區【http://www.5280344.com/forum.php?mod=forumdisplay&fid=36
安全旅館推薦區【http://www.5280344.com/forum.php?mod=forumdisplay&fid=37
男女兩性知識區【http://www.5280344.com/forum.php?mod=forumdisplay&fid=60
情色成人小說區【http://www.5280344.com/forum.php?mod=forumdisplay&fid=46
幽默笑話開心區【http://www.5280344.com/forum.php?mod=forumdisplay&fid=51
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
外送地區: 籟nini9595 sy:bjx778  
【新北】三重 土城 汐止 新莊 板橋 永和 瀘州 中和 五股 泰山 新店 八里-林口-淡水-龜山萬壽路
【台北】大同 大安 士林 中山 中正 內湖 文山 北投 松山 信義 南港 萬華
【新竹】新竹《東區》竹北
【彰化】員林鎮 鹿港鎮 埔心鄉 和美鎮 溪湖鎮 田尾區 南投市 草屯區 田中鎮 彰化市
【台中】東區 南區 西區 北區 中區 南屯區 西屯區 北屯區 大里 大雅 烏日 豐原 沙鹿 太平
【高雄】左營 三民 苓雅 新興 前鎮 前金 鼓山 楠梓 小港 鳳山
【台南】東區 北區 南區 中西區 永康區-仁德區
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[/size]
空姐 模特兒 演藝明星 女主播 護士 女軍官 AV女優 運動員 女學生 促 狂野型 淫蕩型 服務型 外貿型 氣質型 美腿型 甜美型 大奶型 高檔型 特別型 火辣 台北/新竹/台中/彰化/南投/高雄市區 住家、飯店、商汽旅(見到妹妹/滿意金消費) ╭適時點杯台灣好tea╮★╭新鮮出爐ㄉ好茶等你來泡!!絕對驚艷![應有盡有~任君挑選☆服務超優] 臺北/臺中/高雄/彰化/新竹/茶訊論壇/鐘點情人外送茶/找茶喝/找魚論壇/高價正妹外送茶/高價辣妹外送/高價清純學生妹/高價麻豆外送/高價混血正妹外送/出差外叫小姐/外送到府 籟nini9595成人愛愛論壇 大家來找茶 伊利 玩美情人 男人幫 QK情色休閒俱樂部 重車論壇 一夜情 瀘州指壓 成人圖片 李宗瑞 陳自搖 口爆 幼幼 成人貼圖 吳亞馨 中出 顏射 太子 找魚論壇 陳自搖 鬆島楓茶.叫女人.飯店叫辣妹.外約電話.外送人妻辣媽.汐止.瀘州.三重.新莊.南港.林口.龜山外送茶.台北舒壓按摩全套服務外送.援交妹網站.全套服務網站.台北外送茶.外送住家.一夜情.外送鐘點情人外送茶坊台北新竹彰化台中高雄南投彰化旅館飯店叫小姐找炮友最佳選擇地方甜美誘人+性感魅惑+情趣狂野+籟nini9595官網[url]http://5280344.com/url]三點式/情趣比基尼+激情貓裝+性感丁字褲+絲襪/網襪/吊襪帶+俏麗女僕裝+百變護士裝+百變學生服+空姐/OL制服#爆操[ #4p #A片 #E罩 #G罩 #一夜情 #一條龍 #丁字褲 #上床 #下體 #中學生 #籟nini9595官網[url]http://5280344.com/url][ #人妻 #俱樂部 #做愛 #偷偷 #偷吃 #偷情 #偷拍 #偷食 #兔女郎 #內射 #全裸 #出差 #出水 #初夜 #動漫 #原味?褲 #?? #口交 #口爆 #叫雞 #可愛 #台中 #台北 #台妹 #台模 #台? #台灣 #偷拍 #吃精 #名模 #后入 #吞精 #吸蛋 #啪啪啪 #國中生 #國模 #外國 #外送 #夜店 #大奶奶 #大胸 #大腿 #女主播 #女學生 #女教師 #女模 #女神 #女秘書 #妖精 #嫖妓 #嫩女 #嫩模 #嫩穴 #?生妹 #宅男 #安全套 #寂寞 #射精 #小奶 #小母狗 #籟nini9595官網[url]http://5280344.com/url][ #少婦 #巨乳 #平胸 #幼齒 #影片 #後入 #性愛 #情婦 #成人電影 #打炮 #打飛機 #抖音 #按摩 #接吻 #援交妹 #摳穴 #摳逼 #操逼 #旅館 #日本妹 #明星 #校花 #極品 #模特 #模特兒 #歐美 #母狗 #比基尼 #泡澡 #泰妹 #淋浴 #混血 #潮吹 #烏克蘭 #無套 #無碼 #熟女 #爆乳 #發騷 #白嫩 #白富美 #直播 #眼鏡妹 #稚嫩 #空姐 #童? #約炮 #美乳 #美胸 #美鮑 #翹臀 #肛交 #脫衣秀 #藝人 #蘿莉 #裙底 #裸拍 #裸體 #調教 #足交 #跳蛋 #車模 #辣妹 #辣模 #酒店 #野模 #陰道 #電愛 #韓妞 #韓模 #顏射 #飢渴 #騷貨 #高中生 #高挑 #高潮 #黑絲籟nini9595 官網[url]http://www.5280344.com/url]魚網B吃[ ... 情人.茶魚網.QK休閒娛樂網.天空論壇.卡提諾論壇. 樂之軒.宅男女神|排行榜|周韋彤|?梓萱|柳岩|pk|台灣|?馨予伊利討論區.伊魚網 e魚網.茶魚飯後.捷克論壇..台灣壇.小女人論壇.吃魚喝茶網anglebaby高圓圓唐嫣許雅涵波多野結衣送茶南投外送茶莊員林外送茶莊嘉義外送茶台南外送茶高雄外送茶莊,按摩美容護膚 桑拿全套外送台北新莊雅緹找小姐/板橋金色年代一夜情交友西門町找小姐喝茶服務台北士林板橋土城喝茶留言版純兼職外送美女外送GTO台中外送茶台北援交外約全套服務,台中,彰化,南投,新竹,台灣外送茶莊,台中茶裏王,桃色誘惑嘉義,台南,高雄一夜情人外約上百位佳麗兼職點點,蘇菲,水靈,溫蒂,小果,歪歪,amy,薇薇,依晨,冰冰,依依,莫琳,虞姬,珊珊,小Q,海倫,夏娃,念念,語嫣,珍欣,米琪,S姐,葉子,娜美,小辣椒,可可,米雪,灣灣,欣萱,笑笑,圓圓,米蘭,羅琳,阿雅,維尼,海薇,千惠,蝴蝶,小舞,糖萱,天心米外送茶坊台北外送茶坊,台中外送茶,高雄外送茶,美女外約服務/台中/高雄/新竹/彰化/南投/全臺外送本土兼職妹妹茶莊極品俱樂部嚴選絕色經典,成人性愛慾茶園,找茶討論區,最強催情唯美貼圖外送,高檔平價 好茶淫照聊天是尋夢園美女外送,情趣用品八大行業指油壓全套,哪裡有好茶,motel,hotel性感絲襪芭比baby小果論壇第一手貓都卡提諾喝茶台北新竹台中高雄彰化外送茶一夜情籟nini9595鐘點情人A片自慰大奶妹日本妹茶/外送茶/ 喝茶/外送茶/論壇慾茶園 壹週刊/北區喝茶外送茶論壇 PLUS 台灣外送茶eyny PC交 愛情公寓天空找炮夜遊區一夜情台南茶高雄茶打炮 大奶正妹 尋夢園

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