Three.js——粒子效果、粒子水波、粒子组成立方体

2024-06-08 12:52

本文主要是介绍Three.js——粒子效果、粒子水波、粒子组成立方体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

个人简介

👀个人主页: 前端杂货铺
开源项目: rich-vue3 (基于 Vue3 + TS + Pinia + Element Plus + Spring全家桶 + MySQL)
🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍖开源 rich-vue3 🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js实战 🍒Three.js

🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

内容参考链接
WebGL专栏WebGL 入门
Three.js(一)创建场景、渲染三维对象、添加灯光、添加阴影、添加雾化
Three.js(二)scene场景、几何体位置旋转缩放、正射投影相机、透视投影相机
Three.js(三)聚光灯、环境光、点光源、平行光、半球光
Three.js(四)基础材质、深度材质、法向材质、面材质、朗伯材质、Phong材质、着色器材质、直线和虚线、联合材质
Three.js(五)Three.js——二维平面、二维圆、自定义二维图形、立方体、球体、圆柱体、圆环、扭结、多面体、文字
Three.js(六)Three.js——tween动画、光线投射拾取、加载.obj/.mtl外部文件、使用相机控制器
Three.js(七)Three.js——骨骼动画
Three.js(八)Three.js——基础纹理、凹凸纹理、法向贴图、环境贴图、canvas贴图

文章目录

    • 前言
    • 一、粒子效果
    • 二、粒子水波
    • 三、粒子组成立方体
    • 总结

前言

大家好,这里是前端杂货铺。

上篇文章我们学习了 基础纹理、凹凸纹理、法向贴图、环境贴图、canvas贴图。接下来,我们继续我们 three.js 的学习!

在学习的过程中,如若需要深入了解或扩展某些知识,可以自行查阅 => three.js官方文档。


一、粒子效果

Sprite 精灵,是一个总是面朝着摄像机的平面,通常含有使用一个半透明的纹理。

new THREE.Sprite( material : Material );
参数名称描述
material(可选值)是 SpriteMaterial 的一个实例。 默认值是一个白色的 SpriteMaterial

SpriteMaterial 点精灵材质,一种使用 Sprite 的材质。

new THREE.SpriteMaterial( parameters : Object )
参数名称描述
parameters(可选) 用于定义材质外观的对象,具有一个或多个属性。 材质的任何属性都可以从此处传入(包括从 Material 继承的任何属性)。

接下来,我们创建一个 10 x 10 的粒子效果,通过精灵和点精灵材质构建,添加到场景中。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>*{ margin: 0; padding: 0;}</style><script src="../lib/three/three.js"></script>
</head><body>
<script>const clock = new THREE.Clock();// 创建场景const scene = new THREE.Scene();// 创建相机 视野角度FOV、长宽比、近截面、远截面const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);// 设置相机位置camera.position.set(0, 0, 200);camera.lookAt(new THREE.Vector3(0, 0, 0));// 创建渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);renderer.setClearColor(0xffffff);// 添加灯光const spotLight = new THREE.SpotLight(0xffffff);scene.add(spotLight);createNormalSprite();// 基础粒子function createNormalSprite() {for (let i = -5; i < 5; i++) {for (let j = -5; j < 5; j++) {const material  = new THREE.SpriteMaterial({color: Math.random() * 0xffff})const sprite = new THREE.Sprite(material);sprite.position.set(i * 10, j * 10, 0);sprite.scale.set(2, 2, 2);scene.add(sprite);}}}// createSystemSprite();// 粒子系统创建粒子function createSystemSprite() {const geometry = new THREE.Geometry();const material = new THREE.PointCloudMaterial({size: 4,vertexColors: true})for (let i = -5; i < 5; i++) {for (let j = -5; j < 5; j++) {// 坐标geometry.vertices.push(new THREE.Vector3(i * 10, j * 10, 0));// 颜色geometry.colors.push(new THREE.Color(Math.random() * 0xffffff));}}scene.add(new THREE.PointCloud(geometry, material));}const animation = () => {// 渲染renderer.render(scene, camera);requestAnimationFrame(animation);}animation();
</script>
</body></html>

在这里插入图片描述


二、粒子水波

