您的位置:首页 > 其它

OGRE——渲染大量物体,批次(batch)

2012-09-13 20:43 274 查看
OGRE渲染物体,可以把物体作为InstancedGeometry,StaticGeometry,Entity实例来渲染。

区别:

InstancedGeometry:Pre-transforms and batches up meshes for efficient use as instanced geometry in a scene。也就是说,把所有网格作为一个instance geometry。

this shader instancing implementation stores only 80 times the object, and then re-uses the vertex data with different shader parameter.只可以存储同一物体80次,然后重用顶点数据使用不同的渲染参数。

可以每帧调整位置,方向,大小等

StaticGeometry:把所有网格作为一个静态几何体,这样每个材质就是一次批次。但是,看到一小部分,整个StaticGeometry也会全部都渲染的。

Entity:每个Entity包含一个Mesh。

每次渲染操作都是相当的耗费资源的。所以应该减少对DIP的调用。



OGRE的渲染流程



void SceneManager::renderSingleObject(Renderable* rend, const Pass* pass, ...)
{
     //...
     static RenderOperation ro;
     ro.srcRenderable = rend;
     //...
     mDestRenderSystem->_render(ro);
     //...
}

void SceneManager::SceneMgrQueuedRenderableVisitor::visit(Renderable* r)
{
   // Give SM a chance to eliminate
   if (targetSceneMgr->validateRenderableForRendering(mUsedPass, r))
   {
      // Render a single object, this will set up auto params if required
      targetSceneMgr->renderSingleObject(r, mUsedPass, scissoring, autoLights, manualLightList);
   }
}
   void QueuedRenderableCollection::acceptVisitorGrouped(
      QueuedRenderableVisitor* visitor) const
   {
      PassGroupRenderableMap::const_iterator ipass, ipassend;
      ipassend = mGrouped.end();
      for (ipass = mGrouped.begin(); ipass != ipassend; ++ipass)
      {
         // Fast bypass if this group is now empty
         if (ipass->second->empty()) continue;

         // Visit Pass - allow skip
         if (!visitor->visit(ipass->first))
            continue;

         RenderableList* rendList = ipass->second;
         RenderableList::const_iterator irend, irendend;
         irendend = rendList->end();
         for (irend = rendList->begin(); irend != irendend; ++irend)
         {
            // Visit Renderable
            visitor->visit(const_cast<Renderable*>(*irend));
         }
      }
 }


for (ipass = mGrouped.begin(); ipass != ipassend; ++ipass)

{

________//....

________RenderableList* rendList = ipass->second;

________for (irend = rendList->begin(); irend != irendend; ++irend)

______________ {

_________________visitor->visit(const_cast<Renderable*>(*irend));

______________ }

}

也就是说每个Rendable都会调用一次DIP。当把有相同的Pass的Rendable合并成一次时,可以减少对DIP的调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: