• Cesium开发基础篇 | 05glTF介绍及加载


    到目前为止,我们已经介绍了如何利用Cesium显示影像数据、地形高程数据、矢量数据,以及空间可视化方面的几何数据(Entity),感兴趣的同学可以阅读我前面写的文章。在三维数据方面,Cesium支持模型文件glTF,以及三维瓦片数据3D Tiles。本次我们先从glTF说起,3D Tiles的讲解留给下一章节。

    glTF介绍

    glTF全称是 Graphics Language Transmission Format (图形语言传输格式),是一种针对GL(WebGL,OpenGL ES以及OpenGL)接口的运行时资产传递格式,由澳大利亚的 Khronons 集团进行维护,并于2017年6月5日在GitHub上()公布了glTF 2.0的规范,此文也是针对于2.0版本进行介绍的。glTF通过提供高效、可扩展、可互操作的格式来传输和加载三维内容,填补了3D建模工具与现代图形应用程序之间的空白,它已成为了 Web 上的3D 对象标准(Web导出的通用标准),可以说glTF是3D 模型的JPEG格式,几乎每个3D Web框架都支持glTF。随着glTF的不断发展,glTF形成了自己庞大的生态系统,同时受到了各行业的大力支持。所以,如果有人要为你提供3D 模型,你就可以要求他们提供glTF格式的模型。

     

    glTF生态系统

     

    glTF行业支持

     

    同时,Cesium官方GitHub中也提供了obj转glTF的源码库,感兴趣的可以前往这里查看。

    目前,glTF 3D模型格式有两种:

    • *.gltf: 基于JSON的文本文件,可使用文本编辑器轻松编辑,通常会引用外部文件,例如纹理贴图、二进制网格数据等;
    • *.glb: 是二进制格式,通常文件较小且自包含所有资源,但不容易编辑。

    要获取glb文件,可以直接从3D建模程序中导出它们,也可以使用工具将gltf转换为glb。在线转换工具推荐 MakeGLB (),当然,如果您使用的是VS Code编辑器,建议安装 glTF Tools 扩展工具,能够非常方便的查看glTF的数据结构、glTF和glb互转等。

    glTF场景描述结构

    glTF的核心是一个JSON文件,另外还支持外部数据。具体而言,一个glTF模型可包括以下三部分内容:

    • JSON格式的文件(.gltf),其中包含完整的场景描述,并通过场景结点引用网格进行定义 。包括:节点层次结构、材质(定义了3D对象的外观)、相机(定义义了渲染程序的视锥体设置 )、mesh(网格)、动画(定义了3D对象的变换操作,比如选择、平移操作)、蒙皮(定义了3D对象如何进行骨骼变换)等;
    • .bin包含几何和动画数据以及其他基于缓冲区的数据的二进制文件;
    • 图像文件(.jpg,.png)的纹理。

    如下图所示:

    glTF场景描述结构

    以其他格式定义的文件(例如图像文件)可以存储在通过URI引用的外部文件中,并排存储在GLB容器中,或使用数据URI直接嵌入到JSON中,一个有效的glTF模型必须指定其版本。

    glTF的JSON结构

    场景对象以数组的形式存储在JSON文件中,可以使用数组中各个对象的索引来访问它们:

    "meshes" : 
    [
        { ... }
        { ... }
        ...
    ],

    这些索引还用于定义对象之间的关系。上面的示例定义了多个网格对象,并且一个节点可以使用网格索引引用上面定义的其中一个网格对象:

    "nodes": 
    [
        { "mesh": 0, ... },
        { "mesh": 5, ... },
        ...
    }

    下图概述了glTF的JSON部分的顶级元素:

    glTF的JSON结构

     

    下面我对这些元素进行简要说明:

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

    更多详情,可查阅glTF 2.0规范()以及glTF官方教程(

    下面是一个最小巧的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相关工具推荐

    glTF在线验证: 
    浏览-Sketchfab: (需要注册账号,并且要上传模型才能浏览)
    浏览-PlayCanvas查看器: 
    浏览-ThreeJS查看器:
    浏览-BabylonJS查看器: 
    gltf转glb: 
    obj2gltf: 
    FBX2glTF: 
    COLLADA2GLTF: 

    Cesium加载glTF模型

    Cesium提供了两种方式加载glTF模型,分别是通过 Entity API 和 Primitive API 两个 API 实现的。核心代码如下:

    var position = Cesium.Cartesian3.fromDegrees(-120.05, 44, 0);
        var heading = Cesium.Math.toRadians(45);
        var pitch = 0;
        var roll = 0;
        var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
        var orientation = Cesium.Transforms.headingPitchRollQuaternion(
          position,
          hpr
        );
        var model_entity = viewer.entities.add({
          name: "gltf模型",
          position: position,
          // 默认情况下,模型是直立的并面向东。
          // 通过 Quaternion 为 Entity.orientation 属性指定值来控制模型的方向,控制模型的航向,俯仰和横滚。
          orientation: orientation,
          model: {
            show: true,
            uri: "./data/models/DracoCompressed/CesiumMilkTruck.gltf",
            scale: 1.0, // 缩放比例
            minimumPixelSize: 128, // 最小像素大小
            maximumScale: 20000, // 模型的最大比例尺大小。 minimumPixelSize的上限
            incrementallyLoadTextures: true, // 加载模型后纹理是否可以继续流入
            runAnimations: true, // 是否应启动模型中指定的glTF动画
            clampAnimations: true, // 指定glTF动画是否应在没有关键帧的持续时间内保持最后一个姿势
    
            // 指定模型是否投射或接收来自光源的阴影 type:ShadowMode
            // DISABLED 对象不投射或接收阴影;ENABLED 对象投射并接收阴影;CAST_ONLY  对象仅投射阴影;RECEIVE_ONLY  对象仅接收阴影
            shadows: Cesium.ShadowMode.ENABLED,
            heightReference: Cesium.HeightReference.NONE,
          },
        });
        // viewer.trackedEntity = entity; // 相机保持在实体上

     

       var origin = Cesium.Cartesian3.fromDegrees(-120, 44.0, 0);
        // 创建一个本地的东北向上坐标系,其原点为经度-120度,纬度44.0度。
        // 可以随时更改模型的modelMatrix属性以移动或旋转模型。
        var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);
        var model = viewer.scene.primitives.add(
          Cesium.Model.fromGltf({
            url: "./data/models/DracoCompressed/CesiumMilkTruck.gltf",
            modelMatrix: modelMatrix,
            minimumPixelSize: 128,
            maximumScale: 20000,
          })
        );
        model.readyPromise.then(function (model) {
          // Play all animations when the model is ready to render
          model.activeAnimations.addAll();
        });
    

    这里简单说一下 modelMatrix 属性,该属性类型是 Matrix4 ,即4x4转换矩阵,用于将模型坐标转换为世界坐标,也就是为模型创建一个局部坐标系。正如示例中的代码那样,为模型创建了一个本地的东北向上坐标系,其原点为经度-120度,纬度44.0度。在 Cesium 调试器面板中勾选显示参考框架,能够很清晰地看到该模型对应的X、Y、Z轴以及原点。

  • 相关阅读:
    [AH2017/HNOI2017]礼物
    [八省联考2018]林克卡特树lct
    [洛谷P4847]银河英雄传说V2
    [洛谷P4999]烦人的数学作业
    [洛谷P4171][JSOI2010]满汉全席
    [CF785E]Anton and Permutation
    [洛谷P2511][HAOI2008]木棍分割
    [洛谷P4430]小猴打架
    [UVA307]小木棍 Sticks
    [LOJ #6433]「PKUSC2018」最大前缀和
  • 原文地址:https://www.cnblogs.com/telwanggs/p/16670254.html
Copyright © 2020-2023  润新知