粒子系统优化记1

大概是从本周一开始的新一轮粒子系统优化,也算是最有成效的优化了。目前为止一直米有提交代码。如果是一周之前的代码的话,在打开我们的demo场景后默认视角下是30fps左右(fraps跑benchmark),如果是现在的代码的话,是40fps。(*゚▽゚)ノ效率高了30%左右?

(´-ι_-`)但是莫高兴的太早。我们先看看所谓的“优化”二字是个毛意思。

(•̅灬•̅ )一个游戏,高画质低画质都卡,玩家会喷“这游戏优化的不好”。对写代码的而言,优化就是想办法“压缩”代码把执行无谓的工作所用的时间给“挤”出去,或者把冗余数据给挤出去。(←不要抠字眼!)

(。・_・。)ノ但是如果卡是因为我之前的代码写得太捉基的话,这该算修BUG还是优化……(╬ ̄皿 ̄)=○#( ̄#)3 ̄)好吧我自扇耳光……

(•̅灬•̅ )而我这个纯用CPU堆粗来的粒子系统,它的优化……(´-ι_-`)没有多少跟GPU打交道的余地就是了。。。

(。・_・。)ノ然后碰上2B用户就捉基了。某部门某美术做了一个粒子实例,我不知道他用了Alpha值多低的贴图来制造出的滚滚黑烟……反正在我将程序写死为默认发射器同一时刻存活的粒子数设为1000之后,我看到他总共才二十几个粒子实例的场景……Σ( ° △ °|||)︴总共有2W多个粒子!!!!

玩毛啊!!!这跟你一个人物2W根骨骼有啥区别!!【好吧还是有区别的……shader里塞不进2W个参数……

这跟你一屏2W个带刚体动画的模型有啥区别!!【[._________.]⊿我还是别做这样的比较了。。。

(•̅灬•̅ )都是把编辑器界面的精度从0.01改为0.001之后所造成的恶果……美术连隔0.001秒发射一个粒子这种数据都敢填……

好吧吐槽完毕。以上只是今天跑去给编辑器界面加上了统计当前帧粒子数目的功能之后的发现。(•̅灬•̅ )顺便说一句我们的demo场景有100多个粒子实例(*゚▽゚)ノ,同一帧约3.1W个粒子。

(•̅灬•̅ )嗯,粒子系统目前米有做剔除,做了剔除我估计就用不着优化神马的啦。反正我估计国产RPG同一屏的粒子数目也不应该超过1W……

以上是今天所想要吐槽的废话。

本周显著影响粒子性能的大头有俩。

第一个是空循环。之前我不知道空循环会造成多么大的恶果,甚至都没有注意到Intel Parallel Studio XE里在那个if与continue上显示那么大的CPU时间实际是太多次空循环导致的……说来惭愧,这是最开始优化粒子系统的时候弄出来的问题。我为了防止内存的重复分配回收,给了一个发射器同一时刻存活的最大粒子数目,很2地维护了一个存储Unused粒子的index的列表。粒子载入的时候直接按最大数目分配内存,未使用的或者死掉的粒子打个Unused flag然后扔到Unused列表里去,然后需要新粒子的时候从Unused列表里拿一个index出来。但是问题在于我循环遍历粒子的方式是直接遍历整个粒子列表,碰到带Unused的粒子直接continue掉……

而当时我为了不影响美术已经做好的粒子,一狠心一咬牙把最大粒子数目给写成了1000.。。(눈_눈)然后我就每帧空循环了至少几十万次……(´-ι_-`)。。。

(눈_눈)现在改成了用一个列表存活着的粒子,用一个变量存当前活着的粒子的数目,如果某个粒子死了,就把当前这个粒子的index与最后一个活着的粒子的index交换,然后当前活着的粒子数目减一。。。遍历的时候遍历这个列表然后索引粒子……

第二个大头是数据提交的时候lock vertex buffer次数太频繁的问题。老生常谈了。之前是一个粒子实例,其同种类型的粒子使用一个vertex buffer,现在改成了所有粒子共用一个vertex buffer,每帧只对同种类型的粒子(其实现在只有sprite粒子= =,也就是矩形面片这一种粒子)lock,执行一次memcpy。我们的demo里100多个粒子实例,之前每帧lock了100次。(•̅灬•̅ )这部分代码是上周改的。。。

(。・_・。)ノ此外好像还有一些小头儿。

(´-ω-`)之前我把粒子修改器的循环放在了粒子循环的内部,因为我觉得粒子数目多嘛,这样做可以少几次循环遍历。但是当我试了把粒子遍历放到修改器的函数内之后,虽然多遍历了N次但是结果反而帧率提高了1-2fps。。。(๑⊙ლ⊙)可能是cache miss率降低了的问题。。。

(´-ω-`)说起来大头还有一个。粒子渲染坐标的生成。一个sprite四个顶点嘛,逻辑更新的时候不用考虑,但是实际渲染的时候4个顶点还是得要的。我这一步好死不死也是在CPU里算的ヽ(●-`Д´-)ノ引擎的渲染系统都是我后面那小帅哥弄的!我不会写shader!!所以只有用CPU!!ヽ(●-`Д´-)ノ!!!!如果这一步塞进GPU算的话,按照理想状态来看,应该能把现在的帧率从42fps提升到46fps。方法大概就是把每个粒子的size、rotation,当然可能还有方向向量之流塞到顶点里去。所谓的理想状态从42fps提升到46fps是我把所有顶点的计算全去掉,填充了空数据的结果。。。除此之外这一块儿似乎还有一些问题。


int i = 0;
for( each particles blah, blah, )//each particle contains 4 vertices
{
particleVertices[i] = blah;
particleVertices[i+1] = blah;
particleVertices[i+2] = blah;
particleVertices[i+3] = blah;
i += 4;
}

总之下周再看看吧……

(´-ω-`)话说当我看到那个总共二十几个粒子实例的场景里居然有2w个粒子之后……瞬间有种“爱谁优化谁优化,劳资不干了!”的赶脚。

今天就先写到这里吧。

《粒子系统优化记1》有2个想法

    1. 欢迎菊苣光临!!!

      粒子基本是带透明的各种面片~

      各种
      横着的(´-ω-`)
      (」・ω・)」竖着的~
      (/・ω・)/斜着的~
      _(:3」∠)_躺着的~

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>