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

这篇具有很好参考价值的文章主要介绍了游戏引擎的cpu/gpu粒子系统设计思想。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

开篇

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

粒子系统的设计思想

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

游戏引擎的cpu/gpu粒子系统设计思想,游戏引擎,unity,ue4,图形渲染

 在早期的桌面系统中实现的粒子全是用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,而并不需要每回传入大量的顶点了

使用之前:

游戏引擎的cpu/gpu粒子系统设计思想,游戏引擎,unity,ue4,图形渲染

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

使用之后:

游戏引擎的cpu/gpu粒子系统设计思想,游戏引擎,unity,ue4,图形渲染

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

使用SMID优化

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

使用SIMD指令加速计算_星空_MAX的博客-CSDN博客

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

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

游戏引擎的cpu/gpu粒子系统设计思想,游戏引擎,unity,ue4,图形渲染

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


//定义粒子的组件集合
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中,这样每回就可以根据这个信息去更新顶点信息,重新传入顶点着色器中去做渲染

整体流程如下:

游戏引擎的cpu/gpu粒子系统设计思想,游戏引擎,unity,ue4,图形渲染

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

带来的问题

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

游戏引擎的cpu/gpu粒子系统设计思想,游戏引擎,unity,ue4,图形渲染

结尾

粒子系统还有其他很多部分,可做优化的部分非常多,我这里只介绍了一些粒子系统设计的基础思想,其他更全面的内容网上很多,就不赘述了文章来源地址https://www.toymoban.com/news/detail-532498.html

到了这里,关于游戏引擎的cpu/gpu粒子系统设计思想的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Spring核心设计思想

    Spring核心设计思想

    目录 前言: Spring是什么 什么是IoC 传统开发思想 IoC开发思想 Spring IoC 什么是DI 小结:     官网中提出:Spring makes programming Java quicker, easier, and safer for everybody. Spring’s focus on speed, simplicity, and productivity has made it the world\\\'s most popular Java framework.     Spring 使编程 Java 对每个人来

    2023年04月17日
    浏览(9)
  • 【Spring】核心与设计思想

    【Spring】核心与设计思想

     哈喽,哈喽,大家好~ 我是你们的老朋友: 保护小周ღ   谈起Java 圈子里的框架,最年长最耀眼的莫过于 Spring 框架啦,如今已成为最流行、最广泛使用的Java开发框架之一。不知道大家有没有在使用 Spring 框架的时候思考过这些问题, 什么是框架?Spring 是什么?如何理解

    2024年02月08日
    浏览(11)
  • 闪电网络协议设计思想剖析

    闪电网络协议设计思想剖析

    闪电网络可能是比特币之上部署的最受期待的技术创新。闪电网络,为由 Joseph Poon 和 Tadge Dryja 于2015年首次提出的支付层,承诺支持: 用户之间几乎无限数量的链下交易, 几乎免费, 同时利用比特币提供的安全性。 2016年时,至少三个公司——Poon 和 Dryja 的 Lightning、 Block

    2024年03月20日
    浏览(11)
  • Spring 核心与设计思想

    ✏️作者:银河罐头 📋系列专栏:JavaEE 🌲 “种一棵树最好的时间是十年前,其次是现在” 通常所说的 Spring 指的是 Spring Framework(Spring 框架)。 Spring 是包含多种工具方法的 IoC 容器。 IoC(Inversion of Control): 控制反转 \\\"控制反转\\\"又是什么意思? 下面以一个程序来举例。 假如我

    2024年02月02日
    浏览(10)
  • Spring框架核心与设计思想

    Spring框架核心与设计思想

    我们一般所说的Spring指的是Spring Framework(Spring 框架),它是一个开源的框架,Spring支持广泛的应用场景,它可以让Java企业级的应用程序开发变得更简单,官方一点的回答:spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级

    2023年04月15日
    浏览(14)
  • Spring框架概述及核心设计思想

    Spring框架概述及核心设计思想

    我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃而庞大的社区,这就是它之所以能长久不衰的原因;Spring 支持广泛的应用场景,它可以让 Java 企业级的应用程序开发起来更简单。 用⼀句话概括 Spring: Spring 框架是包含了众多工具方法的

    2024年02月16日
    浏览(9)
  • 从架构设计思想出发看Flutter

    Flutter 是一种流行的移动应用程序开发框架,它的设计特点之一是可以使用单一代码库构建 iOS 和 Android 应用程序。然而,对于功能比较多、模块比较复杂的应用程序,仅凭单一的代码库就可能导致代码的复杂性和维护难度的增加。在这种情况下,通过合适的应用程序架构设计

    2024年02月07日
    浏览(8)
  • 【JavaEE进阶】Spring核心与设计思想

    【JavaEE进阶】Spring核心与设计思想

    我们通常所说的 Spring 指的是 Spring Framework (Spring 框架),它是一个轻量级的 Java 开源框架,有着活跃庞⼤的社区。Spring 是为了解决企业应用开发的复杂性而创建的,不仅⽀持⼴泛的应⽤场景,还让 Java 企业级的应⽤程序开发更加简单。 如何简单地使⽤⼀句话概括 Spring:

    2024年02月13日
    浏览(13)
  • Cola4.0 - DDD 设计思想

    COLA提供了一整套代码架构,拿来即用。 其中包含了很多架构设计思想,包括讨论度很高的领域驱动设计DDD等。 COLA 的分层是一种经过改良的三层架构,主要是讲传统的业务逻辑层拆分为展示层、应用层、领域层和基础设施层。 展示层(Presentation Layer):负责以 Rest 的风格接

    2024年02月08日
    浏览(9)
  • 【JavaEE进阶】 Spring核⼼与设计思想

    【JavaEE进阶】 Spring核⼼与设计思想

    我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。 ⽤⼀句话概括 Spring: Spring 是包含了众多⼯具⽅法的 I

    2024年02月04日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包