跳到主要内容

3D Tiles

3D Tiles 是流式传输海量 3D 数据的开放标准,适用于摄影测量采集、城市模型和地形等内容。一个 tileset 由细节逐级增加的 tile 树组成,因此查看器只需加载相机当前需要的瓦片及其细节层级。

NASA-AMMOS 的 3DTilesRendererJS 用于加载和渲染 3D Tiles,并提供 PlayCanvas 渲染器。它通过引擎的 glTF 解析器加载瓦片内容,因此瓦片也可使用引擎支持的 glTF 扩展,并支持 WebGPU 和 WebGL 2 渲染。

安装​

通过 npm 安装库和引擎:

npm install 3d-tiles-renderer playcanvas

PlayCanvas 渲染器从 3d-tiles-renderer/playcanvas 导入。

渲染瓦片集​

使用瓦片集 tileset.json 的 URL 创建 TilesRenderer,为其指定决定瓦片加载的相机,将根实体添加到场景,并逐帧更新:

import { TilesRenderer } from '3d-tiles-renderer/playcanvas';

const tiles = new TilesRenderer('https://example.com/tileset/tileset.json', app);
tiles.setCamera(camera.camera);
app.root.addChild(tiles.group);

// update the tiles every frame, after the camera has moved
app.on('update', () => {
tiles.update();
});

瓦片作为 container 资源加载,并在 tiles.group 下创建带渲染组件的实体。Application 包含所需的全部功能。使用 AppBase 时,需要注册 RenderComponentSystem,以及 ContainerHandler 和 TextureHandler 资源处理器。

瓦片集使用自己的坐标系定位,可以移动、旋转或缩放 tiles.group 或其父实体,将它放置到场景中。

设置​

属性说明
errorTarget瓦片被更高细节瓦片替换前允许的屏幕空间误差,单位为像素。值越小,加载的细节和数据越多。默认为 16。
lruCache.minBytesSize、lruCache.maxBytesSize已加载瓦片的内存预算,默认分别为 0.3 和 0.4 GiB。
fetchOptions每次请求传给 fetch 的选项,例如 mode、credentials 或 headers。
renderOptions瓦片渲染组件的选项,例如 castShadows、receiveShadows 或 layers。
assetOptions瓦片加载时使用的 container 资源选项,例如 glTF 解析器回调。

摄影测量瓦片通常带有较大的纹理。如果内存预算不足以容纳当前视图所需内容,瓦片会被卸载以给其他瓦片腾出空间,导致视图始终无法加载完成。应为这类瓦片集提高预算,同时考虑目标设备的内存限制。

压缩内容​

包含 Draco 压缩网格或 KTX2 纹理的瓦片,需要在加载前配置引擎解码器,否则这些瓦片会加载失败:

import { basisInitialize, dracoInitialize } from 'playcanvas';

dracoInitialize({
jsUrl: 'wasm/draco/draco.wasm.js',
wasmUrl: 'wasm/draco/draco.wasm.wasm'
});

basisInitialize({
glueUrl: 'wasm/basis/basis.wasm.js',
wasmUrl: 'wasm/basis/basis.wasm.wasm',
fallbackUrl: 'wasm/basis/basis.js'
});

解码器不包含在 playcanvas npm 包中,可以在引擎仓库的 examples/assets/wasm 下找到。

定制已加载瓦片​

渲染器在工作过程中会发出事件。每个瓦片加载完成后都会触发 load-model,并传入为其内容创建的实体,因此你可以修改材质。例如,摄影测量瓦片通常不受光照影响,颜色位于自发光贴图中。若希望它们参与光照并接收阴影,可以将颜色移到漫反射贴图:

tiles.on('load-model', ({ scene }) => {
for (const render of scene.findComponents('render')) {
for (const meshInstance of render.meshInstances) {
const material = meshInstance.material;
material.diffuseMap = material.emissiveMap;
material.emissiveMap = null;
material.emissive.set(0, 0, 0);
material.useLighting = true;
material.update();
}
}
});

可以通过 on 和 off,或 addEventListener 和 removeEventListener 订阅与取消订阅事件。

插件​

插件用于扩展渲染器,例如进行瓦片服务身份验证,或支持更多瓦片集功能。使用 registerPlugin 注册:

tiles.registerPlugin(plugin);

位于 3d-tiles-renderer/core/plugins 的引擎无关插件可以用于 PlayCanvas 渲染器。插件也可以是提供加载期间所需钩子函数的普通对象;下方 Helsinki 示例正是用这种方式适配其瓦片集。

限制​

  • 仅支持 glTF、GLB 和 B3DM 瓦片内容。
  • 仅支持 box 和 sphere 包围体。只有 region 包围体的瓦片不会显示。
  • 引擎变换采用 32 位精度,因此以距原点数百万米的地球坐标定位的瓦片集无法精确渲染。此类瓦片集必须在进入引擎前,以双精度将坐标重新定位到原点附近;Helsinki 示例通过插件实现这一点。
  • 不支持对瓦片进行射线检测。

示例​

火星 3D Tiles
赫尔辛基 3D Tiles