当前位置: 首页 > news >正文

游戏引擎中的粒子系统

一、粒子基础

粒子系统里有各种发射器(emitter),发射器发射粒子(particle)。

粒子是拥有位置、速度、大小尺寸、颜色和生命周期的3D模型。
粒子的生命周期中,包含产生(Spawn)、与环境交互以及死亡。设计中很重要的一点是要控制场景中粒子的数量。

粒子发射器有三个作用:

  • 具体规定粒子产生的规则
  • 具体规定粒子模拟的逻辑
  • 描述如何渲染粒子
    在这里插入图片描述

粒子系统经常有不止一类发射器,比如火堆这个系统中有火焰、火星和烟雾三种发射器

在这里插入图片描述
关于粒子的产生,位置上可以分为单点产生、在区域上产生和在mesh上产生三类;
在这里插入图片描述

在模式上也可以分为连续产生和间歇性产生等
在这里插入图片描述

粒子的模拟:

1、常规的受力

在这里插入图片描述
2、粒子如何变动,一般使用显式欧拉法就行。受力状态决定加速度,决定速度的更新,速度决定位置的更新
3、模拟时,除了重力,还可以加上粒子的旋转、颜色的变化、大小的变化以及和环境的碰撞等

粒子的形状一般有三类:

1、Billboard Particle。这种粒子由一些面片构成,其形状其实只有一面,但它始终保持面向摄像头,所以看起来是一个3D的粒子。如果这个particle比较小就无所谓,但如果比较大的时候建议是其形状也会随时间而变化,不然比较假

2、Mesh Particle。要模拟散的碎的粒子时往往直接用3D mesh当做粒子,然后给它们设置各种不同类别的随机属性,从而艺术家也更容易实现想要的效果

3、Ribbon Particle。样条形粒子,其实粒子是样条上的控制点,然后通过连接获得完整的条状。往往使用在比如武器挥舞的残影之类的地方。在控制点连接过程中需要插值,不然每一个连接点间的形状是不连续的(看起来像一个个四边形拼在一起)。一般使用向心的catmull-rom插值(在粒子间加入额外的分割块且数量可自己选定,不过对CPU要求会变高)
在这里插入图片描述

二、粒子渲染

2.1 粒子排序

常见的透明融合问题在粒子渲染处也需要解决,排序一定要从远到近。

粒子排序有两种方式,一种是全局法,完全按粒子个体来排序,很精准但消耗巨大;另一种是按层级,从简单到复杂的排序是依照粒子系统排序、依照emitter排序和在emitter之内排序。
具体来说,如果依照粒子排序,则按粒子离相机的距离排序;如果按系统或发射器排序,则按Bounding box排序。
在这里插入图片描述

2.2 Low-Resolution

另一方面,粒子渲染会带来巨大消耗的原因是“全分辨率粒子”。当我们渲染普通场景时,由于Z-buffer的帮助,其实只需要渲染接触到的场景的第一个物体(其他被遮挡不需要渲染),但粒子效果有时候(最差情况下)会在一瞬间产生叠满整个分辨率好多层的粒子,而且它们不存在完全遮挡关系,所以相当于一下子要进行超大量的渲染。

overdraw:同一个像素被绘制了多少次。

解决方案是:
降分辨率下采样进行粒子的渲染,此时与原场景无关,获得粒子的颜色和透明度alpha。然后再上采样融合到原场景中。
在这里插入图片描述

三、GPU粒子

从上面的所述可以看到,粒子计算功耗很大,所以放到GPU中是一个解决方案,原因有三:

  • 高并行运算,适合大量粒子的模拟计算
  • 可以释放CPU功耗来进行游戏本身计算
  • 方便获得深度缓冲来做遮挡判断

但有一个难点是粒子拥有生命周期,会不断产生消失,所以如何在GPU中实现粒子是一个难点。

解决方案:

Intial State
先建立一个粒子池,设计一个数据结构,设定系统包含的粒子总数量,每个粒子的位置、速度等。再有两个list,一个是Dead List,记录当前死亡的粒子,初始时包含所有粒子序号,还有一个是alive list,记录当前活着的粒子,初始时为空。
比如emitter发射了5个粒子,则从池子结尾取5个粒子(序号)放入alive list,同时把dead list的后5个序号清空。
在这里插入图片描述

Simulate
当时间跳转到下一次tick时,会新建一个alive list1,并依序检索alive list中的粒子,如果发现某个粒子死亡了,就会把这个粒子序号移到死亡列表中,并且在渲染时也跳过这个粒子,如果仍存活就照抄到alive list1中。
这个操作因为compute shader的发明变得容易,因为compute shader可以进行原子级操作。
同时,在更新完活着的粒子之后,还可以利用GPU进行frustum culling视角剔除(针对活着的粒子),并且计算它们的距离,写入距离buffer。
在这里插入图片描述

