三角形带优化库nvtrisrip的使用-创新互联

nvtrisrip是NVIDIA提供的一个开源优化库,这个库可以将三角形顶点索引数组转换为三角形带索引数组。可以极大的提高渲染速度。

NVIDIA这个库的官方地址是:
http://www.nvidia.com/object/nvtristrip_library.html

不过这里代码不全也不够新,推荐从GitHub上下载:
https://github.com/turbulenz/NvTriStrip

下载完毕后,我们把下面文件夹中的源代码加入到项目中:
/NvTriStrip/include
/NvTriStrip/src

一共为6个文件

创新互联是一家专业提供易门企业网站建设,专注与成都网站设计、成都网站建设、H5建站、小程序制作等业务。10年已为易门众多企业、政府机构等服务。创新互联专业网络公司优惠进行中。

三角形带优化库nvtrisrip的使用

需要注意的是VertexCache类有个非常奇怪的设计,在.h和.cpp中同时有两套实现代码。这会导致重定义,我们可以把.h中的代码注释起来。另外还需要修改entries变量为unsign short类型。


#ifndef VERTEX_CACHE_H
 
#define VERTEX_CACHE_H
 
#include 
 
class VertexCache
{
     
public:
     
    VertexCache(int size);
//  {
//      numEntries = size;
//     
//      entries = new int[numEntries];
//     
//      for(int i = 0; i < numEntries; i++)
//          entries[i] = -1;
//  }
         
    VertexCache();// { VertexCache(16); }
    ~VertexCache();// { delete[] entries; entries = 0; }
     
    bool InCache(int entry);
//  {
//      bool returnVal = false;
//      for(int i = 0; i < numEntries; i++)
//      {
//          if(entries[i] == entry)
//          {
//              returnVal = true;
//              break;
//          }
//      }
//     
//      return returnVal;
//  }
     
    int AddEntry(int entry);
//  {
//      int removed;
//     
//      removed = entries[numEntries - 1];
//     
//      //push everything right one
//      for(int i = numEntries - 2; i >= 0; i--)
//      {
//          entries[i + 1] = entries[i];
//      }
//     
//      entries[0] = entry;
//     
//      return removed;
//  }
 
    void Clear();
//  {
//      memset(entries, -1, sizeof(int) * numEntries);
//  }
     
    void Copy(VertexCache* inVcache) ;
//  {
//      for(int i = 0; i < numEntries; i++)
//      {
//          inVcache->Set(i, entries[i]);
//      }
//  }
 
    int At(int index);// { return entries[index]; }
    void Set(int index, int value);// { entries[index] = value; }
 
private:
 
//  int *entries;
  //此处修改为unsigned short
  unsigned short *entries;
  int numEntries;
 
};
 
#endif

我们看一下在SIO2中的使用,其他引擎中的用法,大同小异

void ObjMod::optimize_mesh(unsigned int mesh_index, unsigned int vertex_cache_size) {
    ObjMesh *objmesh = &this->objmesh[ mesh_index ];
      
    unsigned int i = 0,
    s = 0;
      
    unsigned short n_group = 0;
      
    //设置顶点缓存大小,顶点缓存越大,优化时间越长,优化效果越好,但是成边界递减关系
    if( vertex_cache_size )
        SetCacheSize( vertex_cache_size );
      
    while( i != objmesh->n_objtrianglelist )
    {
        PrimitiveGroup *primitivegroup;
          
        //通过三角形索引创建
        //四个参数依次:被优化的三角形索引数组,三角形索引元素数量,优化后的三角形带数组,优化后的三角形带元素个数
        if( GenerateStrips( objmesh->objtrianglelist[ i ].indice_array,
                           objmesh->objtrianglelist[ i ].n_indice_array,
                           &primitivegroup,
                           &n_group,
                           true ) )
        {
            if( primitivegroup[ 0 ].numIndices < objmesh->objtrianglelist[ i ].n_indice_array )
            {
                objmesh->objtrianglelist[ i ].mode = GL_TRIANGLE_STRIP;//渲染模式修改为三角形带
                objmesh->objtrianglelist[ i ].n_indice_array = primitivegroup[ 0 ].numIndices;//重置数据数量
                  
                //重新申请内存//
                s = primitivegroup[ 0 ].numIndices * sizeof( unsigned short );
                  
                //这块使用realloc有点浪费空间,因为优化后的三角形带占用内存比原先的三角形索引要小
                objmesh->objtrianglelist[ i ].indice_array = ( unsigned short * ) realloc( objmesh->objtrianglelist[ i ].indice_array,
                                                                                          s );
                //复制数据
                memcpy( &objmesh->objtrianglelist[ i ].indice_array[ 0 ],
                       &primitivegroup[ 0 ].indices[ 0 ],
                       s );
            }
              
            //删除优化后的临时数据
            delete[] primitivegroup;
        }
          
        ++i;
    }
}

我们这里调用库的函数有两个:
SetCacheSize为设置优化库使用的缓存大小并非越大越好。而是根据模型精细度来考量的。
GenerateStrips就是核心的三角形优化算法了。

然后保存输出的数据删掉临时数据即可。

下面是一个测试报告,画面数为4726个三角形的静态模型。重复绘制模型200次,在iPad mini2上面的结果是:

未开三角形带优化时的FPS:

三角形带优化库nvtrisrip的使用

开启三角形带优化之后的FPS:

三角形带优化库nvtrisrip的使用

FPS提高了70%,效果还是非常明显的。

在这里为了方便,我们使用的是在线优化方式(模型数据加载进内存后再优化)。而实际开发中,往往多使用离线优化,预先处理好模型数据,然后直接调用渲染就可以了,这样没有缓存和时间限制,效果更好。

这个库是平台无关,也没有第三方依赖,可以很方便的集成到自己的工具中去。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前题目:三角形带优化库nvtrisrip的使用-创新互联
当前地址:http://scyanting.com/article/ccepdp.html