游戏引擎的cpu/gpu粒子系统设计思想

news2024/12/24 8:57:52

开篇

网上有很多篇粒子系统源码解析,但是只是简单的接口罗列,没有从最原理出发去讲清楚粒子系统的来龙去脉,我将从粒子系统的本质去讲清楚它的设计理念,当理解了它的理念以后,很多粒子遇到的问题就会迎刃解决了,这篇文章主讲粒子的实现和一些框架级的优化方式,其实有很多优化细节就不赘述

粒子系统的设计思想

在早期游戏发展的时候,有一些粒子效果是实现一些鼠标特效的,比如《刀剑封魔录》中滑动鼠标后,鼠标本身就会作为一个粒子发射器,在鼠标拖动后,会产生很多粒子并随着时间消亡,这就是最早的粒子系统模型

 在早期的桌面系统中实现的粒子全是用cpu在屏幕上渲染的,如果需要世界中的3D粒子,则会将世界坐标转换为屏幕坐标,在屏幕指定位置渲染个粒子,而且这个粒子是每一帧去更新的

我给一个imgui类型渲染系统的粒子伪代码方便大家去理解,每一帧都去更新所有粒子的信息,当然现代游戏引擎粒子实现也类似于此

//定义粒子结构
struct particle

{
	float x;
	float y;
	image  img;
}

//定义粒子集合
vector<particle> particles

//设置粒子位置
void setparticlepositon(particle &p)
{
	p.x++;
	p.y++;
}

tick::update()  //每一帧更行所有需要渲染的信息
{
	for(auto i : particles)
	{    
		setparticlepositon(i);//循环更新粒子位置
		draw(i);//循环更新粒子绘制
	}
}

更复杂的话就是定义每个粒子的周期,并定义粒子发射器,另外可以在setparticlepositon中设置更复杂的更新条件

class ParticleEmitter{
protected:
    void Tick() {
        Spawn();                //生成阶段:创建新粒子
        UpdateAndRecycle();     //更新阶段:更新每个粒子的状态数据并回收已死亡的粒子
        Render();               //渲染阶段:使用粒子渲染器将粒子效果渲染出来
    }
private:
    vector<Particle> Particles;

};

万变不离其宗,都是源于这个思想

既然有大量相同的粒子,那么结合现代游戏引擎的特性,可以用到实例化(Instancing),将相同的mesh和材质用一套,大大减少了数据量,另外也可以用GPU粒子优化

使用几何着色器做优化

Nvidia在2006年的GeForce 8系列中出了DirectX 10.0,并推出了几何着色器

简单说,就是几何着色器可以把单个顶点扩充成多个顶点,如果粒子的mesh都一样的话,只需要从顶点着色器中传入的单个顶点和扩展规则,就可以生成想渲染的粒子mesh,而并不需要每回传入大量的顶点了

使用之前:

可见每个粒子需要传入五个位置然后生成五角星 

使用之后:

 想渲染一个五角星只要传入一个顶点,就可以用几何着色器扩充为五角星,大大减少了draw所占的带宽

使用SMID粒子做的优化

关于smid的介绍我前面有篇文章可以看看,这里就不赘述它的原理了

(1条消息) 使用SIMD指令加速计算_星空_MAX的博客-CSDN博客

这种情况试用语cpu对大量粒子计算和更新的情况

unreal引擎的nigara和chaos就是用这种缓存友好的内存布局,和unity的ECS架构原理一样

 写个大概的数据结构参考一下:


//定义粒子的组件集合
vector<particle> particlesx;
vector<particle> particlesy;


//设置粒子x位置
void setparticlepositonx(particlex &px)
{
	px++;
}
//设置粒子y位置
void setparticlepositonx(particley &py)
{
	py++;
}

//定义粒子和组件集合
class particle
{
	vector<particle> *particlesx = particlesx;
	vector<particle> *particlesx = particlesy;
}

//定义粒子集合
vector<particle> particles;

tick::update()  //每一帧更行所有需要渲染的信息
{
	for(auto i : particlesx)
	{    
		setparticlepositonx(i);//循环更新粒子位置	
	}
	
	for(auto i : particlesy)
	{    
		setparticlepositony(i);//循环更新粒子位置	
	}
	
	for(auto i : particles)
	{    
	 	draw(i);//循环更新粒子绘制
	}
}

使用GPU粒子做的优化

