使用 Three.js 创建动态粒子效果

news2025/1/8 16:55:55

今天,带大家使用粒子实现一个粒子飞毯的效果,我们先来看一下效果。
请添加图片描述

实现

初始化场景

首先创建一个场景,所有 3D 对象都会被添加到这个场景中。

const scene = new THREE.Scene();

相机和渲染器

配置相机和渲染器来捕捉和显示场景。

相机
  • 使用 PerspectiveCamera 提供广角视图。
渲染器
  • 创建 WebGLRenderer 渲染器,将画布设置为全屏。
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  100
);
camera.position.z = 13;

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector("canvas"),
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

添加粒子

我们将创建一个由数十万个小粒子组成的云,这些粒子可以模拟星空或任何动态环境效果。粒子的创建涉及两个主要组成部分:几何体和材质。

我们使用 BufferGeometry 来存储粒子的位置信息。每个粒子是通过三个坐标(x, y, z)定义的,所以对于 count 个粒子,我们需要一个长度为 count * 3 的数组来存储它们的位置。

const particlesGeometry = new THREE.BufferGeometry();
const count = 500000; // 粒子数量
const positions = new Float32Array(count * 3); // 存储位置的数组
const colors = new Float32Array(count * 3); // 存储颜色的数组

for (let i = 0; i < count * 3; i += 3) {
  positions[i] = (Math.random() - 0.5) * 10; // x位置
  positions[i + 1] = (Math.random() - 0.5) * 10; // y位置
  positions[i + 2] = (Math.random() - 0.5) * 10; // z位置

  colors[i] = Math.random(); // r颜色
  colors[i + 1] = Math.random(); // g颜色
  colors[i + 2] = Math.random(); // b颜色
}

这里的随机数 Math.random() - 0.5 范围为 -0.50.5,乘以 10 来扩展粒子云的空间分布。

粒子材质

粒子材质决定了粒子的视觉效果,如大小、颜色和透明度。我们使用 PointsMaterial 并启用 vertexColors 使每个粒子可以有独立的颜色。

vertexColors: 允许每个粒子使用与其关联的顶点颜色,从而实现每个粒子拥有不同颜色的效果。

注意这里,我们使用了 load 一个透明贴图,这样可以让粒子看起来更加自然。
在这里插入图片描述

const particlesMaterial = new THREE.PointsMaterial({
  size: 0.02, // 粒子大小
  alphaMap: textureLoader.load("/point.png"), // 粒子透明贴图
  transparent: true, // 开启透明度
  vertexColors: true, // 使用顶点颜色
});

上面的几个属性,我们在更加详细的介绍一下

  • size:定义了每个粒子点的屏幕上渲染的大小,单位为像素。它控制了粒子的基本尺寸,但实际视觉大小还会受到 sizeAttenuation 属性的影响,后者决定了粒子大小是否随着与摄像机的距离而变化。如果 sizeAttenuation 设置为 true(默认值),粒子大小将随距离变小,模拟现实世界中远处对象看起来更小的透视效果。
  • alphaMap:为每个粒子指定一个纹理贴图,该贴图的透明度(alpha 通道)将被用来影响粒子的透明度。这个功能使得粒子可以具有不均匀的透明度,从而创造更加自然或复杂的视觉效果,如模拟星星或发光粒子等。使用纹理的灰度值来决定相应区域的透明度。
  • 用于开启材质的透明处理。在使用 alphaMap 或者在材质颜色中指定 alpha 值小于 1 的情况下,需要将此属性设置为 true 以确保 Three.js 正确处理透明度。没有启用 transparent 时,即使材质具有透明纹理或颜色值,也会被渲染为完全不透明。
  • vertexColors:用于开启顶点颜色处理。当设置为 true 时,粒子的颜色将由顶点颜色决定,而不是整个粒子使用单一颜色。这使得每个粒子可以具有不同的颜色,从而实现更加丰富多彩的效果。

控制器

使用 OrbitControls 允许用户通过鼠标来旋转和缩放视图。

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

动画循环

创建动画循环来实时更新粒子位置和渲染场景。

更新粒子位置

我们在这里使用简单的三角函数来模拟粒子的垂直移动,创建类似波浪的效果。通过三角函数 Math.sin,我们可以为每个粒子创建一个周期性变化的动画效果,使其在 y 轴方向上波动。

