GLTF和GLB基础知识,第2部分

本文是GLTF和GLB格式基础的延续。 您可以在此处找到本文的第一部分。 在第一部分中,我们与您一起检查了为什么最初计划格式,以及GLTF格式的工件及其属性,例如场景,节点,缓冲区,缓冲区视图,访问器和网格。 在本文中,我们将考虑“材质”,“纹理”,“动画”,“蒙皮”,“相机”,并完成创建最小的有效GLTF文件。


图片

材质和质地


材质和纹理与网格紧密相连。 如有必要,可以对网格进行动画处理。 该材料存储有关引擎将如何渲染模型的信息。 GLTF使用基于物理渲染(PBR)的一组通用参数定义材料。 由于阴影模型必须具有“物理”表面特性,因此PBR模型允许您在不同的光照条件下创建“物理上正确”的对象显示。 有几种描述PBR的方法。 最常见的模型是金属粗糙度模型,该模型在GLTF中默认使用。 您还可以使用镜面光泽度模型,但只能使用单独的扩展名(扩展名)。 该材料的主要属性如下:


  1. name是网格的名称。
  2. baseColorFactor / baseColorTexture-存储颜色信息。 在“因子”属性的情况下,信息以RGBA的数值存储,在“纹理”的情况下,纹理参考存储在纹理对象中。
  3. metalFactor-存储金属信息
  4. 粗糙度因子 -存储有关粗糙度的信息
  5. doubleSided-真或假(默认值),指示是在两侧还是仅在“前”侧渲染网格。
    "materials": [ { "pbrMetallicRoughness": { "baseColorTexture": { "index": 0 }, "metallicFactor": 0.0, "roughnessFactor": 0.800000011920929 }, "name": "Nightshade_MAT", "doubleSided": true } ], 

金属的或“金属性”的含义。 此参数描述了它与真实金属相似的反射强度,即 表面反射了多少光。 该值的测量范围是0到1,其中0是电介质,而1是纯金属。


粗糙度或“粗糙度”。 此属性显示表面有多“粗糙”,从而影响光从表面的散射。 从0到1进行测量,其中0完全平坦,1是完全粗糙的表面,仅反射少量的光。


Texture-一个存储纹理贴图(纹理贴图)的对象。 这样的卡给出了现实的模型。 多亏了他们,您可以指定模型的外观,以赋予各种属性,例如金属性,粗糙度,环境的自然暗淡甚至发光的属性。 纹理由三个高级数组描述:纹理,采样器,图像。 Textures对象使用索引来引用采样器和图像实例。 最重要的对象是图像,因为 是他来存储地图的位置信息。 在纹理中,它由单词source来描述。 图片可能位于硬盘驱动器上的某个位置(例如,“ uri”:“ duckCM.png”)或以GLTF编码(“ bufferView”:14,“ mimeType”:“ image / jpeg”)。 采样器是一个对象,用于定义与GL类型相对应的过滤器和包装参数。


在我们的三角形示例中,没有纹理,但是我将使用其他模型提供JSON。 在此示例中,纹理被写入缓冲区,因此也可以使用BufferView从缓冲区读取纹理:


 "textures": [ { "sampler": 0, "source": 0 } ], "images": [ { "bufferView": 1, "mimeType": "image/jpeg" } ], 

动画制作


GLTF支持使用关键帧进行关节,蒙皮和变形目标动画。 这些帧的信息存储在缓冲区中,并使用访问器引用动画。 GLTF 2.0仅定义了动画存储,因此它没有定义任何特定的运行时行为,例如播放顺序,自动播放,循环,时间轴显示等。所有动画均存储在Animations数组中,并且被定义为一组通道(通道属性),以及由访问者确定的一组样本,这些访问者处理有关关键帧和插值方法的信息(样本属性)


动画对象的主要属性如下:


  1. 名称 -动画名称(如果有)
  2. channel-将动画的关键帧的输出值连接到层次结构中特定节点的数组。
  3. 采样器是引用访问的属性,该访问器处理缓冲区中的关键帧。
  4. 目标是一个对象,该对象确定需要使用node属性对哪个节点(Node对象)进行动画处理,以及需要使用path属性(平移,旋转,缩放,权重等)对节点的哪个属性进行动画处理。 非动画属性在动画期间保留其值。 如果未定义节点,则应省略channel属性。
  5. 采样器 -定义输入和输出对:一组表示线性时间(以秒为单位)的标量浮点值。 所有值(输入/输出)都存储在缓冲区中,并且可以通过访问器访问。 插值属性存储键之间的插值。

