游戏引擎的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模板网!

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

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

相关文章

  • 算法设计思想——动态规划

    是一种常见的算法设计方法,用于解决一类重叠子问题的优化问题。他的基本思想是将问题分解成多个重叠的子问题,递归求解,并将子问题的求解缓存起来,避免重复计算,从而得到问题的解。 动态规划通常适用于以下两个条件的问题: 1.重叠子问题:原问题可以分解为若

    2024年02月03日
    浏览(48)
  • 【Spring】核心与设计思想

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

    2024年02月08日
    浏览(45)
  • Spring 核心与设计思想

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

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

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

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

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

    2023年04月15日
    浏览(47)
  • 从架构设计思想出发看Flutter

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

    2024年02月07日
    浏览(74)
  • Spring框架概述及核心设计思想

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

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

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

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

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

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

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

    2024年02月13日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包