最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于three.js實(shí)現(xiàn)的3D粒子動效實(shí)例代碼

 更新時(shí)間:2019年04月09日 08:40:09   作者:個(gè)推  
這篇文章主要給大家介紹了關(guān)于如何基于three.js實(shí)現(xiàn)的3D粒子動效的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用three.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

一、背景

粒子特效是為模擬現(xiàn)實(shí)中的水、火、霧、氣等效果由各種三維軟件開發(fā)的制作模塊,原理是將無數(shù)的單個(gè)粒子組合使其呈現(xiàn)出固定形態(tài),借由控制器、腳本來控制其整體或單個(gè)的運(yùn)動,模擬出現(xiàn)真實(shí)的效果。three.js是用JavaScript編寫的WebGL的第三方庫,three.js提供了豐富的API幫助我們?nèi)?shí)現(xiàn)3D動效,本文主要介紹如何使用three.js實(shí)現(xiàn)粒子過渡效果,以及基本的鼠標(biāo)交互操作。

(注:本文使用的關(guān)于three.js的API都是基于版本r98的。)


二、實(shí)現(xiàn)步驟

1. 創(chuàng)建渲染場景scene

scene實(shí)際上相當(dāng)于一個(gè)三維空間,用于承載和顯示我們所定義的一切,包括相機(jī)、物體、燈光等。在實(shí)際開發(fā)時(shí)為了方便觀察可添加一些輔助工具,比如網(wǎng)格、坐標(biāo)軸等。

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

2. 添加照相機(jī)camera

THREE里面實(shí)現(xiàn)了幾種相機(jī):PerspectiveCamera(透視相機(jī))、 OrthographicCamera(正交投影相機(jī))、CubeCamera(立方體相機(jī)或全景相機(jī))和 StereoCamera(3D相機(jī))。本文介紹我們主要用到的 PerspectiveCamera(透視相機(jī)):

視覺效果是近大遠(yuǎn)小。

配置參數(shù) PerspectiveCamera(fov, aspect, near, far)。

fov:相機(jī)的可視角度。

aspect:相機(jī)可視范圍的長寬比。

near:相對于深度剪切面的遠(yuǎn)的距離。

far:相對于深度剪切面的遠(yuǎn)的距離。

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

3. 添加場景渲染需要的燈光

three.js里面實(shí)現(xiàn)的光源:AmbientLight(環(huán)境光)、DirectionalLight(平行光)、HemisphereLight(半球光)、PointLight(點(diǎn)光源)、RectAreaLight(平面光源)、SpotLight(聚光燈)等。配置光源參數(shù)時(shí)需要注意顏色的疊加效果,如環(huán)境光的顏色會直接作用于物體的當(dāng)前顏色。各種光源的配置參數(shù)有些區(qū)別,下面是本文案例中會用到的二種光源。

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. 創(chuàng)建、導(dǎo)出并加載模型文件loader

創(chuàng)建模型,可以使用three.js editor進(jìn)行創(chuàng)建或者用three.js的基礎(chǔ)模型生成類進(jìn)行生成,相對復(fù)雜的或者比較特殊的模型需要使用建模工具進(jìn)行創(chuàng)建(c4d、3dmax等)。

使用three.js editor進(jìn)行創(chuàng)建,可添加基本幾何體,調(diào)整幾何體的各種參數(shù)(位置、顏色、材質(zhì)等)。

使用模型類生成。

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

導(dǎo)出需要的模型文件(此處使用的是 obj格式的模型文件)。

加載并解析模型文件數(shù)據(jù)。

let onProgress = function (xhr) {
 if (xhr.lengthComputable) {
  // 可進(jìn)行計(jì)算得知模型加載進(jìn)度
 }
 };
 let onError = function () {};
 particleSystem = new THREE.Group();
 var texture = new THREE.TextureLoader().load('./point.png');
 new THREE.OBJLoader().load('./model.obj', function (object) {
 // object 模型文件數(shù)據(jù)
 }, onProgress, onError);

5. 將導(dǎo)入到模型文件轉(zhuǎn)換成粒子系統(tǒng)Points

