unity particle system 优化

时间:2024-04-04 11:19:12

什么是粒子系统

官方解释: 粒子系统是在三维空间渲染出来的二维图像,主要用于烟,火,水滴,落叶等效果。一个粒子系统由粒子发射器、粒子动画器和粒子渲染器三个独立的部分组成。

unity渲染流程

在首先我觉得要想知道如何优化粒子系统以及为什么优化粒子系统,你要先搞懂unity的这个渲染流程在知道在什么地方着手优化。

  • CPU :
    1、检查场景物体,判断是否被渲染,不被渲染的物体被剔除(culled)–最耗费效率
    2、收集排序整理要被渲染的物体信息 (Draw Call) 一个dc包含了一个网格信息以及如何渲染的数据。将不同物体数据合并成一个dc的过程称为batching
    3、为每一个dc创建一个batch数据包
    4、CPU可能会发送一些命令用于变更GPU 一系列渲染相关的变量,这些变量被统称为渲染状态(render state),这些命令本身就是通常所说的SetPass call。仅当下一个需要被渲染的网格需要变更渲染状态的时候才需要发送。
    5、CPU 发送draw call 给GPU。Draw call 指示GPU 使用最近发送的SetPass Call 所提供的设置来渲染特定的网格。
    6、在有些情况下,一个batch 可能需要多于一个的pass。Pass 是着色器(shader)代码中的一节,一个新的pass 需要对render state 进行变更。对于batch 中的每一个pass,CPU 将发送一个新的SetPass call 并且再次发送draw call。
  • GPU:
    1、按照cup发送顺序处理渲染任务
    2、如果当前的任务是个SetPass call,GPU 更新render state。
    如果当前的任务是个draw call,GPU 渲染该mesh。此过程按照shader 代码的不同段落分步有序进行,此过程较为复杂,简单来说,其中一段称为顶点着色器(vertex shader)的代码告知GPU 如何处理网格的顶点,另一段称为片段着色器(fragment shader)的代码告知GPU 如何绘制每一个像素。
  • SetPassCall 、DrawCall 、 Batch
    Set Pass Call代表渲染状态切换,主要出现在材质不一致的时候,进行渲染状态切换。我们知道一个batch包括,提交vbo,提交ibo,提交shader,设置好硬件渲染状态,设置好光源属性等(注意提交纹理严格意义上并不包括在一个batch内,纹理可以被缓存并多帧复用)。如果一个batch和另一个batch使用的不是同种材质或者同一个材质的不同pass,那么就要触发一次set pass call来重新设定渲染状态。例如,Unity要渲染20个物体,这20个物体使用同种材质(但不一定mesh等价),假设两次dynamic batch各自合批了10个物体,则对于这次渲染,set pass call为1(只需要渲染一个材质),batch为2(向GPU提交了两次VBO,IBO等数据)。
    Draw call严格意义上,CPU每次调用图形API的渲染函数(使用OpenGL举例,是glDrawElements或者DrawIndexedPrimitive)都算作一次Draw Call,但是对于Unity而言,它可以多个Draw Call合并成一个Batch去渲染。

真正造成开销较大的地方,第一个在于在于切换渲染状态,第二在于整理和提交数据。在真正的实践过程当中,可以不用过于介意Draw call这个数字(因为没有提交数据或者切换渲染状态的话,其实多来几个draw call没什么所谓),但是Set Pass Call和Batch两个数字都要想办法降低。由于二者存在强相关性,那么通常降低一个,就一并可以降低第二个。

粒子系统非常多有什么问题

  • 帧率占用:从profiler中可以看到,粒子 的渲染是在子线程中进行渲染的,虽然在主线程占用不是很多,但是渲染过程中,如果说渲染线程压力过大的时候,主线程依然会出现等待(Gfx.WaitForPresent),从而对帧率产生影响。particleSystem.Updatejob 每一帧都会执行
    unity particle system 优化
  • 渲染的粒子越多,GPU的渲染压力越高,屏幕的每帧填充率越高,容易造成设备发热
    可能还导致别的问题,我这里就举例两点我觉得比较严重的问题,欢迎各位老板补充????

如何优化

制作建议
1:粒子是可以添加物理碰撞的,在制作小的多个的粒子的时候,要考虑要不要添加物理碰撞。建议是:不要添加,没必要有这么精准的碰撞;二是消耗影响性能
2:一个粒子产生多个dc的原因是因为,一个粒子是有多个部分组成的,子节点使用了不同的texture和matrial会导致增多dc,在粒子制作的时候,尽量把相同材质的粒子放在一起,避免穿插,打断dc。
3:对于粒子系统来说,对性能影响最大的还是overdraw的情况。所以在制作的过程中要注意检查overdraw
4:图的资源占用方面,尽量使用小的粒子图片,可以制作图集,用来放多个图。
5:如何使用一个图集一个material制作特效?material使用一个texture(图集),然后修改Texture Sheet Animation的渲染的frame。 下面的图是用一个matrial制作的四个特效只用了1个batches。
unity particle system 优化
以上所有内容了,欢迎各位大佬交流分享,积极指出错误。