一直想等得闲开始写博客,却总是“说的未来到底多久才来”,这两天在研究OGRE中渲染优化的问题,无意中搜到一大牛在博客园的博客http://www.cnblogs.com/lancidie/ 好像突然又看到了更大的OGRE世界,夜深人静,想想确实该抛弃掉一些无谓的东西,专心做这些想做的事了,好吧,博客园的处女作就写写这两天关于场景管理的学习笔记吧。大多都来源于网上的资料,配以个人的理解。

  

  目前的大多数有游戏引擎都采用场景图(scene graph)的概念对场景中的模型进行管理。如图:

  

  场景图其实是一棵树,上面挂接结点,结点则可以依附模型实体(OGRE中为entity,即mesh),当然还包括灯光、摄像机等。这种方式对场景模型管理的好处就是可以应用各种不同的算法对这些模型进行管理,一般一款游戏引擎的场景管理器需要负责这几件事:

·在场景中创建和放置活动物体、灯光以及摄像机,并维护他们的在场景图中的周游和变换。

·载入和布置世界地图(World geometry,与活动实体不同,世界地图是巨大且可以延伸的,通常情况下是不可移动的,比如一个完整的BSP地图)。

·对场景查询(Scene Queries)的支持,比如回答“在世界的某个原型空间内,都包含了那些物体”。

·剔除不可见物体并且将可见物体放入渲染队列。

·根据当前和渲染物体的透视图,对无方向的光源(Nondirectional Light)进行组织和排序(按由近到远)。

·设置并且渲染场景中的阴影。

·渲染场景中的其他物体,如背景和天空盒

·发送组织好的内容到渲染系统执行渲染

 

  而其中场景图与其中第3、4点是最有直接联系,OGRE中不同的场景算法是通过插件的,主要有:

  1 八叉树场景管理器

  2 地形场景管理器

  3 自然场景管理器

  4 分页场景管理器

  5 BSP场景管理器

  6 DotSceneOctree场景管理器    

  其中较为常见的是1、2两种,SDK中就有。

  创建场景管理器的代码诸如:

  mRoot->createSceneManager(ST_GENERIC);  

  (如果加载了八叉树插件,将创建八叉树,如果加载DotSceneOctree插件,将创建DotSceneOctree,根据文档上说八叉树适宜管理户外场景,目前不知道为什么,否则则为最基本场景管理器)

  mRoot->createSceneManager(ST_EXTERIOR_CLOSE);

  (创建地形场景管理器,从字面上意思理解也是一种适合户外场景的)

  mRoot->createSceneManager(ST_EXTERIOR_FAR);

  (创建自然场景管理器)    

  mRoot->createSceneManager(ST_EXTERIOR_REAL_FAR);

  (分页场景管理器)

  mRoot->createSceneManager(ST_INTERIOR);

  (BSP场景管理,字面上适合室内场景管理)

  以上为较早版本OGRE代码(目前也兼容),新版本的代码诸如mRoot->createSceneManager("OctreeSceneManager");的就不一一累赘了。

  八叉树对于场景的优化具有很重要的意义,关于什么是八叉树,大家可以到百度百科上看,这里贴一张OGRE中八叉树的UML图:

  

  结点的插入、视锥剔除和查找等等一大堆麻烦事都交给了管理器,我们所要做的只是考虑将我们的场景如何划分为mesh和submesh文件,使得场景管理器发挥最大作用。此话怎解?因为OGRE中八叉树的视锥剔除是根据SceneNode(mesh级别的),所以mesh应该是分的越细越好?但是mesh 过多又会引起载入资源过慢的问题。而RenderSystem的渲染单位则是Renderable(submesh级别的),所以应尽量将同样材质的东西绑定为一个submesh。总之,我得出一个结论,假设美工在制作一个港口模型,首先将位置相近的草、树之类的一定要作为一个submesh,然后在与周围的建筑(一般是一个建筑一个submesh,因为建筑材质不同)绑定为一个mesh。这样则可以取得一个视锥剔除、载入资源、渲染更少批次等方面达到一个较优解,至于static geometry的概念,我想只要美工把模型设计好了,就可以无需考虑了。

 

  终于把这几天对场景管理优化这一块学到的东西整理完了,毕竟不是教学文章,比较随性,想起之前在OGRE上花了那么多的功夫,不整理整理实在浪费了,以后会慢慢回忆起来一点点补充。

posted on 2011-09-17 21:18  云 溪  阅读(781)  评论(0编辑  收藏  举报