@realsee/five
Version:
Realsee Renderer SDK
173 lines (123 loc) • 8.77 kB
Markdown
# 3DTile (3D 瓦片)
- **Summary**: Five 用于加载和渲染大规模三维场景的核心模块,支持动态 LOD 调度与流式加载。
- **Schema**: 对应 `ParameterTilesetValue` 接口,通过 Parameter 配置 LOD、显存与并发控制。
- **Concepts**: LOD (细节层级), SSE (屏幕空间误差), Cache Management (显存管理), ViewLayer (视图层)。
- **Configuration**: 包含画质精度、显存配额、几何误差、并发请求等详细参数。
- **Examples**: 画质平衡与多图层优化。
## Schema
> **Definition**: [ParameterTilesetValue](../../five/model/parameter.d.ts)
以下是 `ParameterTilesetValue` 的 TypeScript 定义摘要:
```typescript
export interface ParameterTilesetValue {
/** 屏幕空间误差阈值 (像素) */
maxScreenSpaceError: number;
/** 最大显存占用 (MB) */
maxMemoryUsage: number;
/** 最小几何误差 (精度上限锁) */
minGeometricError: number;
// ... 更多字段见下方配置表
}
```
## Concepts
### 1. LOD & Screen Space Error (SSE)
LOD (Level of Detail) 是 3DTile 的核心机制。引擎不会一次性加载整个从宏观到微观的所有模型数据,而是根据相机位置动态计算每个瓦片的 **屏幕空间误差 (SSE)**。
* **Geometric Error (几何误差)**: 3D Tiles 数据源中定义的指标(单位:米),表示当前瓦片与真实物体之间的最大形状差异。
* **根节点**: 误差巨大(如 100米),仅有模糊轮廓。
* **叶子节点**: 误差极小(如 0.01米),细节丰富。
* **SSE 计算逻辑**: `SSE = (GeometricError / DistanceToCamera) * ScreenHeight`。
* **判定标准**: 如果 `SSE > maxScreenSpaceError`,说明当前瓦片在屏幕上看起来太粗糙(误差像素太大),需要分裂并加载下一级子瓦片;反之则停止细分。
* **调整影响**: 调低 `maxScreenSpaceError` 会迫使引擎加载更深层级的瓦片,从而获得更清晰的细节,但也会急剧增加渲染三角形数量和显存占用。
### 2. 显存管理 (Cache Management)
为了在浏览器有限的资源下渲染海量数据(如城市级倾斜摄影),3DTile 实现了基于 LRU (Least Recently Used) 的缓存淘汰机制和动态画质调整策略。
* **LRU 淘汰**: 当 `maxMemoryUsage` 超限时,引擎会优先保留当前视锥体内的瓦片。视锥体外的、或者距离相机较远的瓦片会被优先释放。
* **动态画质调整 (Dynamic Scaling)**: 如果开启了 `memoryAdjustedScreenSpaceError`,引擎会以 `maxMemoryUsage` 为目标,实时调整 SSE。
* **目标**: 尽量跑满 `maxMemoryUsage` 设定的显存额度,不浪费资源。
* **范围**: 实际 SSE 会在 `1.0` (极高画质) 到 `maxScreenSpaceError` (设定底线) 之间波动。
* **场景**: 适合显存充足但希望自动平衡画质的场景。
### 3. ViewLayer 与 3DTile
目前所有的 `ViewLayer` 在底层都是一个 `Tile3D` 实例。它们各自拥有独立的:
* **配置**: `maxScreenSpaceError`, `maxMemoryUsage` 等参数互不干扰。
* **缓存**: 显存配额各自独立计算。
> **注意**: 即使是通过 `file_url` 加载的单体模型(如 `.obj`, `.at3d`),在 Five 内部也会被封装为 `Tile3D` 实例进行统一管理。
## Configuration
以下表格列出了控制 3DTile 加载与性能调度的所有可用参数。
### Core Quality & Performance (核心画质与性能)
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `maxScreenSpaceError` | `number` | `16` | **核心参数**。屏幕空间误差阈值 (像素)。<br>值越小画质越高,性能开销越大。建议范围 8-32。 |
| `maxMemoryUsage` | `number` | `512` | 最大显存占用 (MB)。超限后自动触发 LRU 淘汰机制。 |
| `memoryAdjustedScreenSpaceError` | `boolean` | `false` | 是否开启基于内存的动态 SSE 调整。<br>开启后引擎会自动调整 SSE 以尽量占满显存配额。 |
| `cameraCulling` | `boolean` | `true` | 是否开启视锥体剔除 (不加载视野外的瓦片)。**建议始终开启**。 |
### Geometric Error Control (几何误差控制)
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `minGeometricError` | `number` | `0` | 最小几何误差 (精度上限锁)。<br>当瓦片误差小于此值时停止细分。可用于限制过高精度的加载。 |
| `maxGeometricError` | `number` | `10000` | 最大几何误差 (最低精度保证)。<br>强制细分直到误差小于此值。可用于避免模型过于模糊。 |
### Network & Loading (网络与加载)
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `maxRequests` | `number` | `4` | 最大并发请求数。建议保持默认,避免网络拥堵。 |
| `requestOrder` | `string` | `'SCREEN_SPACE_ERROR'` | 请求优先级策略。<br>`'SCREEN_SPACE_ERROR'`: 优先加载 SSE 大的瓦片;<br>`'SCREEN_LEVEL_VERTICAL'`: 优先加载垂直层级高的。 |
| `loadSiblings` | `boolean` | `true` | 是否预加载兄弟节点。 |
| `skipLevelOfDetail` | `boolean` | `false` | 是否允许跳级加载 (跳过中间层级直接加载高精瓦片)。 |
### Legacy LOD Control (不推荐)
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `minLevelOfDetail` | `number` | `0` | 最小 LOD 层级 (Tree Depth)。建议使用 `maxGeometricError` 替代。 |
| `maxLevelOfDetail` | `number` | `20` | 最大 LOD 层级 (Tree Depth)。建议使用 `minGeometricError` 替代。 |
## Examples
### 1. Adjusting Quality & Memory (调整画质与内存平衡)
在移动端或性能受限设备上,建议适当降低画质以保证流畅度。
```typescript
const parameter = five.modelScene.parameter;
// 1. 性能优先模式 (适用于低端设备)
// 增大 SSE 阈值,降低画质
parameter.set('maxScreenSpaceError', 16);
// 限制显存,防止 Crash
parameter.set('maxMemoryUsage', 256);
// 2. 画质优先模式 (适用于桌面端/截图)
// 减小 SSE 阈值,提升细节
parameter.set('maxScreenSpaceError', 4);
// 允许更多显存占用
parameter.set('maxMemoryUsage', 1024);
// 3. 重置为默认
parameter.reset('maxScreenSpaceError', 'maxMemoryUsage');
```
### 2. Multi-ViewLayer Optimization (多 ViewLayer 优化)
在对比查看或多楼层场景中,通常存在多个 `ViewLayer`。为了避免资源竞争,建议对非焦点的 ViewLayer 进行降级处理。
```typescript
// 假设 viewLayerA 是当前主要查看的模型,viewLayerB 是背景参考
// 聚焦 ViewLayerA: 正常画质
viewLayerA.parameter.reset('maxScreenSpaceError');
// 降级 ViewLayerB: 仅显示轮廓,节省资源
viewLayerB.parameter.set('maxScreenSpaceError', 48); // 极低画质
viewLayerB.parameter.set('maxMemoryUsage', 128); // 极低显存配额
```
## Debugging
在开发过程中,可以通过访问 `ViewLayer` 内部的 `tileset` 对象来实时监控渲染状态。
```typescript
// 假设已获取 viewLayer 实例
const tileset = viewLayer.tileset;
// 1. 查看当前加载的瓦片数量
console.log(tileset.loadedTiles.size);
// 2. 查看当前实际生效的 SSE (如果开启了动态调整,此值会波动)
console.log(tileset.currentMaxScreenSpaceError);
// 3. 查看显存占用 (近似值,单位字节)
// 注意: 这是内部私有属性,仅供调试参考
console.log((tileset as any).cacheMemoryUsageInBytes / 1024 / 1024 + ' MB');
```
## Common Pitfalls
1. **误解 GeometricError 作用域**: `minGeometricError` 和 `maxGeometricError` 是**全局硬约束**,不随相机距离变化。
* 错误设置(例如将 `maxGeometricError` 设得极小)会强制全场景所有瓦片(哪怕是远处的背景)都加载到极高精度。
* 这会导致三角形数量和显存占用**指数级爆炸**,瞬间卡死浏览器。
2. **过度降低 `maxScreenSpaceError`**: 设置过小(如 < 4)可能导致每帧需要加载和渲染的三角形数量指数级上升,瞬间撑爆显存或导致掉帧。
3. **忽略 `cameraCulling`**: 默认应该开启。如果手动关闭视锥体剔除,引擎将尝试加载全场景数据,极易导致崩溃。
4. **频繁切换配置**: `maxMemoryUsage` 等参数的修改会触发缓存整理,高频修改可能导致卡顿。
## Related
* [Parameter](./parameter.md): 了解参数的继承关系及材质、点云相关配置。
* [Model](./model.md): 了解 Model 和 ViewLayer 的关系。
* [Work](./work.md): 了解 Work 数据结构。
---
```yaml
tags: [大场景, 瓦片, 显存, 画质, 性能优化, 流式加载, 3dtile, viewLayer, performance, lod, optimization, tile-loading, memory, sse, screen-space-error]
```