Loading

【转载】谈谈GIS三维渲染引擎

> 原文地址:https://zhuanlan.zhihu.com/p/419667971

三维引擎

minemap:

是我们公司的产品,主要以earth的形态展示,支持矢量切片+倾斜数据(这一点我个人认为是它最大的优点,即兼容了矢量切片精美地图又兼容倾斜数据,目前倾斜数据采用的3dtile格式),目前正在重构引擎架构,任重而道远啊,现在官网的案例demo都是早期版本,好多新功能还木有更新,属实有点汗颜。

cesium:

一款开源的三维地图引擎,国内的大多三维GIS引擎大多基于cesium二次开发,其3dtile标准列入OGC,是唯一具有完备的渲染底层封装的GIS三维引擎库,完整的渲染模块,图元概念等,cesium的三维概念不同于其他三维GIS引擎,Cesium是以第一人称相机,其余的都以第三人称相机。第三人称相机最大的特点就是有mapCenter的概念,这一点cesium并没有,目前cesium的矢量切片也在完备,很是期待。对于好多GIS开发人员感觉cesium不好用,倾斜加载效率低。如果对于基础上手确实不容易,但是对于webgl的功能扩展,它非常好用,关于倾斜最大的优化在于数据,比如draco、crn、ktx2等优化,可以使数据加载与浏览的性能极大提升。

mapboxgl:

矢量切片的王者,也是矢量切片标准的制定者,mapboxgl最大的特点就是其矢量切片(包括其字体,真的是一绝)。mapboxgl的数据切片大量用了webworker,以及数据的合批(在同一个瓦片内的数据顶点数据合并,减少数据的上传),关于其render模块,都是以drawXX函数,这一点很扯淡,虽然写小逻辑很爽,但是扩展很不爽,尤其扩展webgl功能,以前drawXX函数中各种uniform函数,现在倒是给管理起来了(我感觉它应该借鉴了cesium,因为它两的风格写的很像)。加载三维能力较弱,如果需要扩展webgl可以通过custom图层,你需要自己写着色器、顶点坐标、索引坐标,其实和原生的webgl一样。有人要说这不是很好,为什么说扩展困难呢?设想一下:如果你加三个box,需要对其中两个做后处理,怎么做?他没有图元的概念,就是一个一个tile,每一个tile中包含所要渲染的数据,这一点让人很难受。总的来说,其矢量切片真的很值得研究。

deck.gl:u

ber的一块三维地图引擎,其本身不具有渲染能力,渲染模块采用的是luma.gl,该库的shader模块写的很有特色,包括 glsl100与glsl300转换, luma.gl的也是uber旗下的,uber旗下还有一个数据加载的库就是loaders.gl.这个库主要负责数据加载是一个混合库,兼顾3dtile、i3s、gltf、pointclout、texture等数据的加载。加载三维能力要强于mapboxgl主要归功于luma.gl。

maptalk:

国内大神作品类似于mapbox,目前其扩展三维能力主要靠maptalk.three实现maptalk本身功能完备,其本身的渲染能力(切片、点、线、面)依靠的是regl ,目前在加载倾斜数据上面好像还待优化(应该正在优化,听Zhen神说的),其插件比较丰富。

arcgis:

GIS领域的老大哥arcgis4.x以上的好像才有三维地球的概念,以前都是二维,好多年不用了,其倾斜数据标准是i3s也是OGC标准。好多人说i3s要优于3dtile,在大数据量的时候才能凸显,小数据量估计不太明显。对i3s格式以及加载逻辑研究不多,这里就不多说了,这里有一篇关于arcgis的i3s vs 3dtile的ppt有兴趣的可以看看

 

vts-brower-js:

一块类似cesium的三维可视化引擎,以前一直不知道该引擎,看到github上面项目创建与5年前,但是提交很少,下面是它与cesium的对比,关于不同坐标系的支持,这个还是有点技术含量的其他的就........,关于不同坐标系的支持我猜他是进行了动态的纠偏,因为地球是WGS84剖分你只能按照四叉树剖分,它也支持加载倾斜摄影,有自己单独的格式。具体的可参见下面这边文章:

openglobus:

也是earth三维开源引擎,目前功能还不够完善,支持栅格和矢量数据,这个库给的感觉好像是openlayer的,例如代码这样写:

var osm = new og.layer.XYZ("OpenStreetMap", {
        isBaseLayer: true,
        url: "//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        visibility: true,
        attribution: 'Data @ OpenStreetMap contributors, ODbL'
    });

    var globus = new og.Globe({
        "target": "globus",
        "name": "Earth",
        "terrain": new og.terrain.GlobusTerrain(),
        "layers": [osm],
        "autoActivated": true,
        "viewExtent": [5.56707, 45.15679, 5.88834, 45.22260]
    });

    new og.layer.Vector("Markers", {
        clampToGround: true
    })
        .addTo(globus.planet)
        .add(new og.Entity({
            lonlat: [5.73, 45.183],
            label: {
                text: "Hi, Globus!",
                outline: 0.77,
                outlineColor: "rgba(255,255,255,.4)",
                size: 27,
                color: "black",
                offset: [10, -2]
            },
            billboard: {
                src: "./marker.png",
                width: 64,
                height: 64,
                offset: [0, 32]
            }
        }));