獲取模型的坐標(biāo)值。

拷貝粒子坐標(biāo)值到新建屬性position1上 ,這個(gè)作為粒子過渡效果的最終坐標(biāo)位置。

給粒子系統(tǒng)添加隨機(jī)三維坐標(biāo)值position,目的是把每個(gè)粒子位置打亂,設(shè)定起始位置。

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動畫庫實(shí)現(xiàn)粒子坐標(biāo)從position到position1點(diǎn)轉(zhuǎn)換

利用 TWEEN 的緩動算法計(jì)算出各個(gè)粒子每一次變化的坐標(biāo)位置,從初始位置到結(jié)束位置時(shí)間設(shè)置為2s(可自定義),每次執(zhí)行計(jì)算之后都需要將attributes的position屬性設(shè)置為true,用來提醒場景需要更新,在下次渲染時(shí),render會使用最新計(jì)算的值進(jìn)行渲染。

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 // 設(shè)置更新
 }
 }

7. 添加渲染場景render

創(chuàng)建容器。

定義render渲染器,設(shè)置各個(gè)參數(shù)。

將渲染器添加到容器里。

自定義的渲染函數(shù) render,在渲染函數(shù)里面我們利用 TWEEN.update 去更新模型的狀態(tài)。

調(diào)用自定義的循環(huán)動畫執(zhí)行函數(shù) animate,利用requestAnimationFrame方法進(jìn)行逐幀渲染。

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() { // 開始循環(huán)執(zhí)行渲染動畫
 requestAnimationFrame(animate);
 render();
 }

8. 添加鼠標(biāo)操作事件實(shí)現(xiàn)角度控制

我們還可以添加鼠標(biāo)操作事件實(shí)現(xiàn)角度控制,其中winX、winY分別為window的寬高的一半,當(dāng)然具體的坐標(biāo)位置可以根據(jù)自己的需求進(jìn)行計(jì)算,具體的效果如下圖所示。

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

三、優(yōu)化方案

1. 減少粒子數(shù)量

隨著粒子數(shù)量的增加,需要的計(jì)算每個(gè)粒子的位置和大小將會非常耗時(shí),可能會造成動畫卡頓或出現(xiàn)頁面假死的情況,所以我們在建立模型時(shí)可盡量減少粒子的數(shù)量,能夠有效提升性能。

在以上示例中,我們改變導(dǎo)出模型的精細(xì)程度,可以得到不同數(shù)量的粒子系統(tǒng),當(dāng)粒子數(shù)量達(dá)到幾十萬甚至幾百萬的時(shí)候,在動畫加載時(shí)可以感受到明顯的卡頓現(xiàn)象,這主要是由于fps比較低,具體的對比效果如下圖所示,左邊粒子數(shù)量為30萬,右邊粒子數(shù)量為6萬,可以明顯看出左邊跳幀明顯,右邊基本保持比較流暢的狀態(tài)。


2. 采用GPU渲染方式

編寫片元著色器代碼,利用webgl可以為canvas提供硬件3D加速,瀏覽器可以更流暢地渲染頁面。目前大多數(shù)設(shè)備都已經(jīng)支持該方式,需要注意的是在低端的設(shè)備上由于硬件設(shè)備原因,渲染的速度可能不及基于cpu計(jì)算的方式渲染。

四、總結(jié)

