关于GLTF格式的综述、结构与TS解析_gltf数据结构-程序员宅基地

技术标签: webgl  webgl笔记  gltf  opengles  typescript  三维格式  

目录

三维格式

GLTF总概

GLTF历史

gltf1.0

gltf2.0

为什么是GLTF

GLTF生态

GLTF业界支持

GLTF目的

GLTF优势

GLTF基础结构

一句话总结

三维数据简述

数据分区

Json节点简述

外部数据简述

GLTF基础示例

scenes和nodes结构

meshes

accessor

bufferView

buffer

asset

GLTF结构解析实践

关键代码

每篇一句


三维格式

 

 

 在讲gltf之前,我们先来聊一聊三维格式。三维格式存储的是用于构建三维场景的实时或非实时的渲染三维数据,一般作为传输与用户数据存储的标准。不同的格式(维基百科上罗列了不下70多种)有不同的定位与目的,如只描绘三维对象几何格式(.ply,.vtk,.obj,.dae)、描绘三维视图格式(.x3d,.jvx,.vrml)、描绘模型和渲染格式(.maya,.pov,.lwo)以及CAD相关的格式(.dxf,.stl,.zpr)等等。

GLTF总概

GLTF历史

gltf1.0

 

 部分大事件回顾:

  • gltf1.0是COLLADA(.dae)工作组的成员在2012年提出的。  
  • 在SIGGRAPH 2012上,Khronos展示了glTF的演示,然后将其称为WebGL传输格式(WebGL TF)。  
  • 2015年10月19日,发布了glTF 1.0规范。  
  • 在SIGGRAPH 2016上,Oculus以与ovrscene格式的相似之处宣布采用glTF。  
  • 2016年10月,微软加入了Khronos的3D格式工作组,就glTF进行合作。

gltf2.0

 

 部分大事件回顾:

  • 第二个版本glTF 2.0于2017年6月发布,是对1.0版文件格式的完整检查,大多数工具都采用2.0版。  
  • 添加了基于物理的渲染(PBR),取代了glTF 1.0中使用的WebGL 着色器。  
  • (其他升级包括稀疏访问器和面向对象的变形目标,例如面部动画,模式调整以及针对极端情况或性能的重大更改,例如将数组替换顶层glTF对象属性以实现基于索引的访问更快。  在Unity 和集成的多引擎查看器/验证器中,正在进行着导入和导出的工作。)  
  • 3.2017年3月3日,Microsoft宣布他们将在其整个产品线中使用glTF 2.0作为3D资产格式,包括Paint 3D,3D Viewer,Remix 3D,Babylon.js和Microsoft Office。Sketchfab还宣布了对glTF 2.0的支持。  
  • 截至2019年,glTF和GLB格式已在UX3D,Sketchfab,Facebook,Microsoft,Oculus,Google,Adobe,Box,TurboSquid和Unreal Engine等公司使用并受其支持。该格式已被视为增强现实的重要标准,并与Autodesk Maya,Autodesk 3ds Max和Poly等建模软件集成在一起。  
  • 2020年2月,史密森学会(Smithsonian Institution)发起了开放访问计划(Open Access Initiative),将约280万个2D图像和3D模型发布到公共领域,并以glTF形式提供了3D模型。

为什么是GLTF

 gltf的创始者在互联网的兴起中意识到需要一种有效的现代三维格式来传输三维模型和场景信息数据。    

 在gltf出现前,三维圈子也流行着一些标准化的格式,如FBX、OBJ等等。FBX格式具有非常多的功能,不过其中有些在目前的渲染中是已经被时代淘汰了,而且它是私有的,AutoDesk提供的SDK封装好了,我们并不能在官方查看到其内部结构(不过网上有很多分析FBX文件内部结构的文章),并且它是针对建模工具之间交互数据使用的。再说OBJ,文件格式虽然是公开的,但OBJ的功能集有限且由于是文本格式,数据量大,在存储空间和快速读写数据的能力效率极低。虽然可在Web浏览器中传输加载OBJ文件,但这是一个非常不好的体验。    

 总而言之,在gltf之前,大家都要花较长的的时间来处理模型的载入或者花较大代价进行模型的传输。很多的游戏引擎或者3D渲染引擎,都使用的是插件的方式来载入各种格式的模型,繁多的格式插件增大了引擎本身体积。并且,各种格式的模型总是会包含了一些与当前加载无关的信息,例如一些过程数据。

