一种面向Web3D的大规模场景实时绘制方案

2017-04-27 11:46葛一波
电脑知识与技术 2016年29期

葛一波

摘要:网页端处理大规模3D场景一直是一个极具挑战性的问题。提出了一套面向Web3D的大规模场景实时绘制方案。首先,对场景数据进行处理,对室外进行网格划分,对室内构建连通图,对重复模型进行检测,建立出适用于Web上展示的场景结构;之后,使用基于兴趣区域(area of interest,AOI)的室外场景管理和基于连通图的室内场景管理结合的方式进行场景加载和绘制。为提高用户体验,引入关注度的概念优化场景绘制方案。最后通过实验,证明了方案的有效性。

关键词:Web3D;AOI;连通图;场景管理;实时绘制

中图分类号:TP391 文献标识码:A 文章编号:1009-3044(2016)29-0201-03

1引言

随着互联网时代的到来,将互联网与虚拟现实进行结合所产生的Web3D技术也随之应运而生,其目的在于在互联网上构架三维虚拟世界。而由于计算机用户对图形效果要求的不断提高,三维场景日益复杂,在虚拟场景的规模快速扩大的同时,场景数据的复杂度也在随之增加,这使得浏览器不可能一次性地加载所有场景数据。此种情况下,如何在网页端处理大规模3D场景,实现在线流畅展示,是一个极具挑战性的问题。

本文主要设计了一种面向Web3D的大规模场景实时绘制方案。方案通過场景数据分析,对场景进行网格划分,用于实现场景的分块加载,同时对可重用模型进行检测,便于之后进行数据重用;引入AOI思想,根据视点位置,通过多线程对室外场景进行分块加载及绘制;引用Cell&Portal算法思想,构建室内场景连通关系图,实现室内场景分区加载;通过实际测试,引入场景模型关注度的概念,对方案进行优化。最后,通过实验,证明本文提出的方案是有效可行的。方案主要使用We-bGL进行实现。具体技术路线图如图1所示。

2场景数据预处理

为了更方便地进行后续场景管理,本文首先对场景数据进行预处理。主要分为三部分工作:

1)

针对场景中存在的某些模型对象重复使用的情况,例如,一个房间中多个相同型号的椅子。本文通过将多个模型对象使用一套模型数据及多个变换矩阵的形式给出,有效降低了需要加载的数据量及程序运行时的内存消耗。

2)针对室外场景,本文将整个场景地图进行网格划分,并对网格进行编号,然后将模型顶点投影到网格平面,记录下投影到的网格编号,即将模型绑定到了一个或多个网格上,便于后续场景管理策略的实现。如图2 a)所示,B0、B1、B2、B3代表了室外建筑物,可以看出B0占据一个网格,而B1、B2、B3分布在多个网格中。图2b)给出了网格A、B、C、D对应的数据结构。

3)针对室内场景,引人Cell&Portal算法的思想,通过分析室内房间的连通关系,将整个室内空间按照房间进行分区,实现室内场景分区管理,而像过道等特殊空间也可用房间进行表示。如图3左图所示,门、窗等连通面代表了房间的连通关系,房间内则附带一些家具模型信息,右图则给出了构筑物B0与室内房间构建出的连通关系图。

3场景管理策略

为对大规模场景进行实时渲染,需要进行有效的场景管理,本文分别从室内与室外进行阐述。

3.1基于AOI的室外场景分块加载与绘制

在现实生活中,人们的视野是有一定限度的,超过视野的区域是看不清,也就不会过多关注,而会将更多注意力放在眼前物体上,在虚拟场景中也是同样的道理。通过视点坐标对场景对象集进行过滤,这即是AOI的思想。

通过前述网格划分,本文很容易将AOI应用于算法中。如图4所示,考虑到场景漫游时需要频繁旋转视角的特点,本文将距视点坐标一定范围的圆形区域作为兴趣区域,即图4中粗线描述的圆形区域,而将兴趣区域覆盖的网格作为需要绘制的区域,对这些网格内绑定的模型对象进行显示。同时,为了提高渲染的实时性,不会出现当前显示区域模型文件还未加载的情况,本文在兴趣区域基础上扩充一定范围作为加载区域,即图4中细线划定的圆形区域,而将该区域覆盖的网格作为需要加载的区域,对这些网格内绑定的模型对象对应的数据进行预加载。这样在视点运动时,从一个网格运动到另一个网格,变化后的显示区域并未超出运动前的加载区域,从而不需要等待数据的加载完成即可实时进行新区域的场景绘制。

