【Unity3D】Cesium加载大地图
1 前言
Cesium 是一个地球可视化平台和工具链,具有数据切片、数据分发、三维可视等功能。

Cesium 支持 JS、Unity、Unreal、O3DE、Omniverse 等平台,框架如下。

Cesium 相关链接如下:
- Cesium 官网:https://cesium.com
- CesiumLab 下载:https://www.cesiumlab.com/cesiumlab.html
- CesiumLab 手册:https://www.cesiumlab.com/CesiumLab地理信息基础数据处理平台使用手册.pdf
- CesiumLab viewer:http://localhost:9003/viewer
- Cesium ion:https://ion.cesium.com
- cesium-unity-samples:https://github.com/CesiumGS/cesium-unity-samples
- cesium-unity:https://github.com/CesiumGS/cesium-unity
- cesium-native:https://github.com/CesiumGS/cesium-native
- Cesium for Unity Quickstart:https://cesium.com/learn/unity/unity-quickstart
- Building Cesium for Unity:https://github.com/CesiumGS/cesium-unity/blob/main/Documentation~/developer-setup.md
- Cesium实验室-CSDN:https://blog.csdn.net/weixin_43805235
- Cesium实验室-B站:https://space.bilibili.com/346212872
本文实验完整资源见→Cesium加载大地图案例。
2 环境搭建
本节主要参考 Cesium for Unity Quickstart。
1)创建 3D (URP) 或 3D (HDRP) 项目

说明:官方建议 Unity Editor 最低版本为 2021.3.2f1,笔者 Unity Editor 版本为 2021.3.11f1c2;Cesium for Unity 可与通用渲染管线(URP)和高清渲染管线(HDRP)配合使用,但是,它不支持 Unity 的内置渲染器,如果选择 3D 项目作为模板,Cesium 加载的数据集将无法正确渲染。
2)添加作用域注册表
依次点击【Edit→Project Settings→Package Manager】,添加注册表信息如下。

Name: Cesium
URL: https://unity.pkg.cesium.com
Scope(s): com.cesium.unity
3)下载 Cesium For Unity
依次点击【Window→Package Manager】打开包管理器窗口,在 Packages 菜单中选择 My Registries,下载 Cesium for Unity,如下。

下载成功后, 菜单栏会多出一个 Cesium 菜单,如下。

4)连接到 Cesium ion
在 Cesium 窗口点击 Connect to Cesium io 按钮,跳转到 Web 网页,点击 Allow。


5)添加 Token
在 Cesium 窗口点击 Token 按钮,添加 token,如果没有 token,就创建一个 token,如果有 token,就使用已创建的 token。

6)创建世界地图
在 Cesium 窗口点击 Cesium World Terrain + Bing Maps Aerial imagery 添加世界地图。

场景显示如下。

如果看不见地图,可能是相机的位置比较远,被裁剪了,可以调整远裁剪平面的位置,如下。

7)添加动态相机
屏蔽场景中默认的相机,在 Cesium 窗口添加 Dynamic Camera,如下。此时,在 Hierarchy 窗口可以看到 CesiumGeoreference 对象下面自动生成了一个名为 DynamicCamera 的对象,该对象上挂了 Camera 组件。

运行后,可以通过鼠标和方向按键控制相机位置和姿态,如下。

说明:视觉的变化通过调整 CesiumGeoreference 组件下的 Latitude 和 Longitude 属性实现,如下。

补充:读者也可以下载 Cesium 官方 Deom 体验一下,详见→cesium-unity-samples。
3 地图切片
本节主要介绍 fbx 文件切片流程,对于其他文件的切片,可以参考 CesiumLab地理信息基础数据处理平台使用手册。
3.1 切片
下载并安装 CesiumLab 后,打开 CesiumLab 客户端,fbx 文件的切片如下。

在处理日志中可以查看任务是否处理成功,如下。如果切片失败,可能是 fbx 文件中包含相机或灯光,使用 Blender 删除相机和灯光,再重新导出 fbx 文件。

生成的文件如下,加载切片时,需要用到 tileset.json 文件。

3.2 预览切片
在分发服务中可以查看切片,步骤如下。

点击预览后,会跳转到另一个网页,显示切片如下。

