深色模式
一帧中的更新与渲染
地球看起来静止,程序仍可能每秒更新许多次。浏览器的动画回调、Cesium 的状态更新、模拟时钟(simulation clock)和 GPU 绘制是相关但不同的过程。一帧(frame)是一幅画面的生成单位,帧率(frame rate)以每秒帧数 FPS 表示;时间步长(time step)则是相邻两次模拟状态之间推进的时间。学会分开它们,才能解释为什么页面空闲时仍占用资源,以及为什么“每秒调用六十次函数”不等于用户看到六十个完整画面。
更新决定状态,渲染产生画面
默认 Viewer 会管理渲染循环,并通过 Clock 推进模拟时间。Scene 的更新事件与绘制事件可以分别监听。preUpdate、postUpdate 围绕场景更新;preRender、postRender 围绕实际渲染。图中是教学简化,真实引擎还包含请求调度、命令分类和多个渲染通道。
以下是接在第二课初始化之后的功能片段,沿用已经导入的 Cesium 命名空间和已创建的 viewer,省略容器与初始化代码。
js
viewer.scene.requestRenderMode = true;
viewer.scene.maximumRenderTimeChange = Infinity;
// 应用自己的状态改变后,明确请求新画面。
viewer.scene.globe.baseColor = Cesium.Color.DARKSLATEBLUE;
viewer.scene.requestRender();按需渲染(explicit rendering)适合静态地图。相机、资源加载等变化会触发必要绘制;应用自己修改某些渲染状态时,需要主动请求。上面的 Infinity 表示不因模拟时间变化本身而要求新帧,它不等于暂停 Clock,也不等于暂停所有 JavaScript。
连续风粒子、时间变化光照和持续变化的 shader uniform 往往仍需要连续请求画面。是否节能取决于场景真正静止的时间,不能只看选项已经打开。
一次停顿可能跨越多个阶段
把等值线提取放进 Worker,只把算法计算移出了主线程。结果返回后,顶点转换、几何合并、GPU 资源创建仍可能产生工作。需要分别记录每一段耗时。对于 Cesium Primitive,asynchronous 控制其几何准备路径;它不能自动把任意用户代码搬入 Worker。
也不要在 preRender 里不断新建材质和大数组:即便单次很快,垃圾回收与资源上传仍会积累成停顿。优先复用对象,并让更新量与真实变化一致。
一帧的节奏
观察持续渲染与按需渲染,理解更新和绘制的关系。
在浏览器本地运行 · 无需账号 · 鼠标拖动旋转,滚轮缩放
底图:Natural Earth II(公共领域);其余几何和地形为教学合成。 数据说明
查看运行源码
此代码直接读取实际运行的实验模块。按 kind 分支定位当前实验,也可查看数据公式和 GLSL。
读取源码…观察任务: 关闭“旋转对象”,先保持按需模式,再打开“连续渲染模式”,比较“已完成绘制”计数。接着恢复旋转,观察两种模式的差异。这个计数是否等于显示器实际呈现的帧数?
展开解释
静止且按需时绘制应明显减少,连续模式会继续绘制相同画面;恢复旋转后,需要持续产生新画面。计数来自 Scene 的渲染事件,并不是显示器呈现测量。应结合浏览器性能记录与 GPU 负载看问题;渲染回调完成不保证该帧已经被显示器呈现。