接下来,我们基于上述的粒子效果和 canvas 纹理贴图,制作出水波的效果。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>*{ margin: 0; padding: 0;}</style><script src="../lib/three/three.js"></script>
</head><body>
<script>const clock = new THREE.Clock();// 创建场景const scene = new THREE.Scene();// 创建相机 视野角度FOV、长宽比、近截面、远截面const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);// 设置相机位置camera.position.set(0, 50, 200);camera.lookAt(new THREE.Vector3(0, 0, 0));// 创建渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 添加灯光const spotLight = new THREE.SpotLight(0xffffff);scene.add(spotLight);// 使用canvas贴图实现圆形纹理function getSprite() {const canvas = document.createElement('canvas');const size = 8;canvas.width = size * 2;canvas.height = size * 2;const c = canvas.getContext('2d');c.fillStyle = '#00ff00';c.arc(size, size, size / 1.5, 0, Math.PI * 2);c.fill();const texture = new THREE.Texture(canvas);texture.needsUpdate = true;return texture;}// 存储粒子内容const spriteList = [];// 粒子数量const total = 20;createNormalSprite();// 基础粒子function createNormalSprite() {const material  = new THREE.SpriteMaterial({color: 0x008800,map: getSprite()})for (let i = -total; i < total; i++) {for (let j = -total; j < total; j++) {const sprite = new THREE.Sprite(material);sprite.position.set(i * 10, 0, j * 10);spriteList.push(sprite);scene.add(sprite);}}}// 变化的速度const speed = 0.1;// 波浪的高度const height = 5;// 波浪的幅度const step = 0.3;let status = 0;const animation = () => {// 渲染renderer.render(scene, camera);requestAnimationFrame(animation);let index = -1;// 通过 sin 曲线,设置点的位置for (let x = 0; x < total * 2; x++) {for (let y = 0; y < total * 2; y++) {index++;spriteList[index].position.y = ((Math.sin(x + status) * step) * height + (Math.sin(y + status) * step) * height);// 缩放系数const scaleValue = (Math.sin(x + status) * step) + 1;spriteList[index].scale.set(scaleValue, scaleValue, scaleValue);}}status += speed;}animation();
</script>
</body></html>

水波效果


三、粒子组成立方体

接下来,我们实现粒子组成立方体,组成法向材质的立方体。

这需要我们使用 canvas 贴图实现圆形纹理、使用法向材质创建几何体、随机设置点的位置创建点云、使用 TWEEN 实现动画效果等

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>*{ margin: 0; padding: 0;}</style><script src="../lib/three/three.js"></script><script src="../lib/three/tween.min.js"></script><script src="../lib/three/dat.gui.js"></script>
</head><body>
<script>const clock = new THREE.Clock();// 创建场景const scene = new THREE.Scene();// 创建相机 视野角度FOV、长宽比、近截面、远截面const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);// 设置相机位置camera.position.set(0, 30, 100);camera.lookAt(new THREE.Vector3(0, 0, 0));// 创建渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染器尺寸renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 添加灯光const spotLight = new THREE.SpotLight(0xffffff);scene.add(spotLight);// 使用canvas贴图实现圆形纹理function getSprite() {const canvas = document.createElement('canvas');const size = 8;canvas.width = size * 2;canvas.height = size * 2;const c = canvas.getContext('2d');c.fillStyle = '#00ff00';c.arc(size, size, size / 1.5, 0, Math.PI * 2);c.fill();const texture = new THREE.Texture(canvas);texture.needsUpdate = true;return texture;}const geometry = new THREE.BoxGeometry(10, 10, 10, 10, 10, 10);// 存储原始坐标const indexList = [];// 设定当前随机的范围const range = 100;// gui 控制const controls = {polymeric: false, // 是否要组合成立方体completeMesh: false, // 组合之后是否要显示立方体showMesh: false // 是否要现在显示立方体}// 创建随机位置function createRandomPosition(i) {geometry.vertices[i].x = Math.random() * range - range / 2;geometry.vertices[i].y = Math.random() * range - range / 2;geometry.vertices[i].z = Math.random() * range - range / 2;}let cloud;// 创建法向材质的几何体function createMesh() {cloud = new THREE.Mesh(new THREE.BoxGeometry(10, 10, 10, 10, 10), new THREE.MeshNormalMaterial());scene.add(cloud);}function createPointCloud() {let listen = false;for (let i = 0; i < geometry.vertices.length; i++) {indexList.push({x: geometry.vertices[i].x,y: geometry.vertices[i].y,z: geometry.vertices[i].z,})// 随机坐标createRandomPosition(i);// 聚合点 => 体if (controls.polymeric) {// 聚合的动画为 2sconst tween = new TWEEN.Tween(geometry.vertices[i]).to(indexList[i], 2000).start();if (!listen) {listen = true;// 动画完成时,创建法向材质的几何体if (controls.completeMesh) {tween.onComplete(() => {// 先移除点几何体scene.remove(cloud);createMesh();})}}}}// 点云材质const material = new THREE.PointCloudMaterial({size: 2,transparent: true,map: getSprite()});// 点云cloud = new THREE.PointCloud(geometry, material);cloud.sortParticles = true;scene.add(cloud);}createPointCloud();const gui = new dat.GUI();const onChange = () => {scene.remove(cloud);controls.showMesh ? createMesh() : createPointCloud();}// gui 控制for (const key in controls) {gui.add(controls, key).onChange(onChange);}const animation = () => {scene.rotation.y += 0.01;// 渲染renderer.render(scene, camera);TWEEN.update();requestAnimationFrame(animation);}animation();
</script>
</body></html>