用户在浏览器中输入:http://localhost:9003/viewer/index.html,再按以下步骤添加切片,也可以预览切片。

3.3 上传切片到 Cesium ion
在 Cesium ion 官网登录账号后,按以下步骤上传切片。

选择文件后,上传切片。

在 My Assets 窗口可以查看已经上传的切片,如下。

注意:第一列的 ID 在加载资源时会用到;用户也可以将 Asset Depot 中的资源添加到 My Assets 中。
4 Unity 中加载切片
4.1 加载 Cesium ion 中切片
在 Cesium 窗口单击 Add 按钮,在底部 Console 右边会出现 Cesium ion Assets 窗口,选择地图添加到场景中,如下。

在 Hierachy 窗口双击 CesiumGeoreference 下面的地图对象,使相机聚焦到地图,地图显示如下,通过修改 ion Asset ID 可以加载不同地图。

4.2 加载 CesiumLab 服务中切片
在 Cesium 窗口点击 Blank 3D Tiles Tileset,在 Hierarchy 窗口会生成 CesiumGeoreference 和 Cesium3DTileset 对象,选中 Cesium3DTileset 对象,设置切片的 url,如下。

url 来自 CesiumLab,如下。

在 Hierachy 窗口双击 Cesium3DTileset 对象,使相机聚焦到地图,地图显示如下。

可以看到,地图方位异常,在 4.4 节将介绍调整地图方位的方法。
4.3 加载本地切片
将切片拷贝到项目目录下的 Resources / city 目录下。在 Cesium 窗口点击 Blank 3D Tiles Tileset,在 Hierarchy 窗口会生成 CesiumGeoreference 和 Cesium3DTileset 对象,选中 Cesium3DTileset 对象,设置切片的 url,如下。

在 Hierachy 窗口双击 Cesium3DTileset 对象,使相机聚焦到地图,地图显示同 4.2 节。
4.4 调整地图方位
1)通过 CesiumLab 预览参数调整地图
使用 3.2 节中方法预览切片,调整好方位后,将鼠标放在屏幕正中间,记录底部的经度、纬度、高度,如下。

选中 CesiumGeoreference 对象,设置经度、纬度、高度为上面记录的值,如下。

在 Hierachy 窗口双击 CesiumGeoreference 对象,使相机聚焦到地图,地图显示如下。

可以看到,地图的方位已正确显示,用户如果对该方位还是不满意,在调整好视觉后,点击 Place Origin Here 按钮重置该视觉下的经度、纬度、高度,如下。

2)通过 tileset 文件中 transform 参数调整地图
在 CesiumLab地理信息基础数据处理平台使用手册 的 2.2.2.1 节 “输出数据的空间参考” 中,我们可以看到以下公式:

其中,3dtiles 里的 transform 矩阵是指切片文件中的 tileset.json 文件,如下。

可以看到 transform 矩阵是一个 4x4 的矩阵,并且最后一列的列向量是 [0, 0, 0, 1]',类似于平移矩阵的形式(平移矩阵详见空间和变换中 2.1.1 节,这篇文章的变换是列向量右乘,Cesium 中是行向量左乘),因此 transform 矩阵的最后一行是平移偏移量,我们将该偏移量设置到 Cesium Georeference 中,如下,地图显示效果同 4.4 1)节。

5 添加对象
5.1 CesiumGlobalAnchor
给场景中添加 DynamicCamera,并屏蔽掉 Main Camera,添加热气球对象,如下。

运行后,发现气球跟随相机一起运动,如下。

将气球对象移到 CesiumGeoreference 下面,并添加 CesiumGlobalAnchor 组件,如下。

运行效果如下,可以看到气球对象没有跟随相机一起运动了。

5.2 参考子场景
选中 CesiumGeoreference 对象,点击 Create Sub-Scene Here 添加子场景,CesiumGeoreference 对象下面会生成一个挂有 CesiumSubScene 组件的对象,重命名为 Sub-Scene。

调整 CesiumSubScene 组件中的 Activation Radius、Latitude、Longitude、Height 属性,如下。Latitude、Longitude、Height 确定了子场景的中心,Activation Radius 为子场景的半径,只有相机在子场景范围内,才激活子场景内的物体(子对象)。

