Cesium源码分析之渲染3DTile的一点思考

Cesium源码分析之渲染3DTile的一点思考

版本号1.135.0

借助一下AI来试试

首先根据AI的回答

javascript 复制代码
{
  "geometricError": 1024,
  "root": {
    "boundingVolume": {"region": [-1.318, 0.697, -1.319, 0.698, 0, 1000]},
    "geometricError": 512,
    "content": {"uri": "建筑群_L1.b3dm"},
    
    "children": [
      {
        // 引用外部的tileset
        "boundingVolume": {"region": [-1.318, 0.697, -1.3185, 0.6975, 0, 500]},
        "geometricError": 256,
        "content": {"uri": "区域A详细模型/tileset.json"}  // 另一个tileset!
      }
    ]
  }
}

他说3DTile是根据某一个中心偏移计算的

首先看看这个结构,每一个Node包含

boundingVolume, geoError, content, children 4个字段

首先根据这个结构啊,数据可能AI乱写的,

geoError不出意外是用来判定是否当前LOD级别是否足够

content装了3d模型等等资源的url

boundingVolume,但是没有显式指定一个偏移中心,那么可以猜测中心就是包围盒的中心

children按理说就是更细的node,不过AI说还有一个refine 字段,可以设定是replace还是add,听起来有点道理,两种都有更加灵活

大概这样吧,来抓帧看看

看起来确实有这么几个相关字段

position就是localspace的一个值

u_modifiedModelViewProjection就是去掉了u_center3D之后的mvp

u_center3D就是tile的中心 因为有这句 vec3 position3DWC = position + u_center3D;

那么确实如AI所言,3D Tile是有一个center的

但是这样做的话,就产生了一个问题,Cesium每一个模型有各自的uniform避免了这个问题,这个问题是按理说camera matrix是可以共享的,UBO里可以一个mat4解决掉

但是这里用了modified view意味着这件事做不了

假设方案1

复制代码
每一批共享中心的对象用一个cameraIndex,这样多个mat4就行,然后其实就多了一个字段,来标识取mat4[]的哪一个,3dtile一般来说范围很大,所以这个数组应该很小,感觉是可行的
clike 复制代码
UBO {
mat4 viewMatrices[10];
}

in int viewMatrixId;

但是ID要挂到每一个vertex上,感觉有点冗余,即使拼到某个属性后面在数据量大的时候也多了不少数据,来看看方案2

假设方案2

就只用1个mat4是否可行,当然,特定情况可以,就是展示任务只需要某一个区域内,这个区域能切成1个root

总结

感觉可以考虑实际情况来做决策

AI润色后的文章(直出)

渲染3DTile的核心机制分析(Cesium 1.135.0)

3DTiles数据结构解析

javascript 复制代码
{
  "geometricError": 1024,
  "root": {
    "boundingVolume": {"region": [-1.318, 0.697, -1.319, 0.698, 0, 1000]},
    "geometricError": 512,
    "content": {"uri": "建筑群_L1.b3dm"},
    "children": [
      {
        "boundingVolume": {"region": [-1.318, 0.697, -1.3185, 0.6975, 0, 500]},
        "geometricError": 256,
        "content": {"uri": "区域A详细模型/tileset.json"}
      }
    ]
  }
}
  • boundingVolume通过region参数定义空间范围,中心点隐含计算得出
  • geometricError控制LOD切换阈值
  • content包含实际模型资源路径
  • children实现层级嵌套结构,支持外部引用(通过tileset.json)

渲染核心发现

通过帧调试捕获到关键着色器变量:

  • u_center3D表示Tile中心坐标
  • u_modifiedModelViewProjection为去中心化后的MVP矩阵
  • 顶点最终位置通过vec3 position3DWC = position + u_center3D计算

矩阵优化方案对比

方案1:多矩阵索引

cpp 复制代码
UBO {
  mat4 viewMatrices[10];
}
in int viewMatrixId;
  • 优势:支持多区域并行展示
  • 代价:每个顶点需携带matrixID,数据量增加约4-8%

方案2:单矩阵模式

  • 适用场景:单一聚焦区域(如城市级应用)
  • 实现方式:强制所有Tile共享root节点中心
  • 性能收益:完全消除矩阵索引开销

工程实践建议

  • 大范围漫游应用建议采用方案1(如全球尺度)
  • 聚焦式应用优先选择方案2(如建筑展示)
  • 可设计动态切换机制,根据视锥体范围自动选择模式

(注:原文中的CSDN图片链接保留原样,未作修改)

相关推荐
lebornjose14 小时前
javascript - webgl中绑定(bind)缓冲区的逻辑是什么?
前端·webgl
BoBoZz1920 小时前
WarpTo 对 3D 几何体进行形变(Warping操作,使其顶点朝着一个指定的空间点移动
python·vtk·图形渲染·图形处理
feiduoge1 天前
教程 44 - 相机系统
windows·游戏引擎·图形渲染
feiduoge2 天前
教程 43 - 渲染目标和可配置渲染通道
windows·游戏引擎·图形渲染
BoBoZz192 天前
RotationAroundLine 模型的旋转
python·vtk·图形渲染·图形处理
BoBoZz192 天前
PolyDataContourToImageData 3D集合图像转换成等效3D二值图像
python·vtk·图形渲染·图形处理
温宇飞2 天前
WebGL 的渲染管道和编程接口
前端·webgl
二狗哈2 天前
Cesium快速入门30:CMZL动画
javascript·3d·webgl·cesium·地图可视化
郝学胜-神的一滴2 天前
使用EBO绘制图形:解锁高效渲染与内存节省之道
c++·qt·游戏·设计模式·系统架构·图形渲染
BoBoZz192 天前
PolyDataToImageDataStencil如何用多边形数据作为“模板”来裁剪或屏蔽图像数据
python·vtk·图形渲染·图形处理