綜上所述,實(shí)現(xiàn)粒子動效的關(guān)鍵在于計(jì)算、維護(hù)每個(gè)粒子的位置狀態(tài),而three.js提供了較為便利的方法,可以用于渲染整個(gè)粒子場景。當(dāng)粒子數(shù)量極為龐大時(shí),想要實(shí)現(xiàn)較為流暢的動畫效果需要注意優(yōu)化代碼、減少計(jì)算等,也可以通過提升硬件配置來達(dá)到效果。本文中的案例為大家展示了3D粒子動效如何實(shí)現(xiàn),大家可以根據(jù)自己的實(shí)際需求去制作更炫酷的動態(tài)效果。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • three.js利用gpu選取物體并計(jì)算交點(diǎn)位置的方法示例

    three.js利用gpu選取物體并計(jì)算交點(diǎn)位置的方法示例

    這篇文章主要給大家介紹了關(guān)于three.js利用gpu選取物體并計(jì)算交點(diǎn)位置的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用three.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 前端通用Token操作詳細(xì)指南(常見常用版)

    前端通用Token操作詳細(xì)指南(常見常用版)

    在前端開發(fā)中,處理用戶登錄和退出時(shí)涉及的一個(gè)重要環(huán)節(jié)就是Token的管理,Token是用于驗(yàn)證用戶身份的一種令牌,通常在用戶登錄成功后由服務(wù)器頒發(fā),這篇文章主要介紹了前端通用Token操作詳細(xì)指南的相關(guān)資料,需要的朋友可以參考下
    2026-04-04
  • 利用Bootstrap Multiselect實(shí)現(xiàn)下拉框多選功能

    利用Bootstrap Multiselect實(shí)現(xiàn)下拉框多選功能

    這篇文章主要介紹了利用Bootstrap Multiselect實(shí)現(xiàn)下拉框多選功能,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-04-04
  • tree?shaking功能及使用原理詳細(xì)解析

    tree?shaking功能及使用原理詳細(xì)解析

    這篇文章主要為大家介紹了tree?shaking功能及使用原理詳細(xì)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪的相關(guān)資料
    2023-01-01
  • 深入探討JavaScript異步編程中Promise的關(guān)鍵要點(diǎn)

    深入探討JavaScript異步編程中Promise的關(guān)鍵要點(diǎn)

    這篇文章將全面深入地探討Promise,包括其前身、歷史、能力、優(yōu)點(diǎn)、缺點(diǎn)以及提供每個(gè)方法的案例,感興趣的小伙伴可以跟隨小編一學(xué)習(xí)一下
    2023-06-06
  • javascript使用輸出語句實(shí)現(xiàn)網(wǎng)頁特效代碼

    javascript使用輸出語句實(shí)現(xiàn)網(wǎng)頁特效代碼

    這篇文章主要介紹javascript使用輸出語句實(shí)現(xiàn)網(wǎng)頁特效,有需要的朋友可以參考下
    2015-08-08
  • bootstrap treeview 樹形菜單帶復(fù)選框及級聯(lián)選擇功能

    bootstrap treeview 樹形菜單帶復(fù)選框及級聯(lián)選擇功能

    這篇文章主要介紹了bootstrap treeview 樹形菜單帶復(fù)選框及級聯(lián)選擇功能,代碼超簡單,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-06-06
  • js中方法重載如何實(shí)現(xiàn)?以及函數(shù)的參數(shù)問題

    js中方法重載如何實(shí)現(xiàn)?以及函數(shù)的參數(shù)問題

    js中沒有辦法直接實(shí)現(xiàn)方法重載,但每一個(gè)函數(shù)都有一個(gè)特殊的參數(shù)arguments,利用它可以實(shí)現(xiàn)方法的重載,具體示例如下
    2013-08-08
  • 原生js實(shí)現(xiàn)3D輪播圖

    原生js實(shí)現(xiàn)3D輪播圖

    這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)3D輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • 深入理解JavaScript中的for循環(huán)

    深入理解JavaScript中的for循環(huán)

    這篇文章主要給大家深入的介紹了JavaScript中的for循環(huán),其中包括ES5中的三種for循環(huán),分別是簡單for循環(huán)、for-in以及forEach,另外還詳細(xì)介紹了ES6新增的一種循環(huán):for-of ,有需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02

最新評論

抚宁县| 丘北县| 牙克石市| 台东县| 阿坝县| 开江县| 景洪市| 沙雅县| 射洪县| 西平县| 长岭县| 阜平县| 铅山县| 临夏市| 栾川县| 武定县| 鄱阳县| 北流市| 广灵县| 阜新市| 南丰县| 安西县| 八宿县| 中阳县| 无锡市| 东丰县| 宕昌县| 南城县| 开封市| 芜湖县| 宝清县| 湖北省| 巩义市| 政和县| 阳泉市| 涞源县| 晋宁县| 个旧市| 泰宁县| 科技| 尼勒克县|