Web 端的三维 GIS 应用在 WebGL 等技术的不断发展中逐渐成为主流,城市模型的数据量越来越大,要想将城市级三维模型数据流畅、完美的呈现,除了较好的硬件、软件、网络带宽条件,还有采取一些优化措施。
今天总结下从模型数据、服务发布到前端渲染的软性的优化方法。
一、模型优化
模型大小和复杂度直接影响数据传输和前端解析渲染的效率,所以为了前端显示性能,在保证数据的完整性和显示精度的前提下,尽可能的通过不同的策略对模型进行优化。
01 模型数据优化
常见的三维模型数据有地形、倾斜摄影、BIM、激光点云、精细模型、水面、地下管线、场数据,城市级的数据量很大,一定要检查模型三角面数、纹理大小。
最有效的模型优化方法就是通过减少模型总面数、减少模型总个数、模型总贴图量来减少数据量,在三维建模时,一定要重视,养成模型优化的习惯。
(1) 简化模型三角面
一个单独对象的面数不要超过 3 万个,若超过 3 万个三角面,则应该分成 2 个或多个对象。比较长的条带状物体(如高架路等)必须分段,每段长度不能超过 500 米。
对于手工精细化模型建模时,3Ds Max、SketchUp 都有简化模型的插件,减少模型三角面的数量,比如 Polygon Cruncher 可以将模型的面数量减少到 80%,并保留所有细节。
GIS 软件也提供了模型的简化工具,可以利用移除重复点、移除重复面工具对模型进行简化。
对倾斜摄影数据采用 3 种优化算法进行压缩处理,减少数据量。一是合并根节点,向上抽稀生成一层更为粗糙的 LOD 层级,每合并一次,模型根节点数量减少约为原始数量的 1/4;二是纹理压缩,将 jpg 格式压缩成二进制格式;三是将 OSGB 格式转为适用于 web 端显示的 S3m 格式。
对于管线模型,在利用管线截面和埋深、管底高程、管径进行参数化建模时,尽可能减少管线圆形截面节点数量,减少管线模型的面数。
对于BIM 模型,可以通过简化三角面数、去除重复点和冗余点、导出 LOD 等方式优化模型。
(2)减少纹理大小
贴图尺寸规格为 2 的 n 次方,在保证纹理清晰的情况下,尽可能减少纹理大小,最大不超过 1024*1024,以利于网络传输。
纹理格式尽量使用 JPG、PNG。纹理贴图长宽比差异不宜过大、纹理贴图不易太碎。
贴图中的有效纹理像素面积,与总纹理的像素面积的比值不得低于 70%,减少无效纹理。
区域内不同模型用到相同或类似纹理贴图时,采用同一张纹理贴图。
02 生成场景缓存优化
三维场景搭建完成后,生成场景缓存是一个提升性能的重要方法。
在大场景缓存数据格式方面,Cesium 提出了 3D Tiles 的三维瓦片数据格式,超图、ESRI、MaPGIS 三大 GIS 厂商也陆续推出了自己的三维场景缓存格式 S3M、I3S、M3D,每一个缓存文件就是分层、分块的三维瓦片,它们实际上都是压缩文件,内部包含几何数据、纹理数据和元数据。
每个缓存文件过大将会有较长的下载时间,占据请求队列,并且缓存文件过大,也说明了纹理过大或三角面多,导致渲染速度降低,最好将每个瓦片文件数据大小控制在 1M 以内,通过减小瓦片边长将瓦片文件调小。
每个缓存文件数据过小,则瓦片数量太多,同样给网络传输和渲染显示带来影响,通过增大瓦片边长将瓦片文件调大。
设置瓦片缓存的层级,即 LOD 层数,根据数据类型设置,建筑推荐 5 级,地板推荐 3 级,小品、树木等推荐 3 级。
设置纹理图片缓存格式为 web 压缩格式,相比 Jpg 能减少 40%。
不要保留法线。
现在主流的 GIS 平台,为了保证前端渲染速度,都对模型做缓存切片,虽然速度提升明显。
但也带来一个很严重的问题,那就是需要不定期的更新模型数据,尤其像工程竣工验收后的模型数据更新,更是需要人工频繁的更新切片来保证数据的现势性,比如管线。这是需要技术层面去不断完善优化的。
03 配置场景优化
切片缓存后,要将各个缓存图层进行叠加,搭建三维场景,可以通过以下方式优化:
(1)设置可见高度
通过相机与图层的垂直高度,控制图层对象的可见性。垂直方向离相机太远处不用看清模型,模型图层不用显示。
(2)设置可见距离
通过相机与模型的直线距离,控制模型对象的可见性。水平方向离相机太远处不用看清模型,不用再显示模型。
(3)设置 LOD 缩放比例
通过设置 LOD 层级切换距离的缩放比例,控制 Lod 切换距离。根据 LOD 切换距离 = LOD 距离*缩放比例,缩放比例越大,切换距离就越长,同一相机点的模型显示越粗糙。
(4)创建空间索引
给三维瓦片创建空间索引,再一次提升瓦片显示速度。
对于模型来说,只有在性能和展示效果上取得平衡,找到最为合理的优化方案,才可以获得最满意的浏览效果。
二、GIS 服务器优化
GIS 服务器提供三维场景服务的发布,可以利用工具对 Iserver 性能进行评估,CPU、内存资源够不够,Java 环境设置是否合适,Iserver 配置是否恰当,查找出 Iserver 存在的问题。
主流 GIS 服务器都提供了负载均衡方法,最主要的是能通过使用集群、多进程方式大大提升性能。
01 使用集群
GIS 应用服务器使用集群有使用本地集群服务和使用多机集群服务两种方式。
如果服务器的硬件性能很好或者说是没有更多的服务器的时候可以配置单机集群,只需要一个许可。
如果使用多机集群服务,则是在多台机器上配置集群,需要多台服务器、多个许可。
02 使用单机器多进程
单个进程不能充分利用系统 CPU、内存等系统资源。为了充分利用系统资源,设置单机多进程,每一个地图服务可以通过多进程去跑。
调整开启单机多进程,设置 worker 进程个数,建议 Worker 个数与 CPU 核数相等,以获得最佳性能。
将数据量大的地图、三维场景或数据服务设置成 “允许多实例”,这样才会多个进程跑一个服务。
为了进一步提升 Iserver 性能,开启资源定时回收,可以将时间设在并发访问较少的时间段。
三、前端 WebGL 优化
01 问题诊断
想要优化前端,就得知道前端性能瓶颈来源于哪里,这样才能对症下药,这里推荐一个优化神器—**DevTools**。
使用 Chrome 浏览器 DevTools 的 performance 可以通过分析页面活动,进行性能诊断。
这个工具可以看到每个行为所消耗的时间、应用运行时每个时间点的 cupu、内存、GPU 的压力以及当前时间点的 FPS,很容易发现性能瓶颈出现的地方。
02 优化措施
从大体上来分,优化方向大致可以分为代码优化、内存优化、渲染优化。下面讲讲可以采取哪些具体优化策略。
(1)代码优化
代码层面的优化可以通过 Performance 找到执行效率低的代码片段,对算法进行优化,修改不合理的相关逻辑。比如:使用异步编程,防治线程阻塞;使用 Vue 框架开发时,不要将场景对象挂载到 data 下等。
(2)内存优化
在大型三维 GIS 的 WebGL 应用中,内存资源非常吃紧。在浏览器中,JavaScript 的 heap 容量是有限的,一旦超出容量的限制,页面就会直接崩溃。所以,我们要及时销毁不需要的对象,释放内存,尤其是模型数据。
(3)渲染优化
渲染优化的目的是减少向 GPU 提交的数据量,提高每秒渲染的帧数,可以通过剔除不需要渲染的数据、减小模型精度来实现。
视椎体剔除(Frustum Culling):只有在视椎体内的物体才能被渲染出来,不在视椎体内的物体将被剔除不作渲染,大部分的引擎都已经自带了。
背面渲染剔除 (Backface Culling):只绘制模型正面观察者能看到的部分, 模型背面看不到的部分就丢弃不绘制,检查渲染引擎是否默认开启背面剔除。
遮挡剔除 (Occlusion Culling):在视野范围内被遮挡的对象不需要进行渲染,减少渲染压力,检查渲染引擎是否默认开启遮挡剔除。
设置显示精度:设置渲染分辨率的缩放因子 resolutionScale, 值小于 1.0 时能够在配置较低的设备上提高性能;相反,值大于 1.0 时将会以更高分辨率渲染显示。
设置 LOD 层级切换距离缩放系数:主要用来调整模型显示的精细程度。对于同一位置的模型,lodRangeScale 设置的值越小,模型显示越精细;值越大,模型越粗糙。
除了上面谈到的模型数据、GIS 地图服务器、前端系统做到最优以外,还需要服务器、网络带宽具有较好的条件,毕竟三维模型占用的计算资源、网络传输资源是比较大的。
模型数据的优化、GIS 服务器的优化属于是基础的,但效果改善也是最明显的。前端渲染优化部分,很多三维引擎已经默认做了,我们自己可操作的内容或改善的效果不是太明显,属于是锦上添花的。
微信公众号 |GIS 研习社
https://mp.weixin.qq.com/s/UuAp9j5gtfsgrXM5BR9ZUg