前往小程序,Get更优阅读体验!
立即前往
社区首页 >专栏 >Cesium之b3dm格式

Cesium之b3dm格式

作者头像
Jean
发布于 2021-05-11 02:02:34
发布于 2021-05-11 02:02:34
6.5K00
代码可运行
举报
文章被收录于专栏:Web行业观察Web行业观察
运行总次数:0
代码可运行

//作者:迷途的小书童

//微信公众号:g0415shenweri

b3dm格式

参考文档:

https://github.com/CesiumGS/3d-tiles/blob/master/specification/TileFormats/Batched3DModel/README.md

工具设计

计划写一个工具来查看B3dm的格式,顺便了解其原理。主要分为两部分,一部分是对属性参数的解析,一部分是对gltf的解析。

网址一:https://github.com/daniel-hilton/gltf-b3dm-convertor

实现gltf-b3dm-convertor的互相转换。

这个库无法使用,而且缺少问题

网址二:https://github.com/CesiumGS/3d-tiles-validator

这里的工具可以验证自己导出的3dtiles的格式是否正确

网址三:https://github.com/KhronosGroup/glTF-Validator

这个工具可以验证gltf的格式是否正确

网址四:https://github.com/CesiumGS/3d-tiles-validator/tree/master/samples-generator

这个工具可以自动生成3dtiles格式

网址五:https://www.cnblogs.com/onsummer/p/13252896.html

发现一个同行,有不少研究心得

由于有了这些轮子,基本上不需要再自己设计了,我们只需要加工即可。

B3dm格式验证

文件名:lib\validateB3dm.js

B3dm例子解读

这里推荐一个json格式化的工具:

https://www.bejson.com/explore/index_new/0

featureTableJson:

代码语言:javascript
代码运行次数:0
复制
{
    "BATCH_LENGTH": 10,
    "RTC_CENTER": [
        1214914.5525041146,
        -4736388.031625768,
        4081548.0407588882
    ]
}
代码语言:javascript
代码运行次数:0
复制
  • BATCH_LENGTH:模型的个数,即这个B3dm的文件里面有10个模型
  • RTC_CENTER:模型中心点的坐标,即下面所有模型的坐标都是以这个中心点为原点的坐标。

batchTableJson:

代码语言:javascript
代码运行次数:0
复制


{
    "id": [
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9
    ],
    "Longitude": [
        -1.3197004795898053,
        -1.3197036065852055,
        -1.319708772296242,
        -1.3197052536661238,
        -1.3197012996975566,
        -1.3197180493677987,
        -1.3197058762367364,
        -1.3196853243969762,
        -1.3196881546957797,
        -1.3197161145487923
    ],
    "Latitude": [
        0.6988582109,
        0.6988621128191176,
        0.698870582386204,
        0.6988575056044288,
        0.6988603596248432,
        0.6988530761634713,
        0.6988687144359211,
        0.6988698975892317,
        0.6988569944876143,
        0.6988651780819983
    ],
    "Height": [
        11.721514919772744,
        12.778013898059726,
        9.500697679817677,
        8.181250356137753,
        10.231159372255206,
        12.68863015063107,
        6.161747192963958,
        7.122806219384074,
        12.393268510699272,
        11.431036269292235
    ]
}

这里的id、Longitude、Latitude和Height都拥有10个元素的数组,这里其实是和上面的BATCH_LENGTH为10是一一对应的。也就是说这个字符串保存的是每个模型对应的属性信息。

接下来我,我们来研究gltf的json如下:

代码语言:javascript
代码运行次数:0
复制
  
代码语言:javascript
代码运行次数:0
复制
  "scenes": [
        {
            "nodes": [
                0
            ]
        }
    ]
代码语言:javascript
代码运行次数:0
复制

scenes场景引用了nodes数组下标为0的对象。