粒子组成立方体


总结

本篇文章我们讲解了粒子的基本使用,包括 粒子效果、粒子水波、粒子组成立方体。

更多内容扩展请大家自行查阅 => three.js官方文档,真心推荐读一读!!

好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. Three.js 官方文档
  2. WebGL+Three.js 入门与实战【作者:慕课网_yancy】

在这里插入图片描述


这篇关于Three.js——粒子效果、粒子水波、粒子组成立方体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1042239

相关文章

js+css二级导航

效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con

以canvas方式绘制粒子背景效果,感觉还可以

这个是看到项目中别人写好的,感觉这种写法效果还可以,就存留记录下 就是这种的背景效果。如果想改背景颜色可以通过canvas.js文件中的fillStyle值改。 附上demo下载地址。 https://download.csdn.net/download/u012138137/11249872

echarts省份标注加散点效果

这个是安徽的效果图,鼠标移到红色标注或者对应的市区位置都会显示对应的数值。 先直接上代码: import anhuiMapJson from './anhui.json'getCoords: function(city) {var res = [];if (city != null) {for (var c in this.cityMap.features) {if (this.cityMa

计算机组成原理——RECORD

第一章 概论 1.固件  将部分操作系统固化——即把软件永恒存于只读存储器中。 2.多级层次结构的计算机系统 3.冯*诺依曼计算机的特点 4.现代计算机的组成:CPU、I/O设备、主存储器(MM) 5.细化的计算机组成框图 6.指令操作的三个阶段:取指、分析、执行 第二章 计算机的发展 1.第一台由电子管组成的电子数字积分和计算机(ENIAC) 第三章 系统总线

js小题:通过字符串执行同名变量怎么做

在JavaScript中,你不能直接使用一个字符串来直接引用一个变量,因为JavaScript是一种静态类型语言(尽管它的类型在运行时可以变化),变量的名字在编译时就被确定了。但是,有几种方法可以实现类似的功能: 使用对象(或Map)来存储变量: 你可以使用一个对象来存储你的变量,然后使用字符串作为键来访问这些变量。 let myVars = { 'var1': 'Hello', 'var

XMG 抽屉效果

1.比如说我创建了3个View -(void)viewDidLoad{  [ super viewDidLoad]; [self setUpChild] ;         UIPanGestureRecognizer *pan=[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];

图形编辑器基于Paper.js教程03:认识Paper.js中的所有类

先来认一下Paper的资源对象,小弟有哪些,有个整体的认识。认个脸。 在Paper.js的 官方文档中类大致有如下这些: 基类: ProjectViewItemPointToolSizeSegmentRectangleCurveCurveLocationMatrixColorStyleTweenToolEventGradientGradientStopEvent 二级或三级类 继承Ite

【计算机组成原理】部分题目汇总

计算机组成原理 部分题目汇总 一. 简答题 RISC和CICS 简要说明,比较异同 RISC(精简指令集)注重简单快速的指令执行,使用少量通用寄存器,固定长度指令,优化硬件性能,依赖软件(如编译器)来提升效率。 CISC(复杂指令集)包含多样复杂的指令,能一条指令完成多步操作,采用变长指令,减少指令数但可能增加执行时间,倾向于硬件直接支持复杂功能减轻软件负担。 两者均追求高性能,但RISC

HTML文档插入JS代码的几种方法

在HTML文档里嵌入客户端JavaScript代码有4中方法: 1.内联,放置在< script>和标签对之间。 2.放置在由< script>标签的src属性指定的外部文件中。 3.放置在HTML事件处理程序中,该事件处理程序由onclick或onmouseover这样的HTML属性值指定。 4.放在一个URL里,这个URL使用特殊的“javascript:”协议。 在JS编程中,主张

js 正则表达式出现问题

帮同事写个页面,出现正则表达式不管怎么改都没法匹配的情况。。。。 reg = /^sy[0-9]+$/i; if(rtx.match(reg) == null){ alert("请输入正确的RTX账号!"); return false; } 因为之前一直用的是 reg ="/^sy[0-9]+$/i"; 写PHP写习惯了。。外面多写了两个双引号……T.T 改