const tick = () => {
  const elapsedTime = clock.getElapsedTime(); // 获取从开始到现在的时间

  // 使粒子在y轴方向上根据时间变化
  for (let i = 0; i < count; i++) {
    const i3 = i * 3;
    const x = positions[i3]; // 获取粒子当前x位置
    positions[i3 + 1] = Math.sin(elapsedTime + x) * 0.3; // 根据时间和x位置计算新的y位置
  }

  particlesGeometry.attributes.position.needsUpdate = true; // 通知Three.js位置数据已更新
};

这里,Math.sin(elapsedTime + x) 的使用将每个粒子的动画周期与其 x 位置关联起来,创建更自然的波动效果。乘以 0.3 是为了控制波动的幅度,不让粒子移动得太极端。

渲染场景

在每次动画循环的最后,我们调用 renderer.render 方法来绘制更新后的场景:

renderer.render(scene, camera);
window.requestAnimationFrame(tick); // 请求下一帧继续动画

代码

github

https://github.com/calmound/threejs-demo/tree/main/feitan

gitee

https://gitee.com/calmound/threejs-demo/tree/main/feitan

学习threejs:www.threejs3d.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2272716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux双端口服务器:端口1的文件系统目录挂载到端口2

目录 一、服务器安装NFS服务并配置二、文件挂载三、持久化挂载总结为什么服务器配置多个端口 目前有一台服务器&#xff0c;不过他设置了两个SSH的端口&#xff0c;通过下面方法可以让这两个端口连接的主机能够共享同一个文件系统&#xff0c;原本这两个端口的文件系统是隔离的…

机器学习算法---贝叶斯学习

1.了解相关概念 先验概率&#xff1a;有数据集d,以及假设h,此时h是不确定的。在还没有训练数据之前h的初始概率记为P(h),类似地我们把P(d)表示训练数据d在任何假设都未知或不确定时的概率。P(d|h)表示已知假设h成立时d的概率。 后验概率&#xff1a;就是在数据d上经过学习之后…

[paddle] 非线性拟合问题的训练

利用paddlepaddle建立神经网络&#xff0c;模拟有限个数据的非线性拟合 本文仍然考虑 f ( x ) sin ⁡ ( x ) x f(x)\frac{\sin(x)}{x} f(x)xsin(x)​ 函数在区间 [-10,10] 上固定数据的拟合。 import paddle import paddle.nn as nn import numpy as np import matplotlib.…

GWAS数据和软件下载

这部分主要是数据获取,以及软件配置方法。 一、配套数据和代码 数据和代码目前在不断的更新,最新的教程可以私信,我通过后手动发送最新版的pdf和数据代码。发送的压缩包,有电子版的pdf和数据下载链接,里面是最新的百度网盘的地址,下载到本地即可。然后根据pdf教程,结合配套的…

win32汇编环境,在对话框中画五边形与六边形

;运行效果 ;win32汇编环境,在对话框中画五边形与六边形 ;展示五边形与六边形的画法 ;将代码复制进radasm软件里,直接编译可运行.重要部分加备注。 ;下面为asm文件 ;>>>>>>>>>>>>>>>>>>>>>>>>>&g…

springcloud 介绍

Spring Cloud是一个基于Spring Boot的微服务架构解决方案集合&#xff0c;它提供了一套完整的工具集&#xff0c;用于快速构建分布式系统。在Spring Cloud的架构中&#xff0c;服务被拆分为一系列小型、自治的微服务&#xff0c;每个服务运行在其独立的进程中&#xff0c;并通过…

如何进行千万级别数据跑批优化

目录 背景问题分析解决方案 数据库问题分片广播分批获取事务控制充分利用服务器资源MQ消费任务并行动态调整并发度失败任务如何继续下游接口时间线程安全异常 & 监控 总结 背景 定义&#xff1a;跑批是指在特定日期对大量数据进行定时处理的过程。在金融领域&#xff0c;…

电脑提示wlanapi.dll丢失怎么办?wlanapi.dll丢失的多种解决方法

电脑提示wlanapi.dll丢失&#xff1f;别担心&#xff0c;这里有多种解决方法&#xff01; 作为软件开发领域的从业者&#xff0c;我深知电脑在运行过程中可能会遇到的各种问题&#xff0c;其中“wlanapi.dll丢失”这一报错信息就常常让用户感到困惑和不安。今天&#xff0c;我…

刷服务器固件

猫眼淘票票 大麦 一 H3C通用IP 注:算力服务器不需要存储 二 刷服务器固件 1 登录固定IP地址 2 升级BMC版本 注 虽然IP不一致但是步骤是一致的 3 此时服务器会出现断网现象&#xff0c;若不断网等上三分钟ping一下 4 重新登录 5 断电拔电源线重新登录查看是否登录成功

