背景

关于实现全景功能的方案。生成处理全景照片的工具有https://github.com/ppwwyyxx/OpenPano,十分强大。在B端展示的方案有很多,当中有不少基于Three.js实现的,比如https://github.com/pchen66/panolens.js ,也有直接封装WebGL实现的库,必如 https://github.com/mpetroff/pannellum,这两个库都很强大,不仅支持常规的全景浏览,还支持多分辨率的显示和全景视频。

本文实现的全景展示,仅使用Cesium已经封装的webgl渲染接口,不借助第三方库,通过调整渲染流程,在三维地球的canvas元素上,进行全景浏览。优点有:

  • 不依赖任何第三方库,可以集成到Cesium源码。
  • 通过复用Cesium渲染流程的颜色缓冲区,过渡显示可以无缝衔接。避免借助第三方库初始化div容器等出现瞬时切换、黑屏现象
  • 学会使用Cesium封装的渲染接口实现一个自定义的简单渲染流程

现状

全景照片数据格式,常用的有单张ERP投影图片(Equirectangular Projection,宽高比为2:1),立方体贴图(切割成六个面),和多分辨率形式的全景切片数据。关于全景数据格式的更多介绍,可以参考http://hugin.sourceforge.net/docs/manual/Panorama_formats.html,

关于全景查看器,更多介绍可以参考https://wiki.panotools.org/Panorama_Viewers 。在B/S架构中,个人推荐https://pannellum.org/

  • 是支持的格式较多,包括全景切片(提供python切片工具,我没有验证,自己参考别的代码用java写过一个)
  • 不依赖其他的javascript
  • 代码开源,原生WebGL实现,可玩性更强(我没有深入研究)

实现原理

本来想说明实现原理,但是感觉一是比较简单,二是灵活有多种实现方式,另外发现不确定是否能理解。我的实现其实是参考twgl的相关示例并做了改动,使用cubemap,假定相机位于原点,相机方向朝向视角原点,这样可以直接简化MVP矩阵计算关系。

另外,关于融合过渡的是效果,转场过渡效果可以是由两texture的混合过渡,另外一个texture是从Cesium渲染的颜色缓冲区复制过来的。关于转场特效其实还可做一些其他的实现。

关于鼠标移动和缩放,如果没有理清楚投影矩阵和视图矩阵,是很容易出错的,我就卡住了几天。

关于渲染流程,在Cesium流程中增加pass或者通过framebuffer去实现,是没必要而且并没有很好的办法去做切换管理,我这里是直接停掉了Cesium的渲染过程,新增了全景的渲染流程。

结果演示录屏

该视频大约9.95m,可能加载较慢。