将气球对象拖拽到 Sub-Scene 对象下面,如下(气球对象不需要挂 CesiumGlobalAnchor 组件)。

运行效果如下,可以看到,只有相机进入子场景范围内,才激活子场景内的物体(子对象)。

6 Native 编译
本节主要参考 Building Cesium for Unity。
1)编译环境准备
dotnet --version # 6.0 or later
cmake --version # 3.15 or later
Visual Studio 2022
Git Bash # 拉代码和编译命令都可以在 Git Bash里执行
2)拉 cesium-unity-samples 代码
cesium-unity-samples 源码。
git clone --recurse-submodules git@github.com:CesiumGS/cesium-unity-samples.git
3)拉 cesium-unity 代码
cesium-unity 源码。
cd cesium-unity-samples/Packages
git clone --recurse-submodules git@github.com:CesiumGS/cesium-unity.git com.cesium.unity
clone 时如果忘记添加 --recurse-submodules,可以通过以下命令递归拉取子模块依赖。
cd cesium-unity-samples/Packages/com.cesium.unity
git submodule update --init --recursive
注意:不要通过浏览器下载 cesium-unity 源码的 zip 文件,因为这样不会拉子模块代码,也不要试 图把所有子模块的 zip 文件下载下来后再合并,因为子模块太多了,有的子模块里面又包含子模块,很容易漏掉。cesium-unity 源码比较大,大概 1.89 GB(包含所有子模块),如果下载比较慢,可以使用 Git常用命令总结 中方法配置代理来加速下载。
以下是子模块的依赖文件。
com.cesium.unity\.gitmodules
com.cesium.unity\native~\extern\cesium-native\.gitmodules
com.cesium.unity\native~\extern\cesium-native\extern\draco\.gitmodules
com.cesium.unity\native~\extern\cesium-native\extern\earcut\.gitmodules
com.cesium.unity\native~\extern\cesium-native\extern\rapidjson\.gitmodules
com.cesium.unity.gitmodules 内容如下,可以看到 cesium-native 是 cesium-unity 的一个子模块,这正是我们要编译的 native 子模块。
[submodule "native~/extern/cesium-native"]
path = native~/extern/cesium-native
url = ../cesium-native.git
[submodule "native~/extern/tidy-html5"]
path = native~/extern/tidy-html5
url = https://github.com/htacg/tidy-html5.git
[submodule "native~/extern/enum-flags"]
path = native~/extern/enum-flags
url = https://github.com/grisumbras/enum-flags.git
4)构建 Reinterop
Reinterop 是一个 Roslyn(C# 编译器)源代码生成器,在编译 cesium-unity C# 代码时由 Unity 自动调用,并生成 C# 与 C++的交互层。
cd cesium-unity-samples/Packages/com.cesium.unity
dotnet publish Reinterop~ -o .
5)打开 cesium-unity-samples 项目
使用 Unity Editor 打卡 cesium-unity-samples 项目,Unity 将自动编译 cesium-unity C# 源代码,同时调用 Reinterop 生成 C# 和 C++ 源代码。此时 Cesium 的功能还不能正常使用,会抛出以下异常。这是因为 C++ 的代码还没编译。
DllNotFoundException: CesiumForUnityNative assembly:<unknown assembly> type:<unknown type> member:(null)
NotImplementedException: The native implementation is missing so OnValidate cannot be invoked.
生成的 C++ 源码地址为:com.cesium.unity/native~/build,用户可以通过 Visual Studio 打开 CesiumForUnityNative.sln 文件来查看源码。
6)编译 C++ 代码
关闭 cesium-unity-samples 项目,执行完以下命令行再打开项目。
构建 Debug 版本。
# compile the C++ code for use in the Editor
cd cesium-unity-samples/Packages/com.cesium.unity/native~
# 在 build 目录中生成 CMake 构建配置, 并将构建类型设置为 Debug, 以便在构建项目时启用调试信息(只需执行一次, 第二次编译时不需要执行该命令)
cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug
# 在 build 目录中执行构建操作, 使用 14 个构建线程并生成 Debug 版本的可执行文件或库, 将构建结果安装到 install 指向的目录中
cmake --build build -j14 --target install --config Debug
构建 Release 版本。
# build a release build
cd cesium-unity-samples/Packages/com.cesium.unity/native~
# 在 build 目录中生成 CMake 构建配置, 并将构建类型设置为 RelWithDebInfo, 它允许在 Release 版本中包含调试信息(只需执行一次, 第二次编译时不需要执行该命令)
cmake -B build -S . -DCMAKE_BUILD_TYPE=RelWithDebInfo
# 在 build 目录中执行构建操作, 使用 14 个构建线程并生成带有调试信息的 Release 版本的可执行文件或库, 将构建结果安装到 install 指向的目录中
cmake --build build -j14 --target install --config RelWithDebInfo
若在后面的编译过程中,报错:could not find any instance of Visual Studio,可以参考博客→解决CMake时“could not find any instance of Visual Studio”的问题。
7)查看安装目录
打开 com.cesium.unity/native~/CMakeLists.txt 文件,搜索 "CMAKE_INSTALL_PREFIX",如下。
# When building for the Editor, both Runtime and Editor assemblies are
# written to the Editor directory so that Unity won't load them in
# a standalone build.
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/../Editor" CACHE PATH "Installed to the Editor directory." FORCE)
endif()
可以看到,安装目录为 "${CMAKE_CURRENT_LIST_DIR}/../Editor",即 com.cesium.unity/Editor 目录,由此得构建和安装的目录如下。
com.cesium.unity\native~\build\Editor\Debug\CesiumForUnityNative-Editor.dll ->
com.cesium.unity\Editor\CesiumForUnityNative-Editor.dll
com.cesium.unity\native~\build\Runtime\Debug\CesiumForUnityNative-Runtime.dll ->
com.cesium.unity\Editor\CesiumForUnityNative-Runtime.dll
7 修改 Native 代码案例
1)打开 native 源码工程
使用 Visual Studio 打开 CesiumForUnityNative.sln 文件来查看源码,如下。

