Cesium和Three.js结合的5个方案

本文探讨了Cesium与Three.js的集成方案,包括Cesium加载Three.js模型、基于Cesium的Three.js渲染器、在Cesium中使用Three.js接口、将Three.js场景作为模型加载以及Cesium与Three.js的深度融合。总结了各种方案的优缺点,特别是深度融合方案实现了遮挡、光照、阴影的正确处理,提供了统一的渲染效果。

CesiumJS是一个开源、免费的三维地图开发框架,Three.js是一个也开源、免费的3D渲染框架,两者都是基于WebGL技术、使用JavaScript开发的Web前端三维可视化框架,在国内外应用非常广泛。本篇我们来聊聊Cesium+Three.js的几种方案,结合实际应用效果来分析各个方案的优点和缺点,以便项目中快速做出技术路线和方案选择。

1、Cesium和Three.js简单对比

Cesium可视化内容以地理空间数据为主,如卫星影像、地形、城市级三维模型等,数据量和空间范围都非常大,而对精度要求更高,所以其核心优势是高性能、高精度、规范标准,规范标准体现在遵循行业标准和主导制定3D Tiles标准上。

在这里插入图片描述
cesium官网

Three.js的目标则是构建一个易于使用、轻量级、跨浏览器的通用3D渲染框架,核心数据是3D对象和三维模型,视觉呈现、场景组织、3D对象管理、动画、可扩展性等方面有独特的优势,且可以于物理引擎很好的结合使用,在大屏三维展示、游戏、仿真等方面很有应用价值。
官网

相比之下,Cesium更像是一个高级餐厅,下单即可坐享其成;而Three.js更像是一个厨房,厨具、食材甚至菜谱都备齐,就等你来发挥厨艺。

2、探索融合之路

写到这里,不禁要回望一下自己这几年执着地探索两个引擎融合的历程。

2.1、将Three.js场景当作模型加载

早在2017年初,接触Cesium近两年,又写了一段时间Three.js,对Cesium只支持gltf格式模型这一点不满,看到Three.js社区有很多模型格式的插件,便萌生了CesiumThree.js结合的想法。

折腾大概两周,实现了第一个方案,先使用GLTFExporterThree.js场景导出为gltf格式,然后通过加载gltf模型的方式,总算是把Three.js解析的模型加载到Cesium场景中了。

很快就发现这种做法的致命缺点:加载极慢,且不支持动画!

2.2、实现基于Cesium的Three.js渲染器

没过多久,开始读Three.js渲染器的源码,再加上对Cesium底层的一知半解,心里似乎很有底气了,开始了新的探索,参照Three.jsWebGLRendererCanvasRendererSVGRenderer,动手写一个CesiumRenderer,还将源码传到了GitHub,还起了一个很牛的名字Cesium3js( https://github.com/MikesWei/Cesium3js ),这也是我上传的第一个开源项目。

想法很大,名头也很大,也实现了当时预期的效果,前面一个方案的缺点一定程度上已经弥补了,但是和真正渲染器差点不是一星半点,绝大部分的特性,都没有支持。

几个月后,Cesium官方博客上那篇介绍CesiumThree.js集成方法的文章( 《Integrating Cesium with Three.js》https://cesium.com/blog/2017/10/23/integrating-cesium-with-threejs/ ) 发表了。

2.3、在Cesium实现Three.js部分接口

2017年底,换了新工作,有个项目需要将天气雷达三维数据展示在三维地球中,最好是实现体积渲染。寻寻觅觅,最终还是在Three.js社区找到了资源。有了项目需求驱动,我更清楚自己做CesiumThree.js结合的目的,于是将Cesium3js代码重新整理,放弃了在Cesium上使用Three.js所有功能的想法,甚至直接不用依赖Three.js,而是在Cesium中实现类似Three.js的Mesh和Material的一套接口和渲染机制,支持部分Three.js对象。半年后将其开源,这便是我的第三个开源项目CesiumMeshVisualizer ( https://github.com/MikesWei/CesiumMeshVisualizer )。承蒙同行不吝点赞,目前收获了454个Star,156次Fork。

2.4、将融合进行到底

2020年夏,GIS平台和游戏引擎融呈现不可挡的趋势,超图、Cesium等都相继推出虚幻引擎(Unreal Engine)插件。我们接到的需求,除了“静止”的海量数据调度外,场景中“运动”的物体也呈数量级增长,数据更新频率更高,更新的部件粒度也更细,用户三维场景的视觉效果要求更高,Cesium在这方面的能力明显不足。我们看到Three.js在解决这类需求具有极大的潜力,并在2020年底实现了CesiumThree.js深度融合方案,真正实现了基于CesiumThree.js渲染器,让CesiumThree.js两个场景浑然一体!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ld1g34qF-1638780791860)(./案例一(封面)].jpg)

3、方案效果对比及分析

从我们的探索历程可以看出,融合的方案很多,可以分为两类:

  • 两个场景叠加,使用两个相互隔离的绘图上下文(context),WebGL层也没有任何交集,这类我们称之为“两个画布”方案;
  • 两个场景共用一个绘图上下文(context),WebGL层有交集,这类我们称之为“一个画布”方案。

两类方案中又有很多具体的实现方案,下面基于我们现有的技术,通过实际代码,看看几个方案的效果。

3.1、小窗叠加显示three.js场景

此方案以Cesium创建的三维地图为主,展示宏观的地理空间场景,点击到地图上某个要素时,弹出小窗使用three.js展示诸如室内、设备详细结构、零部件等。两个场景只在业务逻辑上有关联,完全可以独立开发,最后进行集成,属于“两个画布”类。

下面通过一个简单的示例演示这个方案的主要流程。

HTML代码很简单,创建两个场景的容器,然后引入Cesium的js和css文件,Three.js通过import导入。

<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1.小窗叠加显示three.js场景</title>
    <style>
        html,body{
     
     
            margin: 0;
            padding: 0;
        }
        #cesiumContainer {
     
     
            width: 100%;
            height: 100%;
        }
        #threeContainer{
     
     
            width: 20%;
            height: 30%;
            position: absolute;
            z-index: 2;
            top: 0%;
        }
    </style>
</head>
<body>
    <div id="cesiumContainer"></div>
    <div id="threeContainer"></div>

    <link rel="stylesheet" href="../node_modules/@mesh-3d/cesium/Build/`Cesium`/Widgets/widgets.css">
    <script src="../node_modules/@mesh-3d/cesium/Build/`Cesium`/Cesium.js">
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值