OGRE针对图形API调用的效率优化

1649 篇文章 11 订阅
1623 篇文章 22 订阅

http://blog.163.com/ding_liang1989/blog/static/168788329201362005946890/


本文所针对的OGRE版本为1.65,因为本人目前公司项目使用这个版本。


本文所讲述的内容是不改变任何渲染流程,直接从最底层Direct3D API 调用上去抠OGRE的性能。

1、Shader参数的分类。这一点在后续版本中做了,但是在1.65版本中是没有的。通常来说,同一个Shader的参数可以分为以下几种:全局常量(值被手动改变或者切Shader的时候传),物件常量(一个DrawCall传一次),Light常量(一个光源传一次),这种分类能最大化利用目前网游开发需要的Shader,OGRE后续版本中加上的分类还多了一个Pass常量(用同一个Shader画一个物件多次,每画一次传一次),用于多Pass光照。传Shader参数的API是很耗时的,而且像光照之类的Shader,需求的参数又非常多,在OGRE1.65中,每个批次都要传将全部的参数传一次,这是非常耗时的,所以要将这部分代码从后续版本中移植过来。

1.5、新版本的做法其实严格来说也有一定缺陷,在切换Shader时,会传所有的GPU参数,更具体的说,切换了VS,却要去更新全部的PS参数,这显然是不合理的,这部分需要自己改进。

2、频繁的Shader切换。OGRE在调用SetXXXShader API时是没有cache机制的,也就是说,无论当前要设置的Shader和上一次设置的Shader是否相同,都会在每个批次设置一次,而SetXXXShader又是非常耗时的,且会导致所有GPU参数的传递。解决方法是根据名字判断一下,和上一次的不一样才Set。

3、SetRenderState之前会调用GetRenderState来做 cache,这样比缓存一个值要慢。

4、过于简单的材质排序。OGRE的材质排序只考虑了pass的顺序和前两张贴图,对于渲染状态是一点都不顾及。一个32位的hash,pass占了4位,也就是说最多支持11个Pass,如果光照处理采用的是单Pass光照,对于物件的渲染最多2个Pass就够了,绝大多数都只需要一个Pass。所以Pass我给了1位,空出3位来可以随便根据项目具体情况找几个开销最大的状态来考虑进去,本人的做法是先把hash位数提高到64位,考虑Pass-Shader-Texture-State。

5、频繁的VertexDeclartion切换。同屏画几百个批次,顶点声明就那么几种,而OGRE的做法是每次渲染都调用Set VertexDeclartion API,而这个API是很耗时的,所以需要 cache 一下。

6、频繁的顶点/索引Buffer切换。如果同一个Mesh连续画一百个批次,OGRE会SetStreamSource/SetIndice一百次,如果顶点分流,还会成倍增长,而这两个API都是很耗时的,所以同样需要 cache 一下。

7、虽然 cache 了Texture,但Texture相关的StageState和SamplerState都没有 cache ,使得按纹理排序获得的收益降低,需要 cache 一下,与RenderState一样,自己 cache ,去掉调用API的Get函数。

以上这些是本人最近两天做优化的总结,大部分都是由于没有 cache而造成的不必要的DX API调用。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值