CPU粒子设计上和我上一节提到的东西大同小异,不过原来的draw是CPU去绘制,现代会把这个内容送到GPU,会调用一次drawcall,但是粒子的消耗消耗会非常大,粒子渲染的数量非常有限

这时候能不能把把粒子更新的逻辑放在gpu里面呢,当然可以了

同样是DirectX 10.0引用了Stream Output的新特性,在OpenGL3.0中也加入了这种特性,不过在OpenGL称为Transform Feedback,在顶点着色器或者几何着色器之后,可以把顶点数据缓存到这个结构中,而这个结构在gpu中,这样每回就可以根据这个信息去更新顶点信息,重新传入顶点着色器中去做渲染

整体流程如下:

 这时候就会发现GPU和cpu可以不进行数据传输了,粒子完成自我更新,大大减少了传输量和cpu的计算负担

带来的问题

如果用gpu粒子的话无法实时计算出剔除范围了,因为剔除步骤在传入顶点着色器之前,所以一开始就需要传入效果的bounds,并预估出粒子的最大范围,否则可能出现特效消失的问题

结尾

粒子系统还有其他很多部分,可做优化的部分非常多,我这里只介绍了一些粒子系统设计的基础思想,其他更全面的内容网上很多,就不赘述了

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

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

相关文章

常用的 Vs Code插件

推荐下自己在使用的 vs code 插件 1. Vue VSCode Snippets / Vue 3 Snippets 功能&#xff1a; 提供vue 相关代码块 2. Git History 功能&#xff1a;查看文件git提交历史 用法&#xff1a;右键你想要查看的文件&#xff0c;选 Git:Open File History 3. GitLens — Git …

LVS+Keepalived架构(负载均衡高可用集群)

一、高可用简介 普通的群集的部署是通过一台调度器控制调配多台节点服务器进行业务请求的处理&#xff0c;但是仅仅是一台调度器&#xff0c;就会存在极大的单点故障风险&#xff0c;当该调度器的链路或则调度器本身出现故障时&#xff0c;就会导致整个业务的无法正常进行 而高…

超越传统标注方法:doccano平台提供智能化数据标注解决方案

目录 前言一、doccano的介绍、安装1-1、doccano的介绍1-2、doccano的安装、初始化配置 二、序列标注任务2-1、登录2-2、创建任务2-3、数据上传2-4、添加标签2-5、任务标注2-6、数据导出 总结 前言 Doccano是一种用于文本标注的开源工具&#xff0c;旨在简化和加速标注任务的进行…

RocketMQ5.0--定时消息

RocketMQ5.0–定时消息 一、定时消息概览 定时消息或延迟消息是指消息发送到Broker后&#xff0c;并不立即被消费而是要等到特定的时间后才能被消费。RocketMQ并不支持任意的时间精度延迟&#xff0c;只支持特定延迟时间的延迟消息。 消息延迟级别在Broker端通过MessageStore…

vue中控制element表格列的显示与隐藏

背景 根据‘执行进度计算方式’的单选框里面的选项不同&#xff0c;展示不同的column 按最小制剂单位统计: 按含量统计: 实现方式 就是拿到选项框里面的值&#xff0c;再根据里面的值来判断哪些column显示和隐藏&#xff1b;关于显示和隐藏可以设置变量&#xff1b; <…

SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Spring Data Spring Data是一个用于简化数据库访问和操作的开源框架&#xff0c;为开发人员提供了一种通用的方式来处理不同类型的数据存储&#xff0c;例如关系型数据…

android13(T) Settings 主页面 Suggestion 菜单源码分析

1、什么是 Suggestion 菜单 呐&#xff0c;下面这个就是 Suggestion 菜单&#xff0c;一般出现在设置主界面最上方位置。 出现时机需要满足三个条件&#xff0c;1、设备不是 LowRam 设备 2、启用 settings_contextual_home 特性 3、在开机一定时间后(一般是几天&#xff0c;具…

山西电力市场日前价格预测【2023-07-08】

日前价格预测 预测明日&#xff08;2023-07-08&#xff09;山西电力市场全天平均日前电价为341.87元/MWh。其中&#xff0c;最高日前电价为871.53元/MWh&#xff0c;预计出现在22: 15。最低日前电价为143.16元/MWh&#xff0c;预计出现在13: 30。以上预测仅供学习参考&#xff…

缓存设计(本地缓存 + 分布式缓存)

