Skip to content

RoyMesh

RoyMesh是网格数据资源的代表,我们在之前的绘制一个正方体中已经使用过RoyMesh。让我们来复习一下,构建一个RoyMesh主要是完成三个部分:顶点(Vertex)、索引(Indices)、包围盒(BoundBox)。这一节我们来分别看一下三者定义:

  • 顶点部分:由属性列表和顶点个数组成
typescript
/**
 * Interface for vertex buffer attribute data
 */
interface RoyVertexBufferAttriData {
    /** The attribute of the vertex buffer data */
    attribute: string;
    /** The type of the vertex buffer attribute */
    elementType: string;
    /** The stride of the vertex buffer */
    stride?: number;
    /** The data of the vertex buffer */
    data: Float32Array;
}
/**
 * Interface for vertex buffer data
 */
interface RoyVertexBufferData extends RoyTransDataInfo {
    /** The list of vertex buffer attribute data */
    attriList: RoyVertexBufferAttriData[];
    /** The count of vertices */
    vtxCount: number;
}
  • 索引部分:由数据类型和数据组成
typescript
/**
 * Interface for index buffer data
 */
interface RoyIndexBufferData extends RoyTransDataInfo {
    /** The type of the index buffer data */
    dataType: string;
    /** The data of the index buffer */
    data: Uint32Array | Uint16Array;
}
  • 包围盒: AABB的定义,用于计算各级RoySceneNode的包围盒。

值得注意的是,RoyMesh使用RoyMeshProvider来进行Buffer数据的持有。RoyMeshProvider继承自RoyResourceProvider,其他的Provider还有RoyTextureProvider。Provider的提供为使用者提供了更大的操作空间。

  • 我们先考虑这样一个事实:当我们把一个静态模型上传到GPU的显存用于显示之后,位于内存中的Float32Array或者Uint32Array也好,就没有什么用了,我们希望把它们完全不再持有,释放出这部分内存。
  • 然而,场景动态的变化之后,比如把一个roySceneNode从渲染树上移除,因为不再绘制随之而来的是显存的释放,后面因为某种条件,再次添加会渲染树,这个时候会再次执行从内存到显存的同步操作,如果我们释放了这部分内存,就无法再次同步到显存,物体绘制就会出错
  • 基于以上两点,我们提供了provider这样一个机制,实际上是提供了一个异步获取内存Buffer的机制。执行的点如下:
    • 当需要从内存上传到显存时,这个时候引擎内部会向provider异步的请求这部分内存,如果请求成功那么上传到显存;
    • 上传显存之后,这部分内存则可以释放,释放之前可以将这部分内存放到cachedb里面,或者放到网络上。下次收到请求的时候再重新获取,至于是在哪里进行缓存,可以由项目侧继承RoyMeshProvider来实现对应的功能。
    • 在异步等待的过程中,不进行显示或者显示默认。

需要明确的是,在实际的项目中,各种模型文件格式都可以通过既定的模型格式解析器,解析对应的mesh数据并填充到上面的格式中,这背后的深层原因是GPU的对Mesh格式的要求,并非引擎定义的Mesh结构体有多么的通用。

目前我们已经在plugin_fmt文件夹下定义了一些文件格式的解析,在未来会随着项目的进行而越来越多,每种格式的加载器和导出器都会封装成为一个插件,大家可以进行参考。

对于RoyMesh来说,还有一个内容就是MeshLod,对于性能的帮助很大。

  • RoyMesh采用的是popBuffer的策略,在2013年提出,论文名称为The POP Buffer: Rapid Progressive Clustering by Geometry Quantization
  • 测试结果如下:
    • 测试机器:Dell笔记本,CPU:intel i5-8250U,GPU:Intel(R) UHD Graphics 620 该笔记本已经是非常低端的机器,Thinkpad等中端机器我们都是60满帧
    • 测试方案:4层复式 竞品对比(酷家乐):200w+三角面,批次数2184个,帧率40+
    • 我们的情况: 优化前:鸟瞰 1500w+三角面,批次1200个,帧率15+ 优化后:鸟瞰 200w+三角面,批次1020个,帧率45+,持平竞品
    • 分析:主要在两个方面上下功夫:批次数目和三角面数。二者都有影响,且当其中一个成为瓶颈之后,另外一个怎么优化也无法提高帧率,所以是一个双项共同优化的过程。