共计 2004 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
在 GIS 与游戏引擎的融合开发中,我们常常遇到无坐标三维模型(如艺术资产、扫描模型)难以匹配真实世界地形的难题。典型表现包括:
- 比例失调:模型在 WGS84 坐标系下被压缩成蚂蚁大小
- 高程错位:模型要么漂浮在空中,要么半截陷入地下
- 朝向偏差:模型 Z 轴与真实世界法向量不匹配
这些问题源于两种坐标系的本质差异:Unreal 使用左手笛卡尔坐标系(单位:厘米),而 Cesium 采用 WGS84 椭球体坐标系(单位:弧度 / 米)。
坐标系转换原理
核心概念对照
- ECEF (Earth-Centered, Earth-Fixed):地心地固坐标系
- ENU (East-North-Up):东北天局部坐标系
- Geodetic:大地坐标系(经度 / 纬度 / 高度)
转换流程遵循:
Geodetic → ECEF → ENU → Unreal World
数学表达为:
\begin{bmatrix}
x_{ENU} \\
y_{ENU} \\
z_{ENU}
\end{bmatrix}
=
R \cdot
(\begin{bmatrix}
x_{ECEF} \\
y_{ECEF} \\
z_{ECEF}
\end{bmatrix}
- \begin{bmatrix}
x_{origin} \\
y_{origin} \\
z_{origin}
\end{bmatrix})
其中旋转矩阵 R 由原点处的地理法向量确定。
核心实现步骤
1. 地形高程采样
使用 CesiumGeoreference 组件建立坐标基准:
- 在场景中放置
CesiumGeoreferenceActor - 设置
Origin Latitude/Longitude为模型目标区域中心 - 通过蓝图调用
Get Viewport Geo Location获取鼠标位置地理坐标
关键采样代码段:
// 获取地形高程(基于 WGS84 椭球体)float Height = CesiumGeoreference->TransformLongitudeLatitudeHeightToUnreal(FVector(Lon, Lat, 0)).Z;
2. 模型顶点变换
通过 FTransform 实现坐标系对齐:
- 计算模型包围盒中心点 P 的 ECEF 坐标
- 转换为相对于场景原点的 ENU 坐标
- 构建包含缩放、旋转的变换矩阵
FTransform ENUTransform = FTransform(FRotator(0, -OriginYaw, 0),
FVector::ZeroVector,
FVector(1, 1, 1)
);
3. 动态投影校准
在材质中使用世界位置偏移补偿地球曲率:
void WorldPositionOffset(
float3 WorldPos,
out float3 Offset
){float3 EllipsoidNormal = normalize(WorldPos);
Offset = -EllipsoidNormal * DisplacementAmount;
}
完整蓝图实现

关键节点说明:
- Cesium3DTileset 加载
- 设置
Url指向地形数据源 -
MaximumScreenSpaceError建议值 4 -6 -
高程采样模块
[GetHeightFromEarthEllipsoid] │ ├─ Longitude → 输入模型经度 ├─ Latitude → 输入模型纬度 └─ Return Value → 输出椭球面高程 -
坐标转换模块
[TransformEarthCenteredEarthFixedToUnreal] │ ├─ ECEF → 输入 ECEF 坐标 └─ Return Value → 输出 Unreal 世界坐标
性能优化策略
- 采样频率控制:
- 静态模型:每 5 帧采样一次(半径 50 米)
-
动态模型:每帧采样(半径 10 米)
-
LOD 分级:
| 距离阈值 | 采样精度 | |----------|----------| | 0-100m | 0.5m | | 100-500m | 2m | | >500m | 10m |
常见问题排查
- 模型漂浮 / 穿透
- 检查
CesiumGeoreference原点是否在模型中心 10km 范围内 -
验证
GetHeightFromEarthEllipsoid是否返回有效值 -
材质扭曲
- 禁用材质的
World Position Offset动态效果 -
检查 UV 坐标是否使用
Planar Mapping模式 -
性能骤降
- 确认
Cesium3DTileset的PreloadAncestors已关闭 - 降低
MaximumScreenSpaceError至 8 以上
进阶探索方向
- 动态地形更新
- 通过 Cesium ion API 实时获取滑坡、洪水等地形变化
-
使用
CesiumRasterOverlay加载高程差异图 -
Nanite 极限测试
- 在
Nanite Enabled模式下验证千万级面片地形的贴合精度 - 对比
Virtual Texture与常规材质的性能差异
实测效果
在 RTX 3080 显卡上测试 100km²区域:
| 方案 | 帧率(FPS) | 内存占用 |
|---|---|---|
| 基础实现 | 72 | 3.2GB |
| +LOD 优化 | 94 | 2.7GB |
| +Nanite | 108 | 4.1GB |
建议根据项目需求平衡精度与性能,通常采样半径 20m+0.5m 精度可满足大部分场景。
正文完
发表至: GIS开发
近两天内
