[深入研究]什么是G3D几何交换格式?

VIM AEC中,我们处理非常大的建筑模型,并将网格和BIM数据导入游戏引擎(例如Unity),3D编辑工具(例如3ds Max)和在不同设备上运行的应用程序(例如Magic Leap)。

当使用FBX作为表示大网格的格式时,将近四分钟的时间在Unity中导入2800万个多边形模型。 作为替代方案,我们开发了一种表示3D几何图形的开放格式,称为G3D ,可将导入时间减少到不到6秒。

总览

G3D格式可以表示三角形和四边形网格,点云,线段和多边形网格,以及与网格的不同子元素(顶点,面)关联的任意属性(例如法线,UV,颜色,平滑组等) ,面角,多边形组或整个对象)。

与使用Assimp模型导入库或导入Unity来读取OBJ,FBX或PLY文件相比,我们的G3D加载器在我们的测试中要快一个数量级。 规范和参考实现也比其他二进制格式(例如glTF)简单得多,同时支持更广泛的数据属性。

G3D Github存储库上,我们使用.NET Standard 2.0(使其跨平台)和Unity测试项目(用于导入和导出G3D网格)在C#中提供参考实现。 我们还发布了Nuget软件包 ,可在生产代码中使用它。

动机

用于表示3D几何形状的常见数据格式(例如OBJ,FBX,Collada,glTF等)通常具有一个或多个缺点:

  • 糟糕的序列化和反序列化性能
  • 平台或语言特定
  • 缺乏可扩展性
  • 实施复杂
  • 对存储的属性的数量和类型的限制

我们的目标是设计一种格式,使我们能够快速轻松地将导入器和导出器实现为不同编辑工具,游戏引擎以及在从台式机到WebGL到Magic Leap等空间计算设备的不同平台上运行的应用程序的插件。

我们还希望这种格式能够传输来自不同来源的各种数据而不会丢失。

G3D怎​​么这么快?

G3D格式之所以如此之快,是因为它不必在将数据转换为可渲染的,GPU友好的状态之前对其进行预处理。

基于文本的网格格式,例如OBJ,PLY,Collada等,要求计算机花费大量时间从文本表示转换为转换器可使用的二进制表示。

类似地,对于某些二进制格式,例如FBX,网格顶点数据被组织为4个双精度浮点值的向量。 大多数渲染上下文期望将顶点位置数据编码为3个单精度浮点的矢量,这意味着需要预处理步骤来截断数据并将其打包为更方便的格式。

G3D数据缓冲区严格对齐,因此,一旦将整个文件加载到内存中,即可将各个数据缓冲区按原样传递给GPU,而无需进行其他处理或分配内存。

3D网格入门

通常,3D网格由一系列空间点(称为顶点)和一系列面组成,这些面指定了如何连接这些点以在3维空间中形成多面表面。

维基百科的图片由RChoetzlien根据CC-SA-3.0 许可

点列表通常称为顶点缓冲区,而面列表则表示为索引缓冲区。 如果每个面的大小是固定的(例如,对于三角形,则为3,对于四边形,则为4),则每N个索引是不同面的角的顶点的索引。 有了这个观察结果,自然就会得出点云和线段是面的退化情况,每个面分别只有一个或两个点。 支持混合尺寸多边形的网格可以使用附加数据数组对每个面的大小进行编码。

边缘

有两种类型的边需要考虑:无向边和有向边(也称为半边)。 在G3D中,就像在3ds Max中一样,边指的是半边。

之所以这样称呼半边,是因为两个相邻的面都有一个有向的半边,这两个边共享相同的顶点,但是沿不同的方向流动,从而完成了将两个面分开的完整边。 枚举半边线比较简单,因为每个面都有N个半边线,其中N =面中的点数。 因此,半边索引缓冲区与索引缓冲区完全相同。

曲面或多边形组

一个表面或多边形组是构成一个连续表面的一系列连续表面。 通常,此表面将共享一种通用材料。 考虑到圆柱体的情况,弯曲部分可以看作是一个曲面,而端盖是两个表面。

具有多边形组可以实现更紧凑的数据表示(例如,每个组可以有一个共享的材质ID,或者在平面情况下可以有一个共享的法线)。 多边形组还可以用于对Unity或Revit API Face中的 “子网格”数据进行编码。

属性

G3D网格格式基于将几何表示为一组严格对齐的二进制数组(称为属性)的集合。 属性是与顶点,面角,面或多边形组关联的标量或向量的数组。 在某些情况下,属性是与整个对象关联的单个值。 属性的一些常见示例包括:

  • 顶点颜色
  • 紫外线坐标
  • 面或顶点法线
  • 平滑组ID
  • 物料编号
  • 每个顶点数据(例如,软选择或折痕权重)
  • 边缘可见度
  • 切线和双法线

属性描述符字符串

G3D中的每个属性都与一个描述符关联,该描述符以以下格式编码为字符串:

g3d: < association > : < semantic > : < data_type > : < data_arity >

描述符包含以下组件:

  • 关联-点,角,边,面,组,所有
  • 基本数据类型-int8,int16,int32,int64,float32,float64
  • arity —每个数据元素的原语数
  • 语义-定义属性角色或目的的标识符

多个属性可以共享同一描述符字符串,例如存储在Unity网格中的多个UV通道。

实施细节

G3D文件的基础二进制布局符合BFAST序列化格式 ,即用于序列化命名字节数组集合的简单有效的开放二进制格式。 (请参阅有关Hackernoon的文章

BFAST容器中的第一个命名缓冲区保留用于有关以JSON格式编码的文件的元信息。 它的名称为“元”。 对于元JSON对象中编码的数据,目前没有任何限制或要求。

随后的每个数据缓冲区都存储属性数据,并使用属性描述符字符串作为名称。 根据BFAST规范,属性数据存储在64字节对齐的数据缓冲区中。

语义的

属性还具有“语义”标签,用于标识属性对呈现或处理的作用。 应用程序可以使用它选择的任何字符串来表示语义,但是G3D规范建议使用许多具有预定义含义的语义(有关完整列表,请参见Github readme.md )。 这旨在使不同的应用程序能够以通用方式交换,处理和呈现G3D数据。

进一步阅读

如果您对理解导致G3D格式的设计决策感兴趣,那么最好阅读一下如何设计其他网格表示形式:

最后的话

在VIM AEC,我们非常希望帮助其他人采用G3D格式,因为我们相信它可以帮助提高每个人的图形软件的质量。 请通过电子邮件Github问题我联系,以提出问题或提出建议。

免责声明 :我在VIM AEC担任研究主管

From: https://hackernoon.com/the-g3d-geometry-exchange-format-pz81b30qx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值