缓存设计 前言正文缓存对象缓存服务缓存策略本地缓存Guava的使用 分布式缓存Redis缓存分布式缓存的生命周期分布式缓存的一致性问题 源码解读从缓存中获取秒杀品 分布式锁 总结参考链接 前言 大家好&#xff0c;我是练习两年半的Java练习生&#xff0c;本篇文章会分析秒杀系统…

el-form实现其中一个填写即可的校验

<el-formref"form":model"formData":rules"formRules"label-width"130px"><el-row :gutter"24"><el-col :span"12"><el-form-item label"司机姓名 :" prop"driverName"…

【贪心+最小子段和】EDU151 D

Problem - D - Codeforces 题意&#xff1a; 思路&#xff1a; 首先K是1e18的范围&#xff0c;不能去枚举&#xff0c;那么就去考虑猜测结论 手推样例&#xff1a; 初步可以猜测&#xff0c;K应该取的是某个峰值 结论是&#xff0c;K应该取最小子段和的左端点 因为当前缀和…

【Qt QML入门】第一个Quick应用

运行结果&#xff1a; 打开Qt Creator&#xff0c;创建一个Qt Quick Qpplication&#xff0c;IDE为我们创建一个应用工程&#xff0c;其中包含如下文件&#xff1a; .pro工程文件&#xff0c;我们通过它来打开整个工程&#xff1a; QT quick# You can make your code fail to…

这个618,项目经理竟然只能买它

早上好&#xff0c;我是老原。 转眼就来到了2023年年中&#xff0c;你们的个人成长计划启动了吗&#xff1f; 比如读书计划。 最近有不少粉丝朋友私信老原&#xff0c;希望能推荐一些可以帮自己“进化”的神作。 每个人的基础不同&#xff0c;想要“进化”还是得对症下药才…

C# --- 类型安全 与 var关键字

C# --- 类型安全 与 var关键字 什么是类型安全var关键字 什么是类型安全 类型安全就是编译器在编译阶段会检查变量内容和变量类型是否匹配, 如果不匹配会抛出错误类型安全的语言包括Java, C, C#等类型不安全的语言有JavaScript 下面这段代码是JavaScript, 编译器不会进行类型检…

git在工作中如何搭建和运用(巨详细!!)

最近有点闲&#xff0c;出一版git在实际公司上的一些运用 1&#xff0c;下载git&#xff0c; 下载git就不多说了&#xff0c;官方上下载安装就好了。 2&#xff0c;初始化 下载安装完成后&#xff0c;找个项目的空文件夹进去&#xff0c;右键点击git bash here &#xff0c;…

servlet和form和session表单实现最简单的登录跳转功能(详解,文末付源码)

目录 第一步&#xff1a;配置环境 在pom.xml引入servlet等依赖 这段代码赋值粘贴进web.xml 第二步&#xff1a;编写前端html的form表单 html代码&#xff08;复制这个&#xff09; 第三步&#xff1a;编写登录的java loginservlet代码&#xff08;复制这个&#xff09; 解释…

vue使用element plus引入ElMessage样式失效的问题

样式失效如图&#xff1a; 我使用的是按需引用&#xff0c;所以在main.js中直接导入下面样式就行&#xff1a; import element-plus/theme-chalk/index.css

Luogu P1280.尼克的任务

Luogu P1280.尼克的任务 原题点这里 思路 方法一&#xff1a;动态规划 这是一道动态规划的题目。 步骤主要分 5 5 5 步&#xff1a; 状态的定义转移式的推到递推顺序的判定边界的确定结果的输出 下面&#xff0c;我们针对这道题&#xff0c;细细地讲解一下每一个步骤 一…

MYSQL单表数据量达到多少时性能会严重下降的问题探讨!

不知从什么时候开始&#xff0c;有着MySQL单表数据量超过2000万性能急剧下降的说法。 在中国互联网技术圈流传着这么一个说法&#xff1a;MySQL 单表数据量大于 2000 万行&#xff0c;性能会明显下降。事实上&#xff0c;这个传闻据说最早起源于百度。具体情况大概是这样的&am…

PS 魔棒选区工具使用方法

我们现在PS中打开一个项目 然后 如下图 在工具左侧 选择魔棒工具 选择魔棒工具之后 我们的鼠标会变成像一个魔法棒一样的东西 我们拿着魔棒工具 在下图指向位置点一下 就可以看到 它在我们整个图上生成了一些选区 这个工具本身也带有一些色彩识别的功能 就相当于 你点的这…