GLTF生态

 

GLTF业界支持

 

GLTF目的

 

来自官方原文:

  • 紧凑的文件大小。尽管Web开发人员希望尽可能多地使用纯文本,但是由于其巨大的尺寸,纯文本编码对于传输3D数据根本不切实际。glTF JSON文件本身是纯文本,但结构紧凑且解析迅速。所有大数据(例如几何图形和动画)都存储在二进制文件中,该二进制文件比等效的文本表示形式小得多。  
  • 快速加载。glTF数据结构已被设计为尽可能接近JSON和二进制文件中的GPU API数据,以减少加载时间。例如,网格的二进制数据可以看作是JavaScript类型数组,并可以通过简单的数据副本直接加载到GPU缓冲区中。无需解析或进一步处理。  
  • 运行时独立。glTF对目标应用程序或3D引擎不做任何假设。glTF除了渲染和动画外没有指定任何运行时行为。 完整的3D场景表示。对于许多应用程序而言,从建模包中导出单个对象是不够的。通常,作者希望将整个场景(包括节点,变换,变换层次结构,网格,材质,摄影机和动画)加载到其应用程序中。glTF努力保留所有这些信息,以供下游应用程序使用。  
  • 可扩展性。尽管最初的基本规范支持丰富的功能集,但仍会有许多增长和改进的机会。glTF定义了一种机制,该机制允许添加通用扩展和特定于供应商的扩展。

目的决定了优势,下面我们来看看GLTF到底有哪些优势

GLTF优势

 

  • 对于那些对加载格式不是非常重要的软件,可以显著地减少代码量,所以也有人说,最大的受益者是那些对程序大小敏感的3D Web渲染引擎,只需要很少的代码就可以顺利地载入各种模型了。    
  • 使用JSON来描述场景结构,可以方便地被应用程序分析处理与预留一般支持以及特定供应商的扩展。    
  • 设计是面向实时渲染应用的,尽量提供可以直接传输给图形API的数据形式,不再需要二次转换。  

例如:将模型数据表示为简单的二进制缓冲区。“访问者”允许根据上下文解释该数据。这特别适合在OpenGL中加载这些文件,您可以在其中使用glBufferData将每个缓冲区加载到GPU中,然后使用glVertexAttribPointer解析每个访问器,以绑定到缓冲区中每个顶点元素的位置。  

  • glTF是对近年来各类三维格式的总结,可以包括场景、摄像机、动画等,也可以包括网格、材质、纹理,甚至包括了渲染技术、着色器以及着色器程序。使用目前最优的数据结构,来保证最大的兼容性以及可伸缩性。

GLTF基础结构

一句话总结

 

三维数据简述

 

  • 场景数据:gltf使用的的是场景图的形式,也就是用树来定义场景,其中的各类节点说明着节点的父子关系、节点的transform(位置,旋转,缩放)矩阵和节点的功能(如mesh、camera);  
  • 真实mesh和skin数据:用来加载静态模型与骨骼模型的;  
  • 材质数据:mesh的渲染信息数据用于渲染模型效果。  
  • animation数据:通过场景中的节点定义组成骨架结构,用以控制mesh做刚体运动;  
  • Morph Target(也称作Blend Shape)模型动画数据:控制逐顶点动画运动;

数据分区

 

Json节点简述

 

  • scene:glTF格式的场景结构描述条目。它通过引用node来定义场景图。
  • node:场景图中的一个结点。它可以包含一个变换(比如旋转或平移),引用更多的子结点。它可以引用网格和相机,以及描述网格变换的蒙皮。

补充:

glTF格式使用scene对象来描述场景。对glTF数据的JSON文件进行解析时,对场景结构的遍历也是从scene对象开始。每个scene对象引用了一个nodes数组,nodes数组通过索引引用了场景的根结点。

  • camera:定义了用于渲染场景的视锥体配置。
  • mesh:描述了场景中出现的3D对象的网格数据。它引用的accessor对象可以用来访问真实的几何数据。它引用的material对象定义了3D对象的外观。  
  • skin:定义了用于蒙皮的参数,参数的值通过一个accessor对象获得。
  • animation:描述了一些结点如何随时间进行变换(比如旋转或平移)。
  • accessor:一个访问任意数据的抽象数据源。被mesh、skin和animation元素使用来提供几何数据,蒙皮参数和基于时间的动画值。它通过引用一个bufferView对象,来引用实际的二进制数据。
  • material:包含了定义3D对象外观的参数。它通常引用了用于3D对象渲染的texture对象。
  • texture:定义了一个sampler对象和一个image对象。sampler对象定义了image对象在3D对象上的张贴方式。 buffer,bufferView和accessor:提供了对mesh对象实际的几何数据的描述。