代码语言:javascript
代码运行次数:0
复制


    "nodes": [
        {
            "matrix": [
                1,
                0,
                0,
                0,
                0,
                0,
                -1,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                0,
                1
            ],
            "mesh": 0,
            "name": "rootNode"
        }

matrix是矩阵变换,这里的变化矩阵是为了使gltf的进行Z轴向上的翻转,具体参考官网介绍

https://github.com/CesiumGS/3d-tiles/blob/master/specification/README.md#gltf-transforms

nodes节点又引用了meshs数组下标为0的节点。

代码语言:javascript
代码运行次数:0
复制


    "meshes": [
        {
            "primitives": [
                {
                    "attributes": {
                        "POSITION": 0,
                        "NORMAL": 1,
                        "_BATCHID": 2
                    },
                    "indices": 3,
                    "material": 0,
                    "mode": 4
                }
            ]
        }
    ]

POSITION、NORMAL、_BATCHID、indices和material对于的值,都对于与accessors的数组的索引,mode表示网格体的类型,这里4表示是三角网。其他详细描述参考下面网址:

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0/#primitivemode

代码语言:javascript
代码运行次数:0
复制
  
代码语言:javascript
代码运行次数:0
复制
  "accessors": [
        {
            "bufferView": 0,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -69.262685040012,
                -63.42564369086176,
                -51.21932876482606
            ],
            "max": [
                84.98775890329853,
                61.14907375629991,
                46.49423664715141
            ]
        },
        {
            "bufferView": 1,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -0.9686407230533828,
                -0.7415693003175017,
                -0.7655772493024053
            ],
            "max": [
                0.9686407230533828,
                0.7415693003175017,
                0.7655772493024053
            ]
        },
        {
            "bufferView": 2,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "SCALAR",
            "min": [
                0
            ],
            "max": [
                9
            ]
        },
        {
            "bufferView": 3,
            "byteOffset": 0,
            "componentType": 5123,
            "count": 360,
            "type": "SCALAR",
            "min": [
                0
            ],
            "max": [
                239
            ]
        }
    ]
代码语言:javascript
代码运行次数:0
复制

accessors定义了4个bufferview。刚好和上面的索引可以对应上。我们研究第一个就可以了

代码语言:javascript
代码运行次数:0
复制
     
代码语言:javascript
代码运行次数:0
复制
   {
            "bufferView": 0,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -69.262685040012,
                -63.42564369086176,
                -51.21932876482606
            ],
            "max": [
                84.98775890329853,
                61.14907375629991,
                46.49423664715141
            ]
        }
代码语言:javascript
代码运行次数:0
复制
  • bufferView:引用了bufferviews数组的索引为0
  • byteOffset:bufferviews数据偏移0字节
  • componentType:5126 代表数值类型为float
  • count:代表由240个vec3数据
  • type:数据类型为三维向量 VEC3
  • min:max:表示240个vec3的最小和最大值
代码语言:javascript
代码运行次数:0
复制
 "bufferViews": [
        {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 0,
            "target": 34962,
            "byteStride": 12
        },
        {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 2880,
            "target": 34962,
            "byteStride": 12
        },
        {
            "buffer": 0,
            "byteLength": 960,
            "byteOffset": 5760,
            "target": 34962,
            "byteStride": 4
        },
        {
            "buffer": 0,
            "byteLength": 720,
            "byteOffset": 6720,
            "target": 34963
        }
    ]
代码语言:javascript
代码运行次数:0
复制

bufferviews我们也研究第一个数据,如下:

具体可以参考下面网址:

https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md

代码语言:javascript
代码运行次数:0
复制
    
代码语言:javascript
代码运行次数:0
复制
    {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 0,
            "target": 34962,
            "byteStride": 12
        }

buffer:引用buffer数组索引的为0

byteLength:字节的长度

byteOffset:buffer数据偏移0个字节开始

target:34962, 表示 ARRAY_BUFFER 表示这个数据是顶点属性,另外还可以表示顶点索引 通34963

byteStride:表示每个元素实际上占用12个字节,可以通过下图有个直观的了解byteStride的作用。

接下来就是buffer了

代码语言:javascript
代码运行次数:0
复制
   
代码语言:javascript
代码运行次数:0
复制
 "buffers": [
        {
            "name": "buffer",
            "byteLength": 7440
        }
    ]
代码语言:javascript
代码运行次数:0
复制

这里buffer为7440大小保存了上面所有引用的数据。

完整的json格式如下:

代码语言:javascript
代码运行次数:0
复制
{
    "accessors": [
        {
            "bufferView": 0,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -69.262685040012,
                -63.42564369086176,
                -51.21932876482606
            ],
            "max": [
                84.98775890329853,
                61.14907375629991,
                46.49423664715141
            ]
        },
        {
            "bufferView": 1,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -0.9686407230533828,
                -0.7415693003175017,
                -0.7655772493024053
            ],
            "max": [
                0.9686407230533828,
                0.7415693003175017,
                0.7655772493024053
            ]
        },
        {
            "bufferView": 2,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "SCALAR",
            "min": [
                0
            ],
            "max": [
                9
            ]
        },
        {
            "bufferView": 3,
            "byteOffset": 0,
            "componentType": 5123,
            "count": 360,
            "type": "SCALAR",
            "min": [
                0
            ],
            "max": [
                239
            ]
        }
    ],
    "asset": {
        "generator": "3d-tiles-samples-generator",
        "version": "2.0"
    },
    "buffers": [
        {
            "name": "buffer",
            "byteLength": 7440
        }
    ],
    "bufferViews": [
        {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 0,
            "target": 34962,
            "byteStride": 12
        },
        {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 2880,
            "target": 34962,
            "byteStride": 12
        },
        {
            "buffer": 0,
            "byteLength": 960,
            "byteOffset": 5760,
            "target": 34962,
            "byteStride": 4
        },
        {
            "buffer": 0,
            "byteLength": 720,
            "byteOffset": 6720,
            "target": 34963
        }
    ],
    "materials": [
        {
            "pbrMetallicRoughness": {
                "baseColorFactor": [
                    1,
                    1,
                    1,
                    1
                ],
                "roughnessFactor": 1,
                "metallicFactor": 0
            },
            "alphaMode": "OPAQUE",
            "doubleSided": false,
            "emissiveFactor": [
                0,
                0,
                0
            ]
        }
    ],
    "meshes": [
        {
            "primitives": [
                {
                    "attributes": {
                        "POSITION": 0,
                        "NORMAL": 1,
                        "_BATCHID": 2
                    },
                    "indices": 3,
                    "material": 0,
                    "mode": 4
                }
            ]
        }
    ],
    "nodes": [
        {
            "matrix": [
                1,
                0,
                0,
                0,
                0,
                0,
                -1,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                0,
                1
            ],
            "mesh": 0,
            "name": "rootNode"
        }
    ],
    "scene": 0,
    "scenes": [
        {
            "nodes": [
                0
            ]
        }
    ]
}
代码语言:javascript
代码运行次数:0
复制

buffer数据获取