程序运行时,由于场景绘制并不需要等待数据加载的完成,场景绘制与场景加载可以分开进行,使用多线程可以很好地进行上述工作。本文工作是在WebGL基础上展开,HTML5很好的提供了多线程的支持,在具体实现上,本文将数据加载与模型对象构建的任务交由一工作线程进行,而主线程主要负责当前场景渲染队列的管理,将显示区域的模型对象添加到渲染队列进行绘制。

在程序运行之初,首先根据视点位置加载模型数据,然后根据模型数据进行模型绘制;之后在场景漫游中则根据视点位置的移动,使用增量和减量的形式,如图5所示,对新进入显示区域的增量网格中的模型对象添加到渲染队列,对离开显示区域的减量网格中的模型对象进行移除。这里需要注意,一个模型对象可能覆盖多个网格,当这多个网格有一个存在于显示区域,就需要对该模型对象进行绘制,因此程序在运行时需要对模型对象进行计数,当模型对象所在某个网格进入显示区域,其显示计数即加1,离开则需要减1,只有当模型对象显示计数为0时,才将其从渲染队列中删除。同理,使用相同的方式维护加载区域。

3.2基于连通图的室内场景分区加载与绘制

当在室内进行场景漫游时,考虑到室内场景结构复杂,房间与房间相互阻隔,当漫游到某个房间,我们不会关心它不相邻的房间的结构情况,因此为减少不必要的渲染,本文通过前述构建的室内场景连通图,对室内采用分区加载和绘制。具体过程如下:

1)当摄像机处于室外时,加载并绘制室外场景的同时,对于室外构筑物连通的室内房间进行加载并绘制,而与该房间相邻的房间则进行预加载。如图3,R0即为与B0构筑物相邻的房间,需要进行显示,R1、R2、R3是与R0相邻的对象,需要进行预加载。

2)当从室外进入室内某个房间,根据预加载的数据绘制与该房间相邻的房间,且预加载与相邻房间连通的房间。

3)当从一个房间通过连通面(門、窗等)运动到另一房间,将与另一房间相邻房间加入渲染队列进行绘制,且将不相关的房间从渲染队列中移除。加载数据的流程也是如此。

需要注意的是,在加载或绘制某个房间时,需要以相同方式处理房间内包含的模型对象。与室外场景管理类似,加载数据也需要单独使用一个工作线程来进行。

4基于关注度的优先绘制算法

以上场景管理策略在实际测试中,我们发现了一个问题:在进行室外场景漫游时,由于程序只是绘制摄像机相邻区域内的模型对象,对稍远一点的模型对象则采用预加载而不绘制的处理方式,这使得实际运行时,一些距离稍远而体积很大的模型对象,由于距离远而未绘制,只有当摄像机离它稍近时才显示出来,这显然没达到预期的效果,用户对一些体积稍大而距离并不太远的构筑物也比较敏感。本文针对这一情况提出了相应改进算法。

首先,本文引入关注度的概念。关注度指的是用户对于场景中的某个模型的关注程度。关注度受到三个主要因素的影响:模型的体积大小,模型数据复杂度,模型距离摄像机的距离。模型的体积越大,复杂度越低,距离越短,模型的关注度越高。所以可以列出以下公式:

attentionLevel=100* boxSize/dataSize/cameraDistance

其中boxSize是指模型包围盒的体积,dataSize是指模型数据复杂度,cameraDistance是指摄像机距离模型的距离,100为扩大常量,便于取值判断。当attentionLevel大于0.01(实验数据)时,表示模型是易受到关注的。

这里,对上述室外场景管理策略进行相应更改。在程序对加载区域的模型对象进行数据加载时,计算出其相应的关注度,并以此判断模型是否易受到关注;当确定模型易受到关注,则将模型直接加入渲染队列来进行显示,这样使得加载区域中关注度高的模型对象能得到优先绘制,从而提供给用户更好的视觉体验。

5实验结果

最后本文通过实验对上文提出的方法进行测试。测试环境为Windows 10操作系统,使用Chrome浏览器进行展示,硬件配置为Intel(R)Core(TM)i5-2400 CPU@3.IOGHz处理器、8.0GB内存、NVIDIA GeForce GTX460显卡。针对基本点、线、面数据量200M、模型对象个数为10000个左右的数据进行测试。使用算法前后对比如下:

从表格中可以看出,使用本文算法后,首次加载时间明显缩短,内存消耗减小,且FPS显著提高,这些都能很好优化用户体验,且本文在测试不使用本文算法的情况时,由于数据量很大,经常会出现浏览器崩溃的情况。图6给出了使用算法后的实验效果。

6结论

以上实验表明,本文提出的方案能有效降低系统资源消耗,提高渲染效率,为大规模场景实时渲染提供有力支撑。