2)修改源码
修改 CesiumForUnityNative-Runtime 模块下的 CesiumCreditSystemImpl.cpp 文件(源码位置:com.cesium.unity/native~/Runtime/src/CesiumCreditSystemImpl.cpp),如下。

3)编译源码
# compile the C++ code for use in the Editor
cd cesium-unity-samples/Packages/com.cesium.unity/native~
# 在 build 目录中生成 CMake 构建配置, 并将构建类型设置为 Debug, 以便在构建项目时启用调试信息(只需执行一次, 第二次编译时不需要执行该命令)
cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug
# 在 build 目录中执行构建操作, 使用 14 个构建线程并生成 Debug 版本的可执行文件或库, 将构建结果安装到 install 指向的目录中
cmake --build build -j14 --target install --config Debug
编译完成后,可以看到 com.cesium.unity/Editor/CesiumForUnityNative-Runtime.dll 文件修改日期发生变化。
4)修改前后对比
修改前底部有一行文字。

修改后底部文字消失。

声明:本文转自【Unity3D】Cesium加载大地图。
【Unity3D】Cesium加载大地图的更多相关文章
- Cesium加载三维倾斜摄影数据
具体技术来源自论文 基于Cesium的倾斜摄影三维模型Web加载与应用研究. 技术架构图 应用实例 利用一个实际实例来详细说明如何利用Cesium加载倾斜摄影数据,并进行可视化和交互操作. 首先,利用 ...
- Cesium加载三维路线
1. 概述 将路线加载到三维地图中,能直观显示道路的坡度变化,协同DEM和遥感影像,能极大丰富道路的可视化效果 本文此处基于Cesium,加载地形数据,叠加遥感影像,再叠加路网数据,形成三维地图,效果 ...
- Unity3d 动态加载场景物件与缓存池的使用
聊聊Unity3d动态加载场景物件那些事儿. 众所周知,在策划或美术设计完游戏场景地图后,一个场景中可能会存在成千上万个小的物件,比如石头,木箱子,油桶,栅栏等等等等,这些物件并不是游戏中的道具,仅仅 ...
- ArcGIS API for JavaScript 4.4 版本加载谷歌地图
ArcGIS API for JavaScript 4.X 版本升级后,API发生了很大的变化. 其中就支持了WebEarth展示,主要是通过 esri/views/SceneView 实现的. 在新 ...
- unity3d动态加载资源
在Unity3D的网络游戏中实现资源动态加载 分类: 最新学习2012-06-14 13:35 1127人阅读 评论(0) 收藏 举报 网络游戏nullvectorjson游戏string 用Unit ...
- (转) Arcgis for js加载百度地图
http://blog.csdn.net/gisshixisheng/article/details/44853709 概述: 在前面的文章里提到了Arcgis for js加载天地图,在本节,继续讲 ...
- ArcMap和ArcGIS Pro加载百度地图
前面发布了两篇我用ArcBruTile开发用于ArcMap加载百度地图的插件ArcBruTileBaidu,放在网上后评论和反响还不错,还有两位大学同学通过百度搜索居然搜到我本人!文章和技术介绍也被网 ...
- 遥感影像和DEM数据获取处理、GeoServer切片发布并使用Cesium加载
1. 数据获取 笔者这里使用的是哨兵一号(Sentinel-1).ALOS的遥感影像和ALOS的DEM数据 下载地址为:ASF Data Search (alaska.edu) ASF(Alaska ...
- Cesium加载ArcGIS Server4490且orgin -400 400的切片服务
Cesium在使用加载Cesium.ArcGisMapServerImageryProvider加载切片服务时,默认只支持wgs84的4326坐标系,不支持CGCS2000的4490坐标系. 如果是A ...
- WPF DataGrid 性能加载大数据
WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系 ...
随机推荐
- 自然语言处理 Paddle NLP - 结构化数据问答-理论
NLP问答任务 相似度和规则匹配,都是早期的方法,现在主流的方法,都是基于生成的方法 结构化数据问答,有两种形式,一种是知识图谱形式.一种是关系型数据库形式. 主要应用在企业中,减少销售的成本 应用于 ...
- TornadoFx 页面之间的数据传递
原文地址: TornadoFx 页面之间的数据传递 - Stars-One的杂货小窝 和Android开发一样,经常遇到两个页面之间需要进行数据的交互传输,本文讲解下TornadoFx框架中,页面之间 ...
- 关于DVWA靶场高难度命令执行的代码审计
需要的环境:dvwa 使用的工具:PHP手册 high难度源代码: <?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target ...
- Redis的设计与实现(1)-SDS简单动态字符串
现在在高铁上, 赶着春节回家过年, 无座站票, 电脑只能放行李架上, 面对着行李架撸键盘--看过<Redis的设计与实现>这本书, 突然想起, 便整理下SDS的内容, 相对后面的章节, 算 ...
- C语言变量常量
目录 前言 一.数据类型 1.整形 2.浮点型 3.字符型 二.变量的操作 1.变量的创建 2.变量的使用 2.1 变量的赋值 2.2 变量的加减 2.3 变量的隐式类型转换 2.4 强制类型转换 3 ...
- ABP 的ajax请求错误:400 Empty or invalid anti forgery header token.
ABP 的ajax请求错误 记录于2018-03-22 13:31:16 星期四 错误信息:400 Empty or invalid anti forgery header token. 我从网上找到 ...
- 行行AI人才直播第13期:刘红林律师《AIGC创业者4大法律问题需注意》
行行AI人才(海南行行智能科技有限公司)是博客园和顺顺智慧共同运营的AI行业人才全生命周期服务平台. AIGC爆火至今,商业落地已成为各行各业焦点的问题.它的广泛应用也带来了一系列的法律风险和挑战.一 ...
- RedHat8静默安装was
前言 was(websphere application server),类似weblogic.tomcat,由IBM开发的一种企业级Java容器. 系统版本:redhat 8.2 was版本:was ...
- redis集群:MASTER aborted replication with an error: NOAUTH Authentication required.
发现个问题:redis集群所在服务器,磁盘空间很快就被占满,使用 "du -sh *"查看每个文件夹的大小,发现redis集群三个从节点的日志文件占用空间很大. 下面记录问题排查及 ...
- .Net AsyncLocal介绍
AsyncLocal的基本概念 AsyncLocal是一个在异步环境中存储和传递状态的类型.它允许你在线程或任务之间共享数据,而不会受到异步上下文切换的影响. 每一个异步的AsyncLocal的数据都 ...