最简单的GLTF中没有动画。 一个示例取自另一个文件:


 "animations": [ { "name": "Animate all properties of one node with different samplers", "channels": [ { "sampler": 0, "target": { "node": 1, "path": "rotation" } }, { "sampler": 1, "target": { "node": 1, "path": "scale" } }, { "sampler": 2, "target": { "node": 1, "path": "translation" } } ], "samplers": [ { "input": 4, "interpolation": "LINEAR", "output": 5 }, { "input": 4, "interpolation": "LINEAR", "output": 6 }, { "input": 4, "interpolation": "LINEAR", "output": 7 } ] }, 

皮肤


蒙皮信息(也称为蒙皮,又称为骨骼动画)存储在蒙皮数组中。 每个外观都是使用inverseBindMatrices属性定义的,该属性引用具有IBM(反向绑定矩阵)数据的访问器。 该数据用于将坐标传递到与每个关节相同的空间,以及关节数组的属性,该数组列出了用作皮肤动画的关节的节点的索引。 连接的顺序在skin.joints数组中确定,并且必须与inverseBindMatrices的数据顺序匹配。 骨架属性指向Node对象,该对象是关节层次结构的公共根,或公共根的直接或间接父节点。


使用皮肤对象的示例(不在三角形示例中):


  "skins": [ { "name": "skin_0", "inverseBindMatrices": 0, "joints": [ 1, 2 ], "skeleton": 1 } ] 

主要属性:


  1. 名称 -外观名称
  2. inverseBindMatrices-指示访问者编号,该访问者编号存储有关反向绑定矩阵的信息
  3. 关节 -表示存储有关关节信息的访问器的数量
  4. 骨架 -指示存储有关“根”信息的访问者的编号
    模型骨架开始的关节

摄影机


相机确定投影矩阵,该投影矩阵是通过将“视图”转换为剪辑的坐标而获得的。 如果更简单,则摄像机将确定用户在加载模型时看到的视觉外观(视角,“视线”方向等)。


投影可以是“透视”和“正交”。 摄像机包含在节点中,并且可以进行转换。 摄像机固定在Node对象中,因此可以进行转换。 定义摄像机的方向是将本地+ X轴指向右侧,镜头朝本地-Z轴方向看,并且摄像机的顶部与本地+ Y轴对齐。 如果未指定转换,则相机位于原点。 摄像机存储在摄像机阵列中。 它们每个都定义了一个类型属性,该属性指定了投影的类型(透视或正交),以及诸如透视图或正交图之类的属性,这些属性已经存储了更详细的信息。 根据zfar属性的存在,具有透视图类型的相机可以使用有限或无限投影。


JSON中具有类型透视图的示例相机。 与最小正确的GLTF文件(三角形)的示例无关:


 "cameras": [ { "name": "Infinite perspective camera", "type": "perspective", "perspective": { "aspectRatio": 1.5, "yfov": 0.660593, "znear": 0.01 } } ] 

Camera对象的主要属性:


  1. 名称 -外观名称
  2. 类型 -摄影机,透视图或正射影像的类型。
  3. 透视图/正交图 -包含相应类型值的详细信息的属性
  4. AspectRatio-长宽比( fov )。
  5. yfov-弧度的垂直视场角( fov
  6. zfar-到远裁剪平面的距离
  7. znear-到附近裁剪平面的距离
  8. 附加功能 -特定于应用的数据

最小有效GLTF文件


在本文开头,我写道我们将收集一个最小的GLTF文件,该文件将包含1个三角形。 缓冲的JSON可以在下面找到。 只需将其复制到文本文件,然后将文件格式更改为.gtlf。 要查看文件中的3D资产,您可以使用任何支持GLTF的查看器,但我个人使用此功能


 { "scenes" : [ { "nodes" : [ 0 ] } ], "nodes" : [ { "mesh" : 0 } ], "meshes" : [ { "primitives" : [ { "attributes" : { "POSITION" : 1 }, "indices" : 0 } ] } ], "buffers" : [ { "uri" : "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=", "byteLength" : 44 } ], "bufferViews" : [ { "buffer" : 0, "byteOffset" : 0, "byteLength" : 6, "target" : 34963 }, { "buffer" : 0, "byteOffset" : 8, "byteLength" : 36, "target" : 34962 } ], "accessors" : [ { "bufferView" : 0, "byteOffset" : 0, "componentType" : 5123, "count" : 3, "type" : "SCALAR", "max" : [ 2 ], "min" : [ 0 ] }, { "bufferView" : 1, "byteOffset" : 0, "componentType" : 5126, "count" : 3, "type" : "VEC3", "max" : [ 1.0, 1.0, 0.0 ], "min" : [ 0.0, 0.0, 0.0 ] } ], "asset" : { "version" : "2.0" } } 

结果如何?


最后,我要指出的是GLTF和GLB格式越来越流行,许多公司已经在积极使用它,并且有些公司已经在为此而努力。 易于在社交网络Facebook上使用(3D帖子,以及最近的3D Photos),在Oculus Home中积极使用GLB以及在GDC 2019上宣布的多项创新,极大地促进了该格式的普及。亮度,快速渲染速度,易用性,Khronos集团的推广和格式的标准化是主要优势,我敢肯定,这最终将在进一步推广中发挥其作用!

Source: https://habr.com/ru/post/zh-CN448298/


All Articles