单纯的og.layer.XYZ感觉有点像openlayer,addTo这种又给人是leaflet的风格,Entity又是Cesium的风格,有点乱哈,这个库适合学习底层支持,至于用于项目不太推荐,目前引擎支持状态:

itowns:

一款基于three.js的三维GIS渲染引擎(earth),它这个球感觉操作起来怪怪的,能加载3dtile(效果好像不咋滴)、WFS、切片等,感觉学习一下还好,要是用,还是算了吧,虽然背靠three.js的大树,我觉得用maptalk.three都比它强,

WebGlobe:国内大神作品,该库目前不在更新,它得相机是俯视状态,无法改变俯仰角,给人二维的感觉,这个库里面得射线求交当前可视范围与四叉树剖分可以看看,适合学习。

二 、自己关于GIS三维渲染引擎的一些看法

关于三维渲染引擎与GIS三维渲染引擎:两者的侧重点不同,三维渲染引擎主要侧重渲染的效果,例如pbr、光源加入等着重在还原真实世界的事物,数据多是gltf、obj等。三维GIS引擎侧重于数据与精度(个人认为)其次是渲染效果,与渲染引擎不同的是三维GIS引擎涵盖的数据量较多例如矢量、倾斜、点云等,这些数据量都是很大的,几百G之大,这一点就对三维GIS引擎的数据的缓存要求很高,要不然浏览器动不动就崩溃了,三维GIS引擎着重准确还原事物在真实世界中的位置。

理论上三维GIS引擎应该涵盖三维渲染引擎,三维渲染引擎作为渲染模块,提供渲染能力,目前将三维渲染引擎涵盖里面,寥寥无几,做的较好deck.gl,其渲染模块由luma.gl提供,其次Cesium,但是并没有提炼出整个渲染引擎,更像是渲染库,有primitive、geometry、Material等概念,并没有像deck.gl完全独立出来渲染模块。为什么要将GIS逻辑与渲染独立出来?一方面为了降低耦合,另一方面你可以自由的更改渲染模块,让GIS三维引擎根据不同的渲染引擎具有不同的特色(例如换成three.js、babylon.js),例如未来切换webgpu,不至于切换那么耗时费力,个人感觉最好不要借助第三方渲染引擎,可以自己写一个简单的渲染引擎,然后慢慢的丰富。

关于数据缓存与销毁:个人认为采用计算geometryBufferSize+textureSize并且结合LRU比较好,这一点参考cesium,其在3dtile上面的数据缓存与销毁采用上述方法,与单纯LRU缓存我觉得前者更为准确,如果在三维GIS引擎中不加载倾斜数据采用LRU缓存策略可能没有问题,如果加载倾斜模型可能造成内存崩溃,个人认为第一种计算更为合理。

关于自研GIS三维引擎:一块GIS三维引擎核心的就是栅格切片、矢量切片、倾斜模型。栅格切片实现还好说,矢量切片个人感觉借鉴mapboxgl、倾斜模型借鉴cesium的3dtile那套加载逻辑。借鉴没有什么好丢人的,有人感觉既然是自研引擎那必须从头开始写,自己一行一行的敲下去,借鉴别人的,在别人的基础之上去改善,难道不是更好?自研GIS引擎要有自己的特色,如果只是抄,那也没什么意义。

关于相机:对于GIS三维引擎,整个场景仅需要一个相机。相机分为第三人称相机和第一人称相机,第一人称相机:cesium,第三人称相机mapboxgl、deck.gl等。第一人称相机结合四叉树可以完全控制整个场景的数据加载,第三人称相机需要结合center,也是地图中心点。第三人称相机类似还是二维的概念切片加载需要计算当前窗口的地理范围配合zoom,计算需要加载的切片,第一人称相机需要借助几何误差(相机距离物体的距离),也就是lod,在三维世界中第一人称相机更为合适?为什么这么说呢,例如加载地形,在第三人称相机,在珠穆拉玛峰正上方看珠峰峰顶,你会发现珠峰峰顶是模糊的,你相机基本放在峰顶离得很近为什么还是模糊的,理论上应该很清晰啊。这是因为此时zoom很小,如果此时zoom为4,而理论上你应该看到的是zoom为8的数据,如果用第一人称相机+四叉树lod方式就不会出现这种情况。

关于渲染效果:在我们印象中GIS三维引擎的渲染效果很差,和纯三维渲染引擎没法比,一方面是两者的侧重点不同,另一方面GIS三维引擎本身的渲染能力很弱,像渲染引擎中的后处理、法线贴图等都不具备。这也是我为什么想把渲染模块与GIS逻辑分析,这样更好的扩展渲染能力,对一些小场景GIS三维引擎有能力做出较好的渲染效果(web端)。

做出来功能很容易,做好真的很难!!!!

以上是自己对web端GIS三维引擎的一些看法,小弟才疏学浅,难免有错,望各位看官指出不足之处,以免误导他人

posted @ 2023-02-10 17:35  Nicander  阅读(320)  评论(2编辑  收藏  举报