Ogre的一些渲染心得

来源:互联网 发布:java function 使用 编辑:程序博客网 时间:2024/06/01 08:39
 

做商业网络游戏的话,效率是一个不可避免的话题,为了留更多的空间给客户端的逻辑,那么渲染模块就应该尽量高效. 小弟只浅谈一下Ogre的渲染优化,以大家熟悉的天龙八部为例. 以网上流传版本的天龙代码来看,Ogre和CEGUI部分的渲染都有严重的性能问题, Ogre: 地形的实现,一个tile,只按材质做了批次优化,并没有按材质做摄像机的裁剪,导致游戏视角下批次增加很多 静态实体的合并,完全错误的做法,同地形一样,只优化了批次,没做摄像机的裁剪. CEGUI: 由于CEGUI本身对字体重绘处理的缺陷,导致缓存的字体没用,每帧都会计算位置排版之类,效率其低,改进的方法当然有, 比如普通字体可以当图片去缓存,最好的方式还是移植到0.75,效率立马提高N倍. CEGUI我就懒得说了,只谈谈Ogre部分的优化.

 

优化之前,先理解优化的原理.

1).Renderable和渲染批次:

      渲染批次是神马?自己去看教程,简单讲,他极大地影响渲染的效率,所以渲染批次尽量少.比如10个批次,渲染10000个三角形,比10000个批次,渲染10个三角形速度快得多,

     怎么才算一个批次?渲染一个Renderable就算一个批次,Renderable是Ogre中最小的渲染单元,所有需要渲染的对象都继承与此.

一句话:一个renderable等于一个batching(渲染批次),减少场景中的renerable,就减少了批次.

     怎么减少renderable?比如2棵材质一样的树(2个renderable),我可以合成一个棵树(1个renderable),合成办法2种,一种是美工在max里面静态合并,一种是程序动态合并(StaticGeometry)

值得一提的是,一个mesh不一定是一个批次,submesh才是,如果一个mesh有2个不同材质的submesh,正常,

如果有2个同材质的submesh,不好,应该立即找美工,骂他一顿.说:为什么不把同材质的2个submesh合成一个?

2)MovableObject和摄像机裁剪

     Ogre的OctreeSceneManager的摄像机裁剪,是以包围盒为准,那么就意味着有包围盒的对象才可以被裁剪,Renderable有包围合么?没有!但是MovableObject就有,MovableObject是移动对象的基本,同时继承ShadowCaster,可以投射阴影.


值得一提的是,摄像机的裁剪并不是以MovableObject而单位,而是以SceneNode为单位,只有挂接到SceneNode上的MovableObject才

会被裁剪,


3)要渲染,Renderable,要移动,Moveable,如果都要,最简单的对象应该就是SimpleRenderable : public MovableObject, public Renderable


想起以前自己做地形用mesh去做,很笨,效率不行,应该mesh类太大,包含了太多不需要的东西,用SimpleRenderable是最高效率的.

 

地形的实现,一种是用拼格子,每个格子一个四边形,不共用顶点,不能lod,但是一个格子就可以多层纹理,适合2.5D视角游戏,比如魔兽3和天龙

另一种就是主流3D游戏做法,共用顶点,lod,缺点是一个地形page的纹理层数和前面那种地形的一个格子一样多...比如8层,其实已经足够,纹理过渡也很自然.拼格子的纹理过渡始终很丑.

1)天龙的地形实现原理如下.

整个地形分很多tile组合而成,class TerrainTile : public Ogre::MovableObject

一个tile是一个MovableObject,用来摄像机裁剪.

每个tile包含一个RenderableList;一个tile里面,同材质的格子会被做成一个Renderable,

tile大小事32,那么有32*32 个格子,假如这些格子用了10种不同的材质,那么这些格子就被做成10个Renderable

渲染没问题,按材质分批次渲染,10个批次,

但是摄像机裁剪有问题,摄像机只能按tile去裁剪,因为tile是MovableObject,而那10个Renderable却不能单独裁剪

这样的话,比如,摄像机只看到这个tile.32*32格子中最边上的一个格子,也会把整个tile渲染,10个批次....

如果把10个Renderable都做成MovableObject,可以裁剪,那么只看到最边上这个格子的话,只会渲染最边上的那个Renderable,1个批次.

实践证明,对于2.5D视角游戏,地形的批次几乎可以降低一半

2)tile的大小

tile设想多大,效率最高?这和摄像机有关,最好是游戏视角,摄像机刚好看那么大的范围再大一点点,天龙的32,对于他的视角,是合理的.

3)texture atlas

天龙的地表的纹理很小,128*256 导致材质很多,批次就很多,如果做texture atlas把小纹理合成大纹理,批次就会减少很多,但是也会有其他一些附加问题,比如mipmap导致的缝隙,解决缝隙,国外其实有不少解决方法, 比如可以写shader,在不同的mipmap下调整纹理坐标,或者预留纹理坐标,在已有纹理上加一圈和边缘相同的像素,这样就不会取到其他纹理像素,导致缝隙.

天龙2增加了天空视角,即使看到很多场景,渲染效率却没有受到多大影响,所以个人认为,他应该做了texture atlas,减少了整个场景的批次,不然实现不了天空视角.

 

转载声明,转自:http://blog.csdn.net/pizi0475/article/details/6315834

原创粉丝点击