这里决定取出buffer内部的一些数据对我们上述的理解进行验证

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebHub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
WebGL简易教程(十五):加载gltf模型
一般来说,图形渲染总是需要从磁盘数据开始,最终保存到磁盘数据中,保存这种数据的就是3D模型文件。3D模型文件一般会把顶点、索引、纹理、材质等等信息都保存起来,方便下次直接读取。3D模型文件格式一般是与图形渲染工作强关联的,了解3D模型文件格式的组成,有助于进一步了解图形渲染的流程。
charlee44
2020/02/14
4.9K1
DEM转换为gltf
DEM(地形文件)天然自带三维信息,可以将其转换成gltf模型文件。DEM是栅格数据,可以通过GDAL进行读取;gltf是一种JSON格式,可以采用nlohmann/json进行读写。
charlee44
2020/01/14
1.3K0
DEM转换为gltf
gltfOverview中文翻译
https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/figures/gltfOverview-2.0.0b.png
Jean
2021/04/07
1.7K0
gltfOverview中文翻译
【愚公系列】2022年09月 微信小程序-three.js加载3D模型
Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机、光影、材质等各种对象。
愚公搬代码
2022/09/28
5.3K0
【愚公系列】2022年09月 微信小程序-three.js加载3D模型
3D领域的jpg?模型交换格式glTF概述
在3D开发领域,存储模型是一个基本需求,对于前端也不例外。就像一般网页需要使用jpg、png、webp等格式渲染图片一样,3d页面/软件/游戏的开发者,也需要把角色、场景、动画等等信息,按照某种格式存储下来,使用时解析并渲染。
WendyGrandOrder
2020/10/30
4.2K0
Cesium入门之十:Cesium加载3DTiles数据
3DTiles是一种面向网格化、可展示的大规模三维空间数据格式,专门为流式传输和渲染海量3D地理空间数据而设计的,用于存储和管理基于网格的三维模型数据。其数据结构基于B3DM和PNTS格式,可以支持多个级别的LOD,并使用Tilesets(瓦片集合)来组织和管理数据。3DTiles具有以下特点:
九仞山
2023/10/14
5.2K0
Cesium入门之十:Cesium加载3DTiles数据
谈谈3D Tiles(1):渲染调度
Cesium在2016年3月份左右推出3D Tiles数据规范,在glTF基础上提供了LOD能力,定位就是Web环境下海量三维模型数据。虽然目前3D Tiles还是Beta阶段,有不少硬伤,但3D Tiles数据规范于2016年9月30日开始了OGC标准化进程,积极成分还是很大。 之前的glTF时分享了个人对二进制格式的一些想法和谨慎的态度。3D Tiles简单说就是具备LOD能力的glTF。有了数据首先是提供API可以渲染,保证用起来,下一步就要了解该数据规范的具体特点,比如倾斜,矢量,点云,OSM等支持
Peter Lu
2018/06/20
2.9K0
【过程记录】Mars3D加载3DTiles三维模型
因为项目需要,去做了三维模型加载的相关调研,发现Mars3D这样一个好用的框架,可以动态加载3DTiles三维模型,并且官方有详细的文档和规范的代码,很容易就可以上手。
zstar
2022/09/26
3.3K0
Cesium基础使用介绍
前言 最近折腾了一下三维地球,本文简单为大家介绍一款开源的三维地球软件——Cesium,以及如何快速上手Cesium。当然三维地球重要的肯定不是数据显示,这只是数据可视化的一小部分,重要的应该是背后的数据生成及处理等。本文先为大家介绍这简单的部分。 一、 Cesium简介 Github地址:https://github.com/AnalyticalGraphicsInc/cesium。官方介绍如下: An open-source JavaScript library for world-class 3D
魏守峰
2018/04/28
6.8K0
Cesium基础使用介绍
漫天花雨HTML特效+3D相册
HTML特效是指在网页中使用各种技术和代码来实现动态效果的一种方式。这些效果可以是动画、过渡、交互和其他视觉效果。HTML特效可以在不影响网页性能的同时增强用户体验。
淼学派对
2023/10/14
5080
漫天花雨HTML特效+3D相册
面试官:请使用 OpenGL ES 将 RGB 图像转换为 YUV 格式。我 ……
最近,有位读者大人在后台反馈:在参加一场面试的时候,面试官要求他用 shader 实现图像格式 RGB 转 YUV ,他听了之后一脸懵,然后悻悻地对面试官说,他只用 shader 做过 YUV 转 RGB,不知道 RGB 转 YUV 是个什么思路。
字节流动
2021/06/09
5.2K1
面试官:请使用 OpenGL ES 将 RGB 图像转换为 YUV 格式。我 ……
NDK OpenGL ES 3.0 开发(二十一):3D 模型加载和渲染
上一节简单介绍了常用的 3D 模型文件 Obj 的数据结构和模型加载库 Assimp 的编译,本节主要介绍如何使用 Assimp 加载 3D 模型文件和渲染 3D 模型。
字节流动
2020/06/02
9220
如果正确读取SQL Server中的扩展事件?
    SQL Server中使用扩展事件捕捉所需的信息后,可以选择存放的位置。比如说内存或文件中,但无论存在哪里,其本质都是一个大XML。因此在SQL Server中读取该XML就是解析扩展事件结果的方式。     微软官方或者一些SQL Server论坛提供了使用SQL XML解析扩展事件的脚本,如代码清单1所示。 1: WITH events_cte 2: AS ( SELECT DATEADD(mi, 3:
用户1217611
2018/01/30
1.4K0
OpenGL ES 文字渲染进阶--渲染中文字体
旧文 OpenGL ES 文字渲染方式有几种? 一文中分别介绍了 OpenGL 利用 Canvas 和 FreeType 绘制文字的方法。 无论采用哪种方式进行渲染,本质上原理都是纹理贴图:将带有文字的图像上传到纹理,然后进行贴图。
字节流动
2021/07/05
1.4K0
OpenGL ES 文字渲染进阶--渲染中文字体
OpenGL ES 2.0 (iOS)[06-1]:基础纹理
Texture 在 OpenGL 里面有很多种类,但在 ES 版本中就两种——Texture_2D + Texture_CubeMap;
半纸渊
2018/08/30
2.1K0
OpenGL ES 2.0 (iOS)[06-1]:基础纹理
Presto对ORC格式的优化
最近Presto的官网发表了一篇文章,叙述了新版本的Presto对ORC格式读取的性能优化过程,包含了很多代码细节,非常有趣,故进行简单编译。
哒呵呵
2019/05/16
2.6K0
Presto对ORC格式的优化
PixiJS 源码解读:绘制矩形的渲染过程讲解
之前写了一篇 PixiJS 绘制矩形,简单说了一下 PixiJS 是怎么绘制矩形的。
前端西瓜哥
2023/09/11
5020
PixiJS 源码解读:绘制矩形的渲染过程讲解
Android多媒体之GLES2战记第五集--宇宙之光
你以为我的封面图只是吸引眼球? 上集说到:用矩阵的变换来操作顶点,使图形产生相应的变化(移动,选择,缩放) 这一集将点亮世界之光,让你对OpenGL的世界有更深的了解 普通副本五:黑龙之珠
张风捷特烈
2019/03/05
7720
深度学习框架OneFlow是如何和ONNX交互的?
在开始阅读本篇文章之前,如果你对ONNX不是很了解介意先阅读我之前写的这几篇介绍ONNX文章:
BBuf
2021/04/16
1.3K0
TensorFlow小程序探索实践
最近业余时间做些创新探索,在微信小程序上实现找到纸或笔记本,定位,然后取到纸上的简笔画,之后进行简笔画识别,找到对应位置(之后可以在此位置上加载对应3d模型,实现ar效果, 对应ar官方案例:https://github.com/bbSpider/miniprogramThree)
EchoROne
2022/12/29
2.1K0
TensorFlow小程序探索实践
推荐阅读
相关推荐
WebGL简易教程(十五):加载gltf模型
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文