深入Android架构(从线程到AIDL)_13 线程安全的化解之例

目录 7、 线程安全的化解之例 复习&#xff1a;Android单线程环境 非单线程环境的线程安全议题 范例-1 范例-2​编辑 同步(Synchronization)化解线程安全的问题 7、 线程安全的化解之例 复习&#xff1a;Android单线程环境 View是一个单线程的类&#xff1b;其意味着&…

每日AIGC最新进展(80): 重庆大学提出多角色视频生成方法、Adobe提出大视角变化下的人类视频生成、字节跳动提出快速虚拟头像生成方法

Diffusion Models专栏文章汇总:入门与实战 Follow-Your-MultiPose: Tuning-Free Multi-Character Text-to-Video Generation via Pose Guidance 在多角色视频生成的研究中,如何实现文本可编辑和姿态可控的角色生成一直是一个具有挑战性的课题。现有的方法往往只关注单一对象的…

【多线程初阶篇¹】线程理解| 线程和进程的区别

目录 一、认识线程Thread 1.为啥引入线程 2.线程理解 &#x1f525; 3.面试题&#xff1a;线程和进程的区别 一、认识线程Thread 1.为啥引入线程 为了解决进程太重量的问题 解释&#xff08;为什么说线程比进程更轻量&#xff1f;/为什么说线程创建/销毁开销比进程小&#…

Cursor 实战技巧:好用的提示词插件Cursor Rules

你好啊&#xff0c;见字如面。感谢阅读&#xff0c;期待我们下一次的相遇。 最近在小红书发现了有人分享这款Cursor提示词的插件&#xff0c;下面给各位分享下使用教程。简单来说Cursor Rules就是可以为每一个我们自己的项目去配置一个系统级别的提示词&#xff0c;这样在我们…

Tomcat解析

架构图 核心功能 Tomcat是Apache开源的轻量级Java Servlet容器&#xff0c;其中一个Server&#xff08;Tomcat实例&#xff09;可以管理多个Service&#xff08;服务&#xff09;&#xff0c;一个Service包含多个Connector和一个Engine&#xff0c;负责管理请求到应用的整个流…

List-顺序表--2

目录 1、ArrayList 2、ArrayList构造方法 3、ArrayList常见方法 4、ArrayList的遍历 5、ArrayList的扩容机制 6、ArrayList的具体使用 6.1、杨辉三角 6.2、简单的洗牌算法 1、ArrayList 在集合框架中&#xff0c;ArrayList 是一个普通的类&#xff0c;实现了 List 接口…

【C++】字符数|组的输出详解与拓展

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;字符数组的输出&#xff1a;三种方法解析方法1&#xff1a;直接输出字符串代码示例解析与特点 方法2&#xff1a;使用while循环逐字符输出代码示例解析与特点 方法3&#x…

解决iNodeClient客户端出现查询SSL VPN网关参数失败的问题

一、问题&#xff1a; 使用iNodeClient连接VPN报错&#xff0c;校验网关、用户名、密码都没问题&#xff0c;仍然抱错查询SSL VPN网关参数失败&#xff0c;请检查网络配置或联系管理员。 二、解决方案&#xff1a; 2.1 方案一 重启iNodeAuthService服务 sudo /Library/Star…

数树数(中等难度)

题目&#xff1a; 解题代码&#xff1a; n,qmap(int,input().split())#分别输入层数和路径数量 for i in range(q):sinput()#输入“L”或“R”x1for j in s:if j "L":xx*2-1 #&#xff01;&#xff01;&#xff01;规律else:xx*2print(x)

CAN201 Introduction to Networking(计算机网络)Pt.5 网络安全

文章目录 6. Network Security&#xff08;网络安全&#xff09;6.1 What is network security&#xff08;什么是网络安全&#xff09;6.2 Principles of cryptography&#xff08;密码学的原则&#xff09;6.2.1 Breaking an encryption scheme&#xff08;破解加密方案&…

【ArcGIS Pro二次开发实例教程】(2):BSM字段赋值

一、简介 一般的数据库要素或表格都有一个BSM字段&#xff0c;用来标识唯一值。 此工具要实现的功能是&#xff1a;按一定的规律&#xff08;前缀中间的填充数字OBJECT码&#xff09;来给BSM赋值。 主要技术要点包括&#xff1a; 1、ProWindow的创建&#xff0c;Label,Comb…