关于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

智能推荐

什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?_成员内部类和局部内部类的区别-程序员宅基地

文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别

分布式系统_分布式系统运维工具-程序员宅基地

文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具

用Exce分析l数据极简入门_exce l趋势分析数据量-程序员宅基地

文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量

宁盾堡垒机双因素认证方案_horizon宁盾双因素配置-程序员宅基地

文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置

谷歌浏览器安装(Win、Linux、离线安装)_chrome linux debian离线安装依赖-程序员宅基地

文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖

烤仔TVの尚书房 | 逃离北上广?不如押宝越南“北上广”-程序员宅基地

文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...

随便推点

java spark的使用和配置_使用java调用spark注册进去的程序-程序员宅基地

文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序

汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用_uds协议栈 源代码-程序员宅基地

文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码

AUTOSAR基础篇之OS(下)_autosar 定义了 5 种多核支持类型-程序员宅基地

文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型

VS报错无法打开自己写的头文件_vs2013打不开自己定义的头文件-程序员宅基地

文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件

【Redis】Redis基础命令集详解_redis命令-程序员宅基地

文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令

URP渲染管线简介-程序员宅基地

文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线

推荐文章

热门文章

相关标签