Cesium 源码分析 Cesium3DTilesetCache

        Cesium中的3DTiles数据加载的过程中会进行缓存,使用的是Cesium3DTilesetCache这个类,这个类中维护了一个双向链表DoublyLinkedList,链表的每个节点DoublyLinkedListNode包含了3部分内容,item(即tile)、previous、next,而DoublyLinkedList维护了链表的head和tail游标,并包含三个方法remove(移除节点)、add(添加节点)、slice(移动节点)。

        

        对于Cesium3DTilesetCache,这个类中使用了一个空节点sentinel(哨兵),这个节点的在链表中起到隔离作用,每一帧中这个哨兵节点都可能会移动,哨兵的左边是当前帧之前缓存的瓦片(数据已经下载完成)节点,右边是当前帧需要的瓦片节点,其中左边的节点受到瓦片集的最大内存选项maximumMemoryUsage和是否剔除的标记trimTiles以及sentinel的三方挟持,只要有一方不满足条件就会删除已经缓存的节点,在当前帧中会检索是否之前缓存的节点在当前帧中可以重复利用,如果是则会将该节点从哨兵的左边移动到哨兵的右边,当前帧处理完成后,哨兵节点会reset到链表的尾部,并进行新一轮的哨兵移动。

 

/**
 * Stores tiles with content loaded.
 * 用来存储已经加载完成的带有数据的瓦片
 *
 * @private
 */
function Cesium3DTilesetCache() {
  // [head, sentinel) -> tiles that weren't selected this frame and may be removed from the cache
  // (sentinel, tail] -> tiles that were selected this frame
  // 双向链表
  this._list = new DoublyLinkedList();
  // 哨兵(空节点)
  this._sentinel = this._list.add();
  this._trimTiles = false;
}

// 重置时把哨兵节点移动到末尾
Cesium3DTilesetCache.prototype.reset = function () {
  // Move sentinel node to the tail so, at the start of the frame, all tiles
  // may be potentially replaced.  Tiles are moved to the right of the sentinel
  // when they are selected so they will not be replaced.
  // 把哨兵节点移动到链表的末尾,在一帧的开始,所有的瓦片可能被替换,可见的瓦片将被移动到链表的右边,它们不能被替换
  this._list.splice(this._list.tail, this._sentinel);
};

// 节点移动到哨兵的后边(从原来缓存的数据中拿到可以使用的节点然后移动到哨兵的右边)
Cesium3DTilesetCache.prototype.touch = function (tile) {
  var node = tile.cacheNode;
  if (defined(node)) {
    // 节点移动到哨兵节点的后面
    this._list.splice(this._sentinel, node);
  }
};

// 在末尾添加节点,这个节点一定在哨兵的后面
Cesium3DTilesetCache.prototype.add = function (tile) {
  // 如果瓦片的缓存结点不存在就创建
  if (!defined(tile.cacheNode)) {
    tile.cacheNode = this._list.add(tile);
  }
};

// 卸载瓦片的缓存节点
Cesium3DTilesetCache.prototype.unloadTile = function (
  tileset,
  tile,
  unloadCallback
) {
  var node = tile.cacheNode;
  // 未定义就返回
  if (!defined(node)) {
    return;
  }

  // 链表中移除节点
  this._list.remove(node);
  // 清空
  tile.cacheNode = undefined;
  // 回调
  unloadCallback(tileset, tile);
};

// 卸载瓦片集
Cesium3DTilesetCache.prototype.unloadTiles = function (
  tileset,
  unloadCallback
) {
  var trimTiles = this._trimTiles;
  this._trimTiles = false;

  // 链表
  var list = this._list;

  // 最大缓存(MB转换为字节)
  var maximumMemoryUsageInBytes = tileset.maximumMemoryUsage * 1024 * 1024;

  // Traverse the list only to the sentinel since tiles/nodes to the
  // right of the sentinel were used this frame.
  // 遍历列表列表,只遍历哨兵左边的节点,因为哨兵右边的节点是正在使用的
  //
  // The sub-list to the left of the sentinel is ordered from LRU to MRU.

  // 哨兵
  var sentinel = this._sentinel;
  // 头节点
  var node = list.head;

  while (
    node !== sentinel &&                                                        // 不是哨兵节点
    (tileset.totalMemoryUsageInBytes > maximumMemoryUsageInBytes || trimTiles)  // 缓存没有超过界限就不删除 
  ) {
    // 获取节点的数据
    var tile = node.item;
    // 遍历下一个节点
    node = node.next;
    // 卸载节点
    this.unloadTile(tileset, tile, unloadCallback);
  }
};

// 减少瓦片的缓存(cpu中)
Cesium3DTilesetCache.prototype.trim = function () {
  this._trimTiles = true;
};
export default Cesium3DTilesetCache;

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cesium 是一个基于 WebGL 的开源地球渲染引擎,主要用于在浏览器中呈现三维地理数据。它使用了一些复杂的渲染技术和算法来实现高性能和高质量的地球渲染效果。下面是对 Cesium 渲染源码的简要分析: 1. Shader:Cesium 使用了大量的着色器程序来实现不同的渲染效果,如光照、纹理映射、阴影等。着色器程序是在 GPU 上执行的,并且可以通过 GLSL(OpenGL Shading Language)语言进行编写。Cesium 的着色器程序通常是在运行时动态生成的,以适应不同的地图数据和渲染需求。 2. 地形渲染:Cesium 支持高度精细的地形渲染,它使用了基于切片的地形渲染技术。在渲染过程中,Cesium 会将地球表面分割成小块切片,并根据每个切片的高度数据和纹理信息生成相应的网格和纹理。这些切片可以根据需要进行加载和卸载,以实现地图数据的动态加载和显示。 3. 纹理映射:Cesium 使用了纹理映射技术来实现地球表面的贴图效果。它可以将不同类型的纹理(如卫星图像、地形纹理、气候数据等)映射到地球表面的不同部分,以实现真实的地貌效果。Cesium 通过加载和解析各种类型的地图数据,将其转换为纹理信息,并将其应用到地球表面的相应区域。 4. 光照和阴影:Cesium 支持实时的光照和阴影效果,以增强地球渲染的真实感。它使用了基于物理的光照模型,考虑了光源的位置、光照强度、表面材质等因素,并通过计算每个顶点和像素的光照值来实现逼真的光照效果。此外,Cesium 还支持动态阴影的生成,可以根据光源的位置和地形的形状计算出地球表面上的阴影效果。 5. 动态渲染:Cesium 支持动态渲染技术,可以在实时交互的情况下实现高性能的地球渲染效果。它使用了一些优化技术,如级联阴影映射、视锥剔除、LOD(Level of Detail)等,以减少渲染负载并提高渲染效率。此外,Cesium 还支持动态加载和卸载地图数据,以实现在不同的视角和缩放级别下的快速渲染和响应。 需要注意的是,Cesium源码非常庞大和复杂,涉及到多个模块和子系统。以上只是对其渲染部分的简要分析,实际的源码分析需要深入研究 Cesium 的代码库和文档,并对 WebGL 和图形渲染技术有一定的了解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值