deck.gl Tile3DLayer 深度指南:加载 3D Tiles 与 ESRI I3S 三维瓦片数据

发布时间:2026/9/15 13:10:38
deck.gl Tile3DLayer 深度指南:加载 3D Tiles 与 ESRI I3S 三维瓦片数据 deck.gl Tile3DLayer 深度指南加载 3D Tiles 与 ESRI I3S 三维瓦片数据【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.glTile3DLayer 是 deck.gl 的 geo-layers 模块中用于渲染海量三维场景数据的核心图层它直接消费符合 OGC 3D Tiles 规范与 Esri I3S 规范的瓦片数据可对接 Cesium ion、ArcGIS、Google Maps 等主流三维瓦片服务。读完本文你将掌握 Tile3DLayer 的安装、三种主流数据源接入Cesium ion / ArcGIS I3S / Google Maps、全部核心参数与回调的用法并理解其在源码层面如何将不同类型的瓦片分发到 PointCloudLayer、ScenegraphLayer 与 SimpleMeshLayer 等子图层进行渲染。一、Tile3DLayer 是什么Tile3DLayer用于渲染以3D TilesOGC 3D Tiles Specification和ESRI I3SIndexed 3D Scene Layer格式组织的三维瓦片数据瓦片数据的解析由 loaders.gl 生态中的Tiles3DLoader完成。从类型上看Tile3DLayer 是一个 CompositeLayer复合图层它本身不直接绘制几何体而是依据每个瓦片的格式类型将渲染任务委托给以下基础图层见源码 tile-3d-layer.ts 中的_getSubLayer分发逻辑点云瓦片pnts→ PointCloudLayer批量 3D 模型b3dm与实例化 3D 模型i3dm→ ScenegraphLayerEsri MeshPyramids 网格数据→ SimpleMeshLayer本项目内为 mesh-layer 模块的MeshLayer这意味着用户只需提供瓦片数据入口 URLTile3DLayer 便会自动完成瓦片树tileset的解析、视口内瓦片的选择、瓦片内容的加载与子图层创建是一条开箱即用的三维瓦片渲染链路。二、快速上手三种主流数据源示例2.1 从 Cesium ion 加载 3D TilesCesium ion 是最常见的 3D Tiles 托管服务。接入时需要先用CesiumIonLoader作为解码器并在loadOptions[cesium-ion]中传入资产对应的 access token。下面给出完整可运行的 JavaScript 版本import {Deck} from deck.gl/core; import {Tile3DLayer} from deck.gl/geo-layers; import {CesiumIonLoader} from loaders.gl/3d-tiles; const layer new Tile3DLayer({ id: tile-3d-layer, // Tileset json 文件入口 URL data: https://assets.cesium.com/43978/tileset.json, loader: CesiumIonLoader, loadOptions: { // 在 Cesium ion 账户中为资产生成 access token cesium-ion: {accessToken: ion_access_token_for_your_asset} }, onTilesetLoad: tileset { // 瓦片集加载完成后将相机重新居中到瓦片集覆盖范围 const {cartographicCenter, zoom} tileset; deckInstance.setProps({ initialViewState: { longitude: cartographicCenter[0], latitude: cartographicCenter[1], zoom } }); }, pointSize: 2 }); const deckInstance new Deck({ initialViewState: { longitude: 10, latitude: 50, zoom: 2 }, controller: true, layers: [layer] });对应的TypeScript写法除类型标注外并无差异核心是引入Tileset3D类型并给回调参数标注import {Deck} from deck.gl/core; import {Tile3DLayer} from deck.gl/geo-layers; import {CesiumIonLoader} from loaders.gl/3d-tiles; import type {Tileset3D} from loaders.gl/tiles; const layer new Tile3DLayer({ id: tile-3d-layer, data: https://assets.cesium.com/43978/tileset.json, loader: CesiumIonLoader, loadOptions: { cesium-ion: {accessToken: ion_access_token_for_your_asset} }, onTilesetLoad: (tileset: Tileset3D) { const {cartographicCenter, zoom} tileset; deckInstance.setProps({ initialViewState: { longitude: cartographicCenter[0], latitude: cartographicCenter[1], zoom } }); }, pointSize: 2 });在React中只需将Deck换成DeckGL组件并把initialViewState放入 React state通过onTilesetLoad回调更新import React, {useState} from react; import {DeckGL} from deck.gl/react; import {Tile3DLayer} from deck.gl/geo-layers; import {CesiumIonLoader} from loaders.gl/3d-tiles; import type {MapViewState} from deck.gl/core; import type {Tileset3D} from loaders.gl/tiles; function App() { const [initialViewState, setInitialViewState] useStateMapViewState({ longitude: 10, latitude: 50, zoom: 2 }); const layer new Tile3DLayer({ id: tile-3d-layer, data: https://assets.cesium.com/43978/tileset.json, loader: CesiumIonLoader, loadOptions: { cesium-ion: {accessToken: ion_access_token_for_your_asset} }, onTilesetLoad: (tileset: Tileset3D) { const {cartographicCenter, zoom} tileset; setInitialViewState({ longitude: cartographicCenter[0], latitude: cartographicCenter[1], zoom }); }, pointSize: 2 }); return DeckGL initialViewState{initialViewState} controller layers{[layer]} /; }仓库中 examples/website/3d-tiles/app.tsx 提供了一个可直接运行的 React 参考实现它使用 Cesium ion 的 asset 43978费城建筑模型并在onTilesetLoad中重定位相机、通过updateAttributions上报瓦片集的版权归属信息。注意其中loaders数组与loader单值两种写法是等价的官方示例更推荐loaders: [CesiumIonLoader]。2.2 从 ArcGIS 加载 I3S 瓦片Esri 的 I3SIndexed 3D Scene Layer数据通过I3SLoader解码data指向 SceneServer 的图层入口import {Tile3DLayer} from deck.gl/geo-layers; import {I3SLoader} from loaders.gl/i3s; const layer new Tile3DLayer({ id: tile-3d-layer, // Tileset 入口Indexed 3D layer 文件 URL data: https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_Bldgs/SceneServer/layers/0, loader: I3SLoader });2.3 从 Google Maps 加载 3D TilesGoogle Maps 的 3D Tiles 服务不需要额外 loader默认即Tiles3DLoader只需通过loadOptions.fetch.headers携带 API Key 即可import {Tile3DLayer} from deck.gl/geo-layers; const layer new Tile3DLayer({ id: tile-3d-layer, data: https://tile.googleapis.com/v1/3dtiles/root.json, loadOptions: { fetch: {headers: {X-GOOG-API-KEY: google_maps_api_key}} } });三、安装与引入方式3.1 npm 安装推荐安装完整包或按需安装最小依赖集合npm install deck.gl # 或者按需安装 npm install deck.gl/core deck.gl/layers deck.gl/mesh-layers deck.gl/geo-layers其中deck.gl/mesh-layers提供 ScenegraphLayer渲染 b3dm/i3dm 模型deck.gl/layers提供 PointCloudLayer渲染 pnts 点云。引入与类型声明import {Tile3DLayer} from deck.gl/geo-layers; import type {Tile3DLayerProps} from deck.gl/geo-layers; new Tile3DLayerTileDataT(...props: Tile3DLayerPropsTileDataT[]);3.2 预打包脚本CDN不使用打包工具时可通过预构建的 UMD 脚本直接使用script srchttps://unpkg.com/deck.gl^9.0.0/dist.min.js/script !-- 或按模块拆分加载 -- script srchttps://unpkg.com/deck.gl/core^9.0.0/dist.min.js/script script srchttps://unpkg.com/deck.gl/layers^9.0.0/dist.min.js/script script srchttps://unpkg.com/deck.gl/mesh-layers^9.0.0/dist.min.js/script script srchttps://unpkg.com/deck.gl/geo-layers^9.0.0/dist.min.js/script随后在全局命名空间下创建图层new deck.Tile3DLayer({});四、属性Properties详解Tile3DLayer 继承 Base Layer 与 CompositeLayer 的全部属性并新增下列专有属性。源码中这些属性的默认值定义于 tile-3d-layer.ts 的defaultProps可对照查阅。4.1 渲染选项Render Optionsopacitynumber可选默认值1.0图层不透明度与 layer 中的同名属性定义一致。测试用例 tile-3d-layer.spec.ts 演示了运行期将opacity更新为0.5后所有已创建子图层的不透明度都会被同步更新。pointSizenumber可选默认值1.0所有点的全局像素半径。仅当瓦片格式为pnts点云时生效该值会通过_makePointCloudLayer直接传给子图层 PointCloudLayer见 tile-3d-layer.ts。4.2 数据属性Data Propertiesdatastring3D Tiles 的 Tileset JSON 文件入口 URL或 Esri I3S 的 Indexed 3D Scene Layer 文件入口 URL。仓库测试数据 test/data/3d-tiles/tileset.json 给出了标准 Tileset JSON 结构顶层包含asset.version、geometricError与root节点root内通过boundingVolume、refine如ADD、content.uri与children构成递归的瓦片树。loaderobject默认值Tiles3DLoader用于解码所获取瓦片的 loader。可用选项包括Tiles3DLoader标准 3D Tiles 解码器默认CesiumIonLoaderCesium ion 服务加载器需要配合loadOptions[cesium-ion].accessTokenI3SLoaderEsri I3S 加载器注意源码注释中标注loader已标记为 deprecated建议改用基础图层通用的loaders数组属性。在_loadTileset中优先读取props.loaders未提供时才回退到loader见 tile-3d-layer.ts。loadOptionsobject可选在 layer 的默认 loadOptions 基础上额外支持以下键cesium-ion传给CesiumIonLoader的选项3d-tiles传给Tiles3DLoader的选项i3s传给I3SLoader的选项tileset瓦片集元数据获取后透传给Tileset3D实例构造函数的参数如并发请求节流、缓存策略等典型用法示例import {CesiumIonLoader} from loaders.gl/3d-tiles; import {Tile3DLayer} from deck.gl/geo-layers; const layer new Tile3DLayer({ id: tile-3d-layer, data: https://assets.cesium.com/43978/tileset.json, loader: CesiumIonLoader, loadOptions: { tileset: { throttleRequests: false }, cesium-ion: {accessToken: ion_access_token_for_your_asset} } });源码层面_loadTileset会先将loadOptions中的tileset键剥离出来剩余选项作为瓦片内容的加载选项tileset内的参数则与Tileset3D构造参数合并见 tile-3d-layer.ts。pickableboolean可选默认值false启用拾取picking后info.object将是Tile3DHeader对象。这得益于getPickingInfo的实现当拾取命中子图层时它会将子图层props.tile中携带的Tile3D对象回填到info.object见 tile-3d-layer.ts。拾取机制的更多细节参见 picking 指南。4.3 数据访问器Data AccessorsgetPointColorAccessorColor可选默认值[0, 0, 0, 255]目标点位的 RGBA 颜色格式为r, g, b, [a]每个分量取值范围 0-255。仅当瓦片格式为pnts且点云瓦片文件中未定义颜色属性时生效见源码_makePointCloudLayer中getColor: constantRGBA || getPointColor的取值逻辑tile-3d-layer.ts。4.4 回调CallbacksonTilesetLoadFunction可选Tileset JSON 文件加载完成后调用回调参数为解析后的Tileset对象。常用于根据tileset.cartographicCenter与tileset.zoom重设相机初始视口如第二节示例。源码中在_loadTileset末尾的this.props.onTilesetLoad(tileset3d)处触发tile-3d-layer.ts。默认值onTilesetLoad: (tileset) {}onTileLoadFunction可选瓦片树中某个瓦片加载完成后调用回调参数为Tile3D对象。默认值onTileLoad: (tileHeader) {}。源码实现_onTileLoad还会先把tileHeader.tileDrawn置为false确保新瓦片的子图层首次渲染前旧瓦片仍然可见避免画面闪烁tile-3d-layer.ts。onTileUnloadFunction可选瓦片被卸载从缓存清理时调用回调参数为Tile3D对象。默认值onTileUnload: (tileHeader) {}。onTileErrorFunction可选瓦片加载失败时调用。默认值onTileError: (tileHeader, url, message) {}其中url为失败瓦片的地址message为错误信息。在initializeState中若检测到旧版属性onTileLoadFail会通过log.removed提示开发者改用onTileErrortile-3d-layer.ts。_getMeshColorFunction可选实验性根据tileHeader对象的属性动态修改网格颜色。接收tileHeader参数返回[r, g, b]数组分量范围 0-255。仅当瓦片格式为meshI3S MeshPyramids时生效主要用于 I3S 调试场景。默认值_getMeshColor: (tileHeader) [255, 255, 255]该回调会作为getColor传给 SimpleMeshLayer 子图层见 tile-3d-layer.ts。五、子图层Sub Layers与渲染管线Tile3DLayer 依据瓦片格式format渲染以下子图层子图层 ID使用的图层适用瓦片格式scenegraphScenegraphLayerb3dm批量 3D 模型、i3dm实例化 3D 模型pointcloudPointCloudLayerpnts点云meshSimpleMeshLayerEsriMeshPyramids数据对于scenegraph子图层_lighting默认设为pbr即采用基于物理的光照模型渲染 glTF 模型见_make3DModelLayertile-3d-layer.ts。三种子图层均使用COORDINATE_SYSTEM.METER_OFFSETS坐标系并以瓦片内容的cartographicOrigin为坐标原点、叠加modelMatrix变换从而在保留局部坐标精度的同时完成全球定位。在renderLayers中tile-3d-layer.ts图层会遍历tileset3d.tiles只对tile.selected被当前视口选中的瓦片创建或复用子图层并用layerMap缓存每个瓦片对应的子图层实例瓦片首次选中 → 创建子图层图层属性变更needsUpdate→ 复用旧子图层实例重建瓦片被剔除选择 → 从渲染列表移除但保留在缓存中供后续再次选中时复用。这一按需创建 缓存复用的机制是 Tile3DLayer 能流畅调度海量瓦片的关键。子图层的属性覆盖方法可参考 CompositeLayer 的 _subLayerProps 说明。此外filterSubLayertile-3d-layer.ts实现了两级裁剪未选中或不属于当前 viewport 的瓦片子图层直接跳过拾取模式下若瓦片内容中心投影到屏幕后距离拾取点过远超过视口宽高的 1/4也会被跳过以避免无谓的绘制调用。六、加载与调度流程从 URL 到屏幕综合 tile-3d-layer.ts 的源码一次完整的瓦片渲染生命周期如下数据入口updateState检测到props.data变化后调用_loadTilesettile-3d-layer.ts。预加载可选若 loader 实现了preload如 CesiumIonLoader先执行预加载以解析真实 URL 与鉴权请求头。获取 Tileset JSON通过load()拉取入口 JSON剥离tileset专属选项后将其余选项作为加载选项。构建 Tileset3D以onTileLoad/onTileUnload/onTileError/onUpdate为回调构造Tileset3D实例onUpdate会触发setNeedsUpdate驱动重绘。视口驱动瓦片选择_updateTileset将当前激活的 viewport 列表传给tileset3d.selectTiles()由 Tileset3D 计算 LOD 并决定哪些瓦片需要加载tile-3d-layer.ts。瓦片加载与子图层渲染每个瓦片加载完成后经_onTileLoad标记tileDrawn false并请求更新renderLayers遍历瓦片、为选中瓦片创建对应格式的子图层。多视口共享Tile3DLayer 可在多个视图中同时渲染。瓦片只要被任一 viewport 需要即被加载并通过单一的缓存系统在所有视口间共享——这正是源码中activeViewports/lastUpdatedViewports状态机所支撑的能力tile-3d-layer.ts。七、测试与验证仓库在 test/modules/geo-layers/tile-3d-layer/tile-3d-layer.spec.ts 中提供了两层验证异步图层渲染测试使用本地测试数据./test/data/3d-tiles/tileset.json配合 test/data 目录下的 b3dm 文件在 WebMercatorViewport 下验证图层加载后能渲染出子图层并验证opacity更新会正确传导到子图层。WebGPU 渲染测试在 WebGPU 设备上加载同一 tileset断言最终产出 ScenegraphLayer 且创建了 glTF 模型state.models.length 0同时校验tileDrawn标记证明 b3dm 内容在 WebGPU 后端下可正常绘制。若你需要用自有数据验证将本地data指向一个 Tileset JSON 即可多视口场景下Tile3DLayer 会在所有 viewport 间共享瓦片缓存避免同一瓦片的重复加载。八、小结Tile3DLayer 是 deck.gl 接入主流三维瓦片生态的桥梁data指定入口loader决定解码器loadOptions透传服务商鉴权与 Tileset3D 调优参数四个on*回调覆盖从瓦片集就绪到单瓦片加载/卸载/失败的完整生命周期pointSize与getPointColor则针对点云瓦片提供视觉定制。理解其复合图层 按格式分发子图层 视口驱动瓦片选择 统一缓存的架构能帮助你更高效地构建大型三维场景应用并为排查瓦片加载性能问题提供源码级依据。【免费下载链接】deck.glWebGL2 powered visualization framework项目地址: https://gitcode.com/GitHub_Trending/de/deck.gl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考