Sort, Render and Swap Alive Lists

接着,还需要进行排序、渲染和交换alive list:
1、排序。根据距离buffer对活着的剔除后的粒子排序
2、渲染。对排序后的粒子渲染
3、交换。交换alive list1和alive list,更新存活列表。
在这里插入图片描述

具体来说排序。GPU的排序类似归并算法,复杂度为nlogn。采取的方式是针对目标序列(排序后)的每一个位置设置一个线程,考虑它应该从两个列表中哪个取得。这样做会比每个源列表位置一个线程去考虑插入到哪里更简单,因为后者会让“写过程”跳来跳去不连续 。

同时利用深度缓冲还可以进行碰撞的检测,具体:
1、把粒子的当前位置投影到上一帧的屏幕空间纹理坐标(相当于投影到上一帧相机坐标系?)
2、读取上一帧的深度纹理图中的深度值
3、检查1和2中的深度值,判断是否碰撞了但又没完全穿过去(厚度值会被用到)
4、如果碰撞发生了,就计算碰撞表面法向和粒子反弹的方向
在这里插入图片描述

四、粒子应用

直接利用粒子来模拟物体,比如鸟群、大地图下行走的路人(因为很小),此时同样也有骨骼,但基本上每个顶点只受一个节点限制(简化版人体)。

在这种情况下,我们可以把原本一个例子的加速等行为换成更复杂的人体姿态动作,相当于每个particle设置了一个状态机。我们把这个particle的各种状态和对应的速度等属性的情况设置成一张纹理图。当particle的属性变化时就从纹理图中找到对应的状态不断切换。

Navigation Texture。在上述基础上,可以利用一个粒子一个人来模拟一个导航纹理图。具体来说,利用SDF来避免人走入建筑物内,然后依次也可以设定一个方向纹理图,当我们给一个粒子设定目的地和初始速度后,它会根据DT的场驱动着往目的地走。当然,过程中可以加一些随机性。
在这里插入图片描述

粒子系统在游戏中的应用早起是“预设型”,即在最初就设定好particle可能的行为,并用stack来表示和存储;后来又有“基于图“的设计,减少代码量增加灵活性;最好的是两者混合型,如下图:
在这里插入图片描述

相关文章:

游戏引擎中的粒子系统

一、粒子基础 粒子系统里有各种发射器(emitter),发射器发射粒子(particle)。 粒子是拥有位置、速度、大小尺寸、颜色和生命周期的3D模型。 粒子的生命周期中,包含产生(Spawn)、与环…...

哈佛大学商业评论 -- 第二篇:增强现实是如何工作的?

AR将全面融入公司发展战略! AR将成为人类和机器之间的新接口! AR将成为人类的关键技术之一! 请将此文转发给您的老板! --- 本文作者:Michael E.Porter和James E.Heppelmann 虽然物理世界是三维的,但大…...

『python爬虫』巨量http代理使用 每天白嫖1000ip(保姆级图文)

目录 注册 实名得到API链接和账密 Python3requests调用Scpay总结 欢迎关注 『python爬虫』 专栏,持续更新中 欢迎关注 『python爬虫』 专栏,持续更新中 注册 实名 注册巨量http 用户概览中领取1000ip,在动态代理中使用.用来测试一下还是不错的 得到AP…...

6-95 希尔排序(Java语言描述)

编程实现希尔排序函数。public static void shellSort(int arr[])。其中arr存放待排序的数据,数组长度不大于1000。 函数接口定义: /* 对长度为n的数组arr执行希尔排序 */ public static void shellSort(int arr[]); 请实现 shellSort函数,使排序后的数据从小到大排列。…...

JAVA面试大全之分布式篇

目录 1、一致性算法 1.1、什么是分布式系统的副本一致性?有哪些? 1.2、在分布式系统中有哪些常见的一致性算法?...

qt各种锁使用讲解

在Qt中,主要有以下几种锁的类型: 1. QMutex(互斥锁): 是最常见的锁类型,用于实现简单的互斥访问。可以通过lock()和unlock()手动控制锁的加锁和解锁。 QMutexLocker:是一个RAII类,…...

5.111 BCC工具之ext4dist.py解读

一,工具简介 ext4dist跟踪ext4的读取、写入、打开和fsync操作,并将其延迟总结为2的幂次方直方图。 二,代码示例 #!/usr/bin/env pythonfrom __future__ import print_function from bcc import BPF from time import sleep, strftime import argparse# symbols kallsyms …...

Rust 的 termion 库控制终端光标的位置

