下面我对 CesiumJS(常简称 “Cesium”)这个项目的 整体架构 + 源码解读路径 做一个尽量详细的说明。如果你希望聚焦某个模块(如渲染 Renderer、地形 Terrain、3D Tiles 等)也可以,我之后可以帮助你深入。
(注:以下内容基于 Cesium 的开源仓库 + 官方文档,截至撰写时最新情况。未来版本可能有变动。)
—
一、项目简介
- CesiumJS 是一个用于 Web 浏览器里展示 3D 地球、2D/2.5D 地图,并支持大数据量、时间动态可视化的 JavaScript 库。(Cesium)
- 它使用 WebGL 实现硬件加速渲染。(GitHub)
- 开源采用 Apache 2.0 许可证。(Cesium)
- 从源码上看,其 GitHub 仓库为 CesiumJS 项目,包含大量模块、依赖、工具、示例。(GitHub)
二、整体架构概览
根据官方 Wiki “Architecture” 页面,Cesium 的源码从较低层(数学、基础)到较高层(应用可视化)可以粗略分为四层:(GitHub)
2.1 核心(Core)层
-
这个层负责基本的数学、几何运算、坐标转换、地图投影、时间日期(如 JulianDate)、三维向量、矩阵、四元数、样条插值、椭球体(WGS84)变换等。(GitHub)
-
举例:从经纬度转换为笛卡尔坐标:
var ellipsoid = Ellipsoid.WGS84; var p = ellipsoid.cartographicToCartesian(new Cartographic(0.0, 0.0)); -
再如:计算一个椭球上定义的椭圆边界点。(GitHub)
-
文件结构上,在源码目录中 “Source/Core” 或类似目录可以找到这些低层模块。
2.2 渲染层(Renderer)
- 这一层是对 WebGL 的抽象封装。也就是说,上层不直接操作 WebGL 而是通过 Renderer 层的接口。官方说法:“Renderer – a thin abstraction over WebGL.” (GitHub)
- 这个层处理 GPU 资源(顶点缓冲、索引缓冲、纹理、帧缓冲)、渲染状态管理(启用/禁用深度测试、剔除、混合模式等)、着色器(vertex/fragment)管理、draw calls 等。
- 在源码中应当有类似 “Source/Renderer” 或 “Source/Graphics” 的目录。
2.3 场景层(Scene)
-
在 Core + Renderer 基础上,Scene 层提供“地图/地球”相关高层功能。包括:
- 地球体 (globe)、地图视图模式(3D、2D、Columbus View)
- 图像图层(Imagery layers)– 从 Bing Maps、Esri、OpenStreetMap、WMS 等服务器获取影像瓦片。(GitHub)
- 多种几何体(polylines、polygons、billboards、labels、ellipsoids、sensors)
- 材质(Materials)描述外观
- 相机(Camera)控制视角、切换视图模式、响应用户输入等。
-
Scene 层管理“可视化对象”及其生命周期。官方示例提到
scene.initializeFrame()、scene.render()等流程。(GitHub) -
源码中此层可能在 “Source/Scene” 目录。
2.4 动态场景层(Dynamic Scene)
- 这一层进一步提升,用于 时间动态可视化(如卫星轨道、实时飞行器、传感器数据流)——通过 CZML(Cesium 标记语言)等格式。(GitHub)
- 也就是说,如果你的场景中有“时间轴”、“可变数据”、“实时变化”的需求,通常用此层封装了对动态实体(Entities layer)、时间线控制、动画、数据源更新的支持。
- 源码可能在 “Source/DynamicScene” 或 “Source/DataSources” 等目录。
2.5 层间关系
- 各层之间是“逐步往上依赖”的:Core ← Renderer ← Scene ← DynamicScene。(GitHub)
- 使用者开发应用(比如基于 Viewer)时多用 Scene 或 DynamicScene 层;底层 Core/Renderer 通常被隐藏。
- 这种分层架构清晰,有助于维护、扩展、也便于用户只用其中部分功能。
三、源码解读路径建议
下面是我推荐的一个“解读源码”的路线,比较适合工程实践与学习。
3.1 准备工作
- 在本地 clone 仓库:
git clone https://github.com/CesiumGS/cesium.git。 - 阅读 README、CONTRIBUTING 指南、目录结构,建立整体感。(GitHub)
- 构建一个最简单的 Cesium 示例(使用 Quickstart 指南)以熟悉库的使用。(Cesium)
3.2 从入口看起
- 在源码中定位 “Viewer” 或 “Scene” 的入口类/函数,比如在
Viewer.js或Cesium.js中。了解当你创建new Viewer(container, options)时内部做了什么。 - 探查 Viewer 背后如何初始化 Scene、Camera、Canvas、事件处理、渲染循环(requestAnimationFrame)等。
3.3 深入 Scene 层
-
看
Scene.render()方法,了解每帧的执行流程:初始化帧 → 更新资源 → 执行 draw calls。官方给出了如下示意:(function tick() {
scene.initializeFrame();
// 用户动画代码
scene.render();
requestAnimationFrame(tick);
}()); (GitHub) -
跟踪其中
initializeFrame(),update(),render()方法,看看它们分别做什么:例如状态清理、摄像机准备、图层排序、剔除、缓冲更新、绘制。 -
看图层/几何体(Primitives / Entities)如何被添加、注册、渲染。比如
Primitive,BillboardCollection,LabelCollection等。
3.4 渲染层细节
-
在 Renderer 层,查看 WebGL 抽象封装。重点看以下内容:
- 管理顶点/索引缓冲区(VertexBuffer/IndexBuffer)
- 着色器管理(ShaderProgram 或类似)
- 渲染状态封装(EnableDepthTest, BlendMode, CullFace)
- FrameBuffer/RenderTarget 支持
-
理解 Cesium 如何管理多个材质、多重渲染通道(如地表、建筑、透明体)以及性能优化(比如顶点缓存优化、纹理压缩、批处理)。
3.5 核心数学模块
- 回到 Core 层,学习
Matrix4,Cartesian3,Ellipsoid,Cartographic等类。了解坐标系转换(经纬度→笛卡尔、笛卡尔→屏幕坐标)、投影、椭球模型(WGS84)。 - 理解地形与瓦片化数据的几何处理:例如 Quantized mesh (地形)、3D Tiles (建筑/点云) 等,是如何在数学层面被支撑的。虽可能不直接在 Core 中,但 Core 数学模块是基础。
3.6 数据动态支持 & 3D Tiles 等扩展
- 看 DynamicScene 层:如何支持 Entities (时间变化的对象)、数据源 (DataSource) (如 CzmlDataSource)、时间轴 (Clock) 管理。
- 学习 3D Tiles (例如 tileset) 如何被加载、遍历、剔除、绘制。虽然 3D Tiles 的细节可能在另一个模块或扩展,但 Cesium 支持 3D Tiles 的能力是其重要特征。官方功能中就提到:“Stream in 3D Tiles and other standard formats”. (Cesium)
3.7 性能/优化/架构设计
-
在源码中查找性能优化策略,如:
- 批处理(Batching)对象绘制
- 裁剪剔除(Frustum Culling)
- LOD (Level Of Detail)支持(地形、建筑)
- 纹理/几何压缩或量化(如 Quantized mesh)
- 异步加载(瓦片、纹理、模型)
-
查看模块间解耦情况:例如 Renderer 与 Scene 解耦,数学库与数据输出解耦。
3.8 实例分析
- 从仓库中的示例或 Demo 入手:定位一个应用(如“可视化航班轨迹”示例),看看它使用哪些 Cesium API,是如何构建 Viewer、加载数据、绑定事件。
- 在源码中追踪该示例调用到各层模块的路径。
3.9 定制/扩展/插拔点
- 查找 Cesium 提供的扩展点/API 入口:例如 Widgets (UI 工具)、 Custom Geometry、 Appearance (材质)、 DataSource 插件等。
- 分析如何将 Cesium 与 React/Vue 等现代前端框架集成(文档中提到有这方面支持)(Cesium)
- 看如何加载自定义地形/影像/模型数据。
四、源码目录举例(基于当前仓库)
下面是根据 GitHub 仓库的大致目录(= 参考)帮助你理解文件结构:(GitHub)
/Source
/Core
/Renderer
/Scene
/Widgets
/ThirdParty
/Specs
/Tools
/Apps
/Build
/Documentation
/Apps
README.md
CHANGES.md
LICENSE.md
/Source/Core:基础数学与工具类。/Source/Renderer:WebGL 抽象、渲染状态、Shader 管理。/Source/Scene:地理场景、摄像机、图层、地表/地图模型。/Source/Widgets:视图控件(UI 部分,如图例、缩放、导航控件)。/Source/ThirdParty:第三方库。/Source/Specs:测试规范。/Source/Tools:构建/打包/开发辅助脚本。/Build:编译后的产物。/Apps:演示应用。
五、关键模块源码解读举例
这里选几个关键模块,略微深入源码内部做说明。
5.1 Cartesian3 & Matrix4 (在 Core)
Cartesian3表示三维笛卡尔坐标 (x, y, z)。Matrix4用于四维矩阵(包括平移、旋转、缩放、投影变换)。- 示例:通过
Ellipsoid.cartographicToCartesian(cartographic)将经纬度坐标转换为 Cartesian3。 (GitHub) - 在源码中可能采用静态方法,如
Cartesian3.fromDegrees(longitude, latitude, height)。 - 理解这些基础类后,你就能理解 地球模型、相机视图、几何体定位 等是如何建立的。
5.2 Scene.render() 流程
如上所述,渲染流程一般分为:初始化帧 → 更新 → 渲染。(GitHub)
- 初始化帧(Scene.initializeFrame)可能包括:清理旧绘制状态、更新时间轴、准备摄像机、剔除等。
- 更新(Primitives/Entities 更新其状态)包括:同步顶点/索引缓冲、更新动画、更新材质、更新数据源。
- 渲染(Renderer 执行 draw calls)包括:遍历可见对象、设置渲染状态、提交顶点/索引、执行 gl.drawElements/drawArrays。
- 你可以在源码中搜索
render()方法、initializeFrame()方法、update()方法,结合调用栈分析。
5.3 Tileset 加载与 LOD 策略
-
虽然具体代码比较复杂,但核心思路包括:
- 加载 3D Tiles 元数据(tileset.json 或类似)
- 对于每帧,根据相机位置决定哪些瓦片需加载/卸载/显示(筛选/剔除)
- 对模型/点云进行 LOD 切换:离相机远时用低精度瓦片,近时高精度。
- 纹理/几何体异步加载,避免阻塞主线程。
-
在源码中你可以查找
Cesium3DTileset类、loadTileset、updateTileset等关键函数。
六、在中国环境/中文用户注意事项
- 虽然 Cesium 是全英文文档,但其 API、源码类名基本都是英文。建议至少具备阅读英文技术文档的能力。
- 如果使用中国地图影像或地形服务,需要注意服务的跨域、瓦片坐标系、影像版权、切片方案是否兼容 Cesium。
- 示例 Quickstart 中提到:如果通过 npm 安装,则要在
window.CESIUM_BASE_URL指定静态资源(如 web workers、ThirdParty、Assets、Widgets 等)的位置。(Cesium)
七、为什么 Cesium 架构好/使用场景
- 模块化明确:四层架构使得开发者可以只依赖所需层。
- 强大的渲染能力:支持 WebGL 硬件加速,大规模地理数据可视化。
- 多数据格式支持:影像、地形、3D 模型、点云、时间动态数据等。
- 开源社区活跃:GitHub 有较多贡献者、较多 Star。(GitHub)
- 支持现代前端集成:文档提到可以与 React/Vue/Angular 等结合。(Cesium)
下面是基于 CesiumJS 源码架构(Core → Renderer → Scene → Dynamic Scene 四层结构)整理的 Mermaid 架构图,你可以直接用于文档或编辑器中(如 VS Code 或 Markdown 插件)查看结构:
改成 分层样式 表示四层:
🔍 图中含义说明
- Core 层:处理向量、矩阵、椭球模型、经纬度→笛卡尔坐标等基础运算。 (GitHub)
- Renderer 层:封装 WebGL,负责顶点/索引缓冲、着色器、渲染状态等。 (GitHub)
- Scene 层:构建地图/地球视图、影像图层、几何体、相机控制。 (GitHub)
- Dynamic Scene 层:支持时间变化的实体、动画、数据源(如 CZML)等。 (GitHub)
如果你愿意,我可以帮你画一个更 详细版的架构图(包含模块/组件如:地形、影像、3D Tiles、实体管理、渲染流程等)并用 Mermaid 格式输出。你看要不要?
1万+

被折叠的 条评论
为什么被折叠?