外部数据简述

 

 外部数据基本为二进制数据与图片数据。二进制数据,比如3D对象的几何数据和纹理数据通常不被包含在JSON文件中,它们被存储在外部的文件中。JSON文件中只包含了到这些外部文件的链接。这使得二进制数据可以以非常紧凑的形式进行存储方便互联网传输,并且可以直接被渲染程序使用,无需额外的解码、预处理。  

 在JSON结构被分析完后,就可以使用buffers和images数组来索引访问buffer和image对象。每个buffer和image对象引用了一块二进制数据。通常会将二进制数据读取到内存中,以它们在原来buffers和images数组中的索引顺序进行存储,以便使用相同的索引来访问对象对应的二进制数据。

GLTF基础示例

scenes和nodes结构

 

示例包含了一个scene对象,这一scene对象引用了一个索引为0的node对象,这个node对象引用了索引为0的mesh对象。

meshes

 示例只包含了一个mesh对象,这一mesh对象只包含了一个primitive对象。primitive对象包含了一个attribute对象数组,存储了mesh对象的几何数据信息。

 对于这个示例来说,只包含了一个POSITION属性,用于描述mesh对象的顶点位置信息。primitive对象的indices属性描述了用于渲染的顶点索引数据,默认情况下,连续3个顶点索引构成一个三角形。

accessor

 

  •  第一个accessor对象描述了顶点的索引数据,它引用了索引为0的bufferView对象,这一bufferView对象引用了顶点索引数据。accessor对象还包含了count,type和componentType3个属性,用来对数据进行描述。对于示例来说,这3个属性描述的的数据元素包含了3个类型为unsigned short的标量。  
  •  第二个accessor对象描述了顶点位置数据。它引用了索引为1的bufferView对象,这一bufferView对象引用了顶点位置数据。对于示例来说,这一accessor对象的count,type和componentType属性描述的数据元素的个数为3,每个数据元素是一个包含3个分量,每个分量类型为float的3D向量。

bufferView

 

 包含了2个bufferView对象,它们引用了同一个buffer对象的不同部分数据。

 第一个bufferView对象引用了三角形的索引数据,数据位置从偏移值byteOffset(0)开始,长度为6字节。

 第二个bufferView对象引用了三角形的顶点位置数据,数据位置从偏移值byteOffset(8)开始,长度为36字节。

补充:

bufferview target属性,此属性是在GPU渲染过程中,区分bufferview指向数据的类型。例如34962代表ARRAY_BUFFER,34963代表ELEMENT_ARRAY_BUFFER

buffer

 

 示例中我们使用数据URI直接在JSON文件中编码长度44字节的buffer数据。

asset

 

 对于glTF数据格式的1.0版本,asset对象是可选的,对于之后版本的glTF数据格式,必须包含asset对象,使用version属性指定glTF数据格式的版本。示例表示数据使用glTF数据格式的2.0版本进行描述。

附:关于gltf数据结构,如想了解更多可以去看一下KhronosGroup的glTF-torials

GLTF结构解析实践

关键代码

 

 左侧代码是读取gltfJson树状结构代码,如代码所示是一个不断递归过程,例如loadScene方法在访问scene节点时需要访问其他节点也会使用getDependency接着递归到其他节点上。

 右侧代码展现的是gltf设计所可以带来的扩展能力,当我们想在gltf实现一个扩展时,我们可以很方便地将这个扩展独立出来与引用进去,不会破坏原先的json结构;当基础json结构在某个节点要用这个扩展时,只要去查询目前我们之前独立出来的扩展类就可以了。

每篇一句

 没有人不爱惜他的生命,但很少人珍视他的时间。——梁实秋 出自《时间与生命》

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_40676050/article/details/115033305

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签