iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何实现基于three.js的3D粒子动效
  • 277
分享到

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

2023-06-02 16:06:49 277人浏览 独家记忆
摘要

小编给大家分享一下如何实现基于three.js的3D粒子动效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、背景粒子特效是为模拟现实中的水、火、雾、气等效果由各

小编给大家分享一下如何实现基于three.js3D粒子动效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、背景

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

二、实现步骤

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进行创建,可添加基本几何体,调整几何体的各种参数(位置、颜色、材质等)。

如何实现基于three.js的3D粒子动效
使用模型类生成。

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

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

三、优化方案

1. 减少粒子数量

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

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

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

以上是“如何实现基于three.js的3D粒子动效”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: 如何实现基于three.js的3D粒子动效

本文链接: https://www.lsjlt.com/news/230513.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何实现基于three.js的3D粒子动效
    小编给大家分享一下如何实现基于three.js的3D粒子动效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、背景粒子特效是为模拟现实中的水、火、雾、气等效果由各...
    99+
    2023-06-02
  • 基于Three.js实现酷炫3D地图效果
    目录实现效果前言使用1.修改整体的背景图可以使用颜色或用贴图改材质2. 取消地图上柱状图显示3.更换地图、更换省份、市 4.修改相机的视角,页面展示的远近角度5....
    99+
    2022-11-13
    Three.js 3D地图 Three.js 地图
  • 基于Three.js实现3D玉兔效果的示例代码
    目录前言技术人的快乐1、中秋与玉兔2、3D玉兔3、环境说明4、创建一个html5、定义Threejs的相关场景、相机等参数6、定义玉兔并设置大小7、最终效果前言 2022年中秋佳节即...
    99+
    2024-04-02
  • 基于WPF如何实现3D画廊动画效果
    本篇内容介绍了“基于WPF如何实现3D画廊动画效果”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!接下来想做一个图廊,所以并没有必要用立方体,...
    99+
    2023-07-05
  • jQuery实现动态粒子效果
    本文实例为大家分享了jQuery实现动态粒子效果的具体代码,供大家参考,具体内容如下 效果图 代码 <!DOCTYPE html> <html lang="...
    99+
    2024-04-02
  • 基于Particles.js如何制作超炫粒子动态背景效果
    这篇文章主要介绍了基于Particles.js如何制作超炫粒子动态背景效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。好久没登录知乎,发现...
    99+
    2024-04-02
  • canvas如何实现粒子动画
    本篇内容主要讲解“ canvas如何实现粒子动画”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ canvas如何实现粒子动画”吧!代码如下:<!DOCTY...
    99+
    2024-04-02
  • react-three-fiber实现炫酷3D粒子效果首页
    目录背景Three.js工作原理场景(Scene)相机(Camera)渲染器(renderer)网格对象(mesh)react-three-fiber画布(Canvas)3D粒子模型...
    99+
    2024-04-02
  • 利用JavaScript实现3D可旋转粒子矩阵效果
    目录演示技术栈dat.gui.min.js源码js部分演示 技术栈 本次使用了dat.gui.min.js这个新库(就是在我文章里没有出现过的那么他们的功能有哪些呢?—...
    99+
    2024-04-02
  • Python粒子烟花动态效果实现
    目录效果展示实现代码剩下代码跨年倒计时还有18天?我已经开始整烟花了,虽然不是很好看吧,但是也能将就看看 这个的背景图,音乐,还有文字都是可以自己修改的哦 效果展示 依次导入本次...
    99+
    2023-01-03
    Python粒子烟花 Python动态烟花 Python烟花
  • JavaScript+Canvas实现带跳动效果的粒子动画
    目录前言实现过程运行效果总结前言 用 HTML5 的 Canvas 元素实现一个带有跳动效果的粒子动画。会用到 Canvas 的2D渲染上下文,通过 JavaScript 编写绘图代...
    99+
    2023-03-14
    JavaScript Canvas实现粒子动画 Canvas粒子动画 JavaScript Canvas
  • ThingJS粒子特效如何实现雨雪效果
    这篇文章主要介绍了ThingJS粒子特效如何实现雨雪效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用ThingJS可以快速编写粒子效果,比如:下雨、下雪(可以控制雨雪大...
    99+
    2023-06-15
  • CSS3中怎么实现粒子动画效果
    这期内容当中小编将会给大家带来有关CSS3中怎么实现粒子动画效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。按钮点击粒子动画<div class=&qu...
    99+
    2024-04-02
  • canvas如何实现粒子喷泉动画
    今天小编给大家分享一下canvas如何实现粒子喷泉动画的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了...
    99+
    2024-04-02
  • Three.js实现脸书元宇宙3D动态Logo效果
    目录背景什么是元宇宙实现效果试炼一:THREE.TorusGeometry试炼二:THREE.TorusKnotGeometry试炼三:THREE.TubeGeometry试炼四:B...
    99+
    2024-04-02
  • 基于Unity3D如何实现3D照片墙效果
    这篇文章主要介绍了基于Unity3D如何实现3D照片墙效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、前言Unity3D不仅仅可以开发游戏,还有非常多的开发方向,秉承着...
    99+
    2023-06-29
  • three.js如何实现3d全景看房
    这篇文章主要介绍“three.js如何实现3d全景看房”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“three.js如何实现3d全景看房”文章能帮助大家解决问题。认识threejsthree.js就...
    99+
    2023-07-02
  • 基于Unity3D实现3D照片墙效果
    一、前言 Unity3D不仅仅可以开发游戏,还有非常多的开发方向,秉承着兴趣为先,将可以使用Unity制作的各种应用案例,分享如何进行开发,如何实现,希望大家可以在感兴趣的地方,学习...
    99+
    2024-04-02
  • JavaScript如何实现带粒子效果的进度条
    这篇文章主要讲解了“JavaScript如何实现带粒子效果的进度条”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript如何实现带粒子效果的进度条”吧!具体代码如下<htm...
    99+
    2023-07-02
  • CSS实现粒子动态按钮效果的示例
    这篇文章将为大家详细讲解有关CSS实现粒子动态按钮效果的示例,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。按钮(button)可能是网页中最常见的组件之一了,大部分都平淡无奇,如果你碰到的是一个这样的按钮...
    99+
    2023-06-08
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作