在控制台应用程序中,固定打印在屏幕的第一行通常涉及到控制终端光标的位置。Rust 标准库本身并不提供直接控制终端光标位置的功能,但你可以使用第三方库如 termion 来实现这个需求。 termion 是一个用于处理终端的 Rust 库,它提供了很多有用…...

ADB(Android Debug Bridge)操作命令详解及示例

ADB(Android Debug Bridge)是一个强大的命令行工具,它是Android SDK的一部分,主要用于Android设备(包括真实手机和平板电脑以及模拟器)的调试、系统控制和应用程序部署。 下面是一些ADB的常用命令&#xff…...

书生浦语训练营2期-第二节课笔记作业

目录 一、前置准备 1.1 电脑操作系统:windows 11 1.2 前置服务安装(避免访问127.0.0.1被拒绝) 1.2.1 iis安装并重启 1.2.2 openssh安装 1.2.3 openssh服务更改为自动模式 1.2.4 书生浦语平台 ssh配置 1.3 补充(前置服务ok…...

【日常积累】指定ruby版本环境安装

背景说明 在redis的5.0版本之前,使用redis提供的redis-trib创建redis集群时还需要依赖ruby环境。当然有时候我们自已也需要安装指定ruby版本环境。下面是安装时的大致过程,以及过程中遇到的问题解决。我使用的环境是centos7,小版本差别应该不…...

SOC内部集成网络MAC外设+ PHY网络芯片方案:MII/RMII 接口与 MDIO 接口

一. 简介 本文来了解一下常用的一种网络硬件方案:SOC内部集成网络MAC外设 PHY网络芯片方案。 其中涉及的 MII接口,RMII接口(MII接口与RMII接口二选一),MDIO接口,RJ45。 二. MII/RMII 接口,M…...

简单了解HTTP和HTTPS

HTTP的安全问题? 我们都知道HTTP是不安全的,而HTTPS是安全的,那HTTP有哪些安全问题呢?(考虑传输过程以及响应方) 明文传输,有窃听风险:HTTP协议无法加密数据,所有通信数…...

系列学习前端之第 9 章:一文搞懂 Node.js 和 nvm,掌握 npm

1、说说 Node.js Node.js 本质上是一款应用软件(本质上与QQ、微信一样),它可以运行 JavaScript 代码,这样就使得 JavaScript 能够脱离浏览器运行。Node.js 是基于 Google 的 V8 引擎,V8引擎执行 Javascript 的速度非常…...

超强命令行解析工具Apache Commons CLI

概述 为什么要写这篇文章呢?因为在读flink cdc3.0源码的时候发现了这个工具包,感觉很牛,之前写过shell命令,shell是用getopts来处理命令行参数的,但是其实写起来很麻烦,长时间不写已经完全忘记了,现在才发现原来java也有这种工具类,所以先学习一下这个的使用,也许之后自己在写…...

JAVAEE——多线程进阶,锁策略

文章目录 锁策略乐观锁和悲观锁乐观锁悲观锁两者的比较 读写锁重量级锁和轻量级锁重量级锁轻量级锁 自旋锁公平锁和非公平锁公平锁非公平锁 可重入锁和不可重入锁可重入锁不可重入锁 锁策略 乐观锁和悲观锁 乐观锁 什么是乐观锁呢?我们可以认为乐观锁比较自信&am…...

富文本编辑器Quill全套教程

Quill简介 Quill是一款现代的富文本编辑器,它以其API驱动的设计和对文本格式的深度理解而著称。与传统的富文本编辑器不同,Quill专注于以字符为中心,构建了一个直观且易于使用的API,使得开发者能够轻松地对文本进行格式化和编辑。…...

Swift 代码注释的使用

Swift代码注释的使用 在 iOS 开发中,代码注释是一种很好的实践,可以帮助他人更容易理解你的代码。通常可以在代码中使用注释来解释代码的功能、目的、实现细节等。下面是一些常见的 iOS 代码注释示例: 1. 单行注释: // 这是一个…...

蓝桥杯—DS1302

目录 1.管脚 2.时序&官方提供的读写函数 3.如何使用读写函数 4.如何在数码管中显示在DS1302中读取出的数据? 1.管脚 2.时序&官方提供的读写函数 /* # DS1302代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行…...

nginx: 集群环境配置搭建

nginx 集群环境搭建 1 ) 概述 nginx 本身就应该选择性能强劲的机器同时为了满足更多流量的需求, 多台nginx 机器做集群来满足强大的需求故而,我们需要一个负载均衡器,以及多台nginx的机器 这里负载均衡器应该有主从和热备,目前先使用一台来描…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

数据链路层的主要功能是什么

数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

网络编程(UDP编程)

思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...