APP下载

基于WebGL的Canvas元素2D绘制加速

2016-02-13谢贤博邓红艳

软件 2016年12期
关键词:着色器浏览器顶点

谢贤博,聂 芸,邓红艳,张 宇

(华北计算技术研究所 地理信息与图形图像技术研发中心,北京 邮编 100083)

基于WebGL的Canvas元素2D绘制加速

谢贤博,聂 芸,邓红艳,张 宇

(华北计算技术研究所 地理信息与图形图像技术研发中心,北京 邮编 100083)

HTML5中的Canvas元素极大地丰富了网页所能呈现的图像信息。Canvas元素具有两种绘图模式:Canvas2D接口类似于画布,用于渲染2D内容,使用简单,可由浏览器负责硬件加速;WebGL接口类似于OpenGL-ES,负责渲染3d场景,使用复杂,但可以直接使用硬件。当绘制的2D基本图元数量较多时,实时性要求高时,Canvas2D接口性能不足。本文将以WebGL为基础,提出一种优化思想,通过缓冲技术、常量属性化技术、帧间缓存技术、DMA技术,加速不同2D基本图元的绘制。本文对不同的2D图元绘制方式性能进行对比实验,证实以WebGL加速Canvas的2D绘制是可行并且有效的,并且给出一个实际应用实例。

计算机图形学;WebGL绘制;设计与实现;高性能渲染;HTML5

0 引言

随着HTML5的普及,网页可以承载更多以往桌面或移动客户端的内容。Canvas是HTML5引入的新画布元素,开发者可以用JavaScript脚本在该元素上绘制任意图形。Canvas本身不具备画图属性,而是通过获取Canvas中的绘制上下文(Rendering Context),利用绘制上下文实现绘制。目前有两种绘制上下文:Canvas2D是用于绘制2D图形的API,包括基本图形绘制、文字绘制、图形变换、图片绘制和合成等;而WebGL是目前用于绘制3d图形的API,拥有一套简化的OpenGL-ES的功能,可以操作硬件,也可以使用封装好的图形库简化开发[1,2]。

目前浏览器上的主流的基于Canvas的2D引擎,尽管封装各不相同,都是用Canvas2D进行底层渲染;而主流3D引擎绘制2D画面的性能并不比2D引擎好。当需要绘制的物体过多,或者要求实时互动性强时,主流方法的渲染性能不足以满足。但是在桌面应用方面,使用3D加速2D绘制是很常见的方法。本文将探讨浏览器端使用WebGL加速2D绘制所遇到的和桌面端不同的问题,给出WebGL加速的具体原理和方法,通过实验验证WebGL绘制几种2D图形的性能,并分析具体的WebGL绘制方案。

1 加速原理

1.1 Canvas2D绘制原理

作为传统的2D绘制接口,Canvas2D提供了丰富的功能用以绘制2D对象。其中有一套以beginPath开始,以closePath结束的,基于过程的绘制接口,也有如drawImage等实时绘制接口,并且维持一个2D变换矩阵和一组绘制模式,应用在当前绘制的图形上。Canvas2D的优势在于使用简单,开发成本低,而缺点在于绘制方式固定,无法充分利用现代图形硬件。Canvas2D提供的绘制方式是以像素为基础的,并且也支持浏览器进行硬件加速。

1.2 WebGL绘制原理

WebGL接口的基本功能由着色器(Shader)[3]、输入、绘制指令、状态指令四部分组成。

为了完成一次基本绘制,首先需要初始化着色器,包括编译着色器,得到着色器内各个输入的地址等。着色器是将要运行在GPU上的小程序,分为顶点着色器(Vertex Shader)和片段着色器(Fragment Shader),顶点着色器负责将输入的顶点信息转化为顶点在屏幕上的位置,并且可以计算一些顶点的属性。光栅化操作依据绘制的图元,将屏幕上的顶点数组填充成三角形等区域,同时可以考虑遮挡关系,并且自动对三角形的顶点信息插值,将得到的像素则交给片段着色器。片段着色器依据得到像素的各个属性,计算像素最终的颜色。

之后,需要输入数据。着色器有两种输入,一种是顶点属性(Vertex Attribute),一种是常量(uniform)。顶点属性是依据需要绘制对象顶点数量而定的WebGL接口的基本功能由着色器(Shader)、输入、绘制指令、状态指令四部分组成。数组,一个顶点可以包含多个顶点属性,常常包括位置、颜色、纹理信息等。常量是和顶点无关的量,常常包括环境光、投影矩阵、变换矩阵等。对于不同的物体,常量可能不同。

然后需要设置状态。状态包括是否启用深度检测、是否启用混合、混合的类型等。

最后使用绘制指令,绘制指定数量的某种图元。

1.3 WebGL绘制特点

WebGL[4]是一套可以使用硬件的绘制接口,但是和传统的桌面OpenGL[5]相比,WebGL经过多次简化,删减了专用的3D投影、光照等内置功能,使其更容易被支持[6]。WebGL的优势是绘制灵活,着色器程序的性能高,可以绘制大量复杂的对象,可以使用更多的优化策略,而劣势是使用复杂,API调用开销大。

其中API调用的开销经常被程序员忽视。调用WebGL的API时,比如clearColor(0,0,0,1),其内容要被浏览器验证有效,并最终将被确实写入GPU,并且GPU确认后才能返回,并执行下一条指令。而Canvas2D的API则不同。与之前类似的fillStyle则直接是一个变量,甚至不需要进入CPU层。而一些绘制控制API比如beginPath、moveTo等,则只用传递给CPU层浏览器的绘制引擎,就可以返回。只有切实绘制内容的API调用会导致GPU访问。这种缺点使得通过WebGL直接实现Canvas2D的API而加速并不可行,这种方法只适用于在WebGL中兼容Canvas2D的一些绘制方式。

因此WebGL提升性能的重要途径之一就是减少API调用,可以使用缓冲技术和常量属性化技术。

1.3.1 缓冲技术

缓冲技术(Batch)[7]是指在绘制时,利用脚本将不同的绘制对象的绘制信息合并在一个缓冲器中,最终调用一次WebGL绘制指令,一次性将缓冲器的内容绘制出来。缓冲技术依赖于WebGL的绘制功能,必须同一类物体才能缓冲在一起绘制。常量属性化技术可以增加缓冲技术的适用范围。

1.3.2 常量属性化技术

常量属性化技术是指在设计着色器时,将uniform常量转换为attribute顶点属性,增加内存开销和顶点渲染器的运算量以减少或消除常量变化的技术。比如将全局属性的颜色,拷贝进顶点属性数组中,在着色器里使用顶点属性来访问全局颜色,这样就可以将不同全局颜色下绘制的对象缓冲在一起绘制。

1.3.3 帧间缓存技术

帧间缓存技术是将一次性的缓冲变为缓存储存起来,供多帧渲染的技术。当每帧之间绘制的物体基本不变时,帧间缓存技术可以大大加快每帧进行对象绘制信息缓冲的速度。可以对采用缓冲技术的一组物体进行缓存,但是当物体属性发生变化,或者物体的数量发生改变时,维护缓存将很复杂。所以帧间缓存一般用于拥有复杂渲染单元的单个物体。

1.4 WebGL-DMA

WebGL-DMA(以下简称WDMA)是为了加速零碎对象WebGL绘制而设计的绘制接口,主要解决了采用帧间缓存技术时,物体与缓存的对接和缓存数据的维护问题。WDMA由WebGL缓冲、属性缓存、物体缓冲和物体解释器和绘制器组成。

WDMA参考特定的Shader,得到Shader中的所有顶点属性输入,参考默认的更新频率、顶点属性位置,建立内部的WebGL缓冲和属性缓存。

WDMA缓冲分为WebGL缓冲和属性缓存,其中属性缓存中每个属性数组为Float32Array类型,并且大小指定,将在每次绘制之间维持,即对应一片内存空间。当实际物体数量将要超过当前的容量时,属性缓存会对每个数组申请一片更大的空间并复制;WebGL缓冲则存储了每个属性对应的glBuffer。按照属性更新频率的不同,活跃属性的glBuffer由WDMA在每帧绘制时载入属性缓存中的全部数据,而不活跃的属性则由物体解释器负责更新WebGL缓冲和属性缓存。不活跃属性的属性缓存仅仅是为了在扩大容量时复原glBuffer。

WDMA物体解释器是由特定的物体对象格式和Shader定义的,可以将某个类型物体信息更新至WDMA缓冲中的函数,也就是完成直接内存操作。因为WebGL某些绘制使用的顶点属性,并不需要被其他脚本使用,如果由物体自身的脚本计算,不仅计算量大,数据零碎而且有重复,每一帧还需要拷贝进顶点数组。物体解释器则可以直接把运算结果存储入WDMA缓冲中的指定位置,并且决定是否更新。同时,解释器还负责更新物体缓冲,决定需要绘制的对象。

WDMA物体缓冲存储了当前帧WDMA缓冲中的物体映射状态。每个对象在其第一次加入WDMA时,会获得一个当前空闲的索引号,并且一直维持到物体被标记为销毁,同时物体被存入相应的物体数组,而索引号被添加到物体上。每一帧当物体调用物体解释器时,物体解释器将索引号解释成绘制命令存入物体缓冲。

WDMA绘制器则使用drawElements函数将物体缓冲中的内容绘制出来。使用drawElements与drawArrays相比,可以降低维护属性缓存的开销,并且维持绘制顺序稳定性。

使用WDMA的限制是所有Uniform变量必须一致。为此在设计系统时,要使用常量属性化技术,然后按照其他输入(比如纹理)聚类,建立多个WDMA,绘制时依次设置Uniform变量绘制所有的WDMA。

图1 一个渲染Sprite对象的WebGL-DMA结构Fig.1 Structure of a sprite WebGL-DMA renderer

2 2D贴图绘制加速

2D贴图(sprite)绘制是指将图片的矩形区域画至画面中的指定矩形区域,是2D游戏绘制引擎最重要的一个部分。在Canvas2D中,2D贴图使用drawImage实现,其完整输入包括图片、源矩形、目标矩形,并且应用transform控制以实现平移和旋转等效果。这种绘制模式比较符合OpenGL类的绘制,因此在浏览器优化下,实际性能也相当出色。在典型的Canvas2D渲染系统中,脚本将针对每一个贴图,操作transform矩阵,然后执行drawImage指令,这样API调用的次数与贴图数量成正比。这种渲染方式不适用于WebGL。

2.1 基于WebGL-DMA的2D贴图绘制

为了解决WebGL绘制2D贴图的瓶颈,本文依据2D贴图的存储特点,改变了2D贴图的绘制方式。2D贴图对象常以中心点、旋转、缩放、纹理映射为主要属性,根据具体应用中贴图的属性的活跃程度,可以设计特定的Shader。文本使用的Shader的顶点属性输入为位置、偏移、纹理、颜色和旋转,其中位置为该顶点所属贴图的中心位置,偏移为顶点相对于中心位置的偏移量,而旋转是贴图的旋转角度。顶点着色器利用位置、偏移和旋转计算出该顶点的实际位置,可以减少JavaScript端的计算量。

图2 WebGL-DMA用于绘制贴图的顶点ShaderFig.2 Vertex-shader of WebGL-DMA sprite renderer

在初始化时,使用Shader建立WebGL-DMA。贴图对象储存了中心坐标、旋转角度、X轴和Y轴缩放比率、纹理坐标,在绘制时,贴图被传入WebGL-DMA,并且由贴图绘制器将贴图对象的属性依次拷贝至WebGL-DMA缓存中,最后调用WebGL-DMA绘制。

2.2 实验

实验采用在1600*900的Canvas中,随机位置绘制10000个32*32大小的贴图,并应用随机旋转。绘制分为初次绘制和重复绘制。采用帧间缓存的绘制方法初次绘制性能会差于重复绘制,但是考虑到实际应用很少同时新增大量对象,而且第一帧可以采用载入方式过渡,所以重复绘制性能的重要性要大于初次绘制。

除了Canvas2D贴图和WebGL-DMA的2D贴图以外,实验还加入了使用WebGL模拟Canvas2D的贴图接口的绘制方式,在这种方式中,每个贴图都会调用一次drawArrays,并使用旋转和缩放矩阵进行变形。

浏览器方面,采用Chrome和FireFox,其中Chrome有激活Canvas2D硬件加速的选项。硬件方面,CPU为四核Intel(R) Q9450@2.66 GHz,显卡为NVIDIA Quadro NVS 290,拥有8个通用流处理器。

表1 2D贴图绘制实验结果Tab.1 Sprite-rendering test result

使用传统软件Canvas2D绘制10000贴图时,绘制用时接近1秒,只能进行静态展示,无法互动。其主要开销为计算旋转和纹理缩放。如果取消旋转,并且将纹理大小与贴图大小统一,即进行像素对齐,可以大幅提升绘制性能,在浏览器启用硬件加速的情况下,可以基本满足互动性。考虑到除了绘制以外的开销,如果要求60FPS的刷新率,实际应用中往往只能做到渲染1000至2000个小型对象,并且无法应用旋转和缩放。

可以看到简单封装WebGL模拟Canvas2D的话,性能还不如普通的Canvas2D绘制。而使用WebGL-DMA的2D贴图绘制方法可以将重绘用时缩小至10ms以内,基本满足了60FPS所需要的16ms帧间间隔,而维护对象的开销要大于绘制对象的开销。在实际应用中,能做到以60FPS显示4000个动态对象。

3 2D线绘制加速

除了贴图,直线也是2D绘制比较多的对象。一些2D应用的模型以线为主,当模型数量众多时,画线的性能决定了系统的性能。线有两个重要属性是颜色和宽度,在传统绘制下,这两个属性存储在Canvas2D的状态机中。

3.1 基于缓冲的线绘制

使用WebGL可以把用户绘制的线缓存起来,结束时调用一次绘制指令全部绘制。为了能一次绘制更多的线,本文将线的颜色属性变为顶点属性,与顶点的位置一起缓冲。缓冲顶点时,也应用全局的坐标变换。当绘制结束,或者线宽发生变化时,将缓冲中所有的对象画出。这种绘制方式对输入没有限制,与之后的方法相比,可以随机输入。

3.2 基于WebGL-DMA的线绘制

当线作为对象的组成,对象在多次渲染间维持,WebGL-DMA就能起到作用。使用WebGL-DMA可以将对象与缓存关联起来,降低维护缓存的开销。

3.3 实验

实验采用的硬件环境与2.2相同,在1600*900的Canvas中随机绘制10000条随机颜色的线段,统计首次绘制和重复绘制的用时。

表2 2D线绘制实验结果Tab.2 Line-rendering test result

可以看出,采用缓冲加速的渲染性能和由浏览器带来的硬件加速Canvas2D相似,而采用WebGL-DMA后,重绘性能还可以提升一倍。其中WebGL-DMA初绘时间较长是因为使用的线解释器支持对绘制对象中使用多个线段情况的解释。

4 WebGL与Canvas2D混合绘制

当页面需要呈现较丰富的内容是,使用单一的Canvas难以满足需求[8]。混合绘制是指在一个页面上,同时使用多个Canvas进行绘制,以达到加速的目的。WebGL没有原生的文字绘制功能,需要使用Canvas2D绘制文字并转换成纹理,无法完全代替Canvas2D,因此使用WebGL加速Canvas2D绘制时,可以采用两层Canvas,将可以加速的交由WebGL绘制,文字和其他功能则还由Canvas2D绘制,最终将结果结合起来。以下介绍两种绘制的方式,可以适用于特定的情况。

图3 在屏混合绘制与离屏混合绘制Fig.3 On-screen layered rendering and off-screen layered rendering

4.1 在屏的混合绘制

在网页页面布局层垂直显示多个Canvas,使用z-index确定遮挡关系,再利用绝对位置定位。这种混合绘制的特点是对浏览器和硬件的要求低,并且多个Canvas可以独立设置渲染方式,兼容性较好。缺点是Canvas之间只能应用DOM渲染的特效,并且由于固定位置分辨率难以调整。

4.2 离屏的混合绘制

离屏混合绘制则是指在网页上只显示一个主Canvas,其他的Canvas离屏渲染,并且转换为纹理,最终绘制在主Canvas上,方便显示控制。Canvas中无论是2D还是3D绘制使用纹理的接口,都可以使用另一个Canvas作为纹理对象。在主Canvas使用WebGL的情况下,离屏Canvas还可以使用WebGL的FrameBuffer虚拟。在一个比较好的离屏混合绘制方案中,主Canvas使用WebGL,离屏Canvas则使用WebGL绘制图形、Canvas2D绘制文字。这样在调整分辨率时,只用调整主Canvas的尺寸,而WebGL的特性使得绘制的结果自然填满整个Canvas。并且在显示各个离屏Canvas时,可以应用各种特效。混合绘制的缺点则是需要额外的显示离屏Canvas的过程,如果浏览器不支持Canvas2D的硬件加速,会使Canvas2D对象转换为WebGL纹理的过程产生巨大开销,因此兼容性较难控制。

4.3 实际应用

本文研究并开发了一款网页弹幕游戏引擎JavaSTaGe[9]。STG游戏中的指玩家需要操作一个物体或角色,发射子弹击毁敌人,同时躲避敌人子弹的游戏。弹幕游戏是STG游戏的一类,通常是指平均子弹判定大小与玩家的判定大小相似或更大,场上子弹的数量众多,姿态各异,玩家需要快速反应并回避。由于对与画面的连续性,操作的敏感性要求很高,弹幕游戏的画面实际刷新率必须稳定在60Hz,并能够渲染上千的子弹。

JavaSTaGe引擎的设计原则是高度可编程。引擎本身并没有渲染器,只提供纹理管理系统,可以由游戏脚本指定渲染器和渲染流程。JavaSTaGe自带的游戏脚本使用了离屏混合绘制方式,将游戏背景、游戏场地、UI三层绘制在一个主Canvas中,因支持全屏模式,其中游戏背景为Canvas2D,只在变化时绘制一次;游戏场地为WebGL的Frame-Buffer,3D场地背景和2D角色与子弹等依次绘制在游戏场地中;UI为Canvas2D,由一个杂项渲染器绘制,主要负责绘制菜单、得分等文本信息。绘制2D与子弹的渲染器使用了WebGL-DMA技术,在保证所有物体的遮挡关系和绘制顺序的前提下,将所有同一层使用同一个纹理的贴图分配给一个WebGL-DMA对象渲染。在渲染流程复杂的同时,游戏开发者使用起来却相对简单,只要指定好对象所在的层和其render属性所属的渲染器及参数,将物体放入物体池中,引擎会自动找到相应的渲染流程并绘制到相应的场景中。

图4 在JavaSTaGe游戏引擎在浏览器中的实际运行效果Fig.4 JavaSTaGe game demo on Chrome

图3 为JavaSTaGe引擎的自带游戏脚本中,开启了3D背景和子弹对玩家的碰撞检测,以60FPS渲染4000个随机种类和颜色的子弹,所有的子弹都应用了触壁反弹并改变朝向的脚本。

除了绘制高度可编程,JavaSTaGe引擎还提供了一套完整的物理、音效、Replay、多人联机、手柄接口,达到甚至超越了常见桌面版STG脚本引擎的特性和性能。

5 总结

本文通过对Canvas中Canvas2D接口与WebGL接口的分析,提出了使用WebGL来加速Canvas中的2D绘制的思路和原理,指出几种能够减少WebGL的API调用的方法,并进一步设计了WebGL-DMA架构,用以加速大量对象的绘制。通过对比试验,证实使用WebGL缓冲技术可以实现与硬件加速Canvas2D相似的性能,而对于在多帧之间重复绘制的对象,引入WebGL-DMA可以在此基础上大幅增加重复绘制的性能。配合混合绘制技术,浏览器的Canvas应用可以达到接近以前桌面版应用的水准。如何进一步扩大WebGL加速的应用范围,以及优化数据管理,是未来Canvas高性能绘制的研究方向。

[1] 张玄, 黄蔚. 3D机房运维可视化系统的设计与实现[J]. 软件, 2016, 37(7). ZHANG X, HUANG W. Design and Implementation of 3D Data Room Opration and Maintenance Visualization System [J]. Software, 2016, 37(7). (in Chinese)

[2] Chen B, Xu Z. A framework for browser-based Multiplayer Online Games using WebGL and WebSocket[C]. Multimedia Technology (ICMT), 2011 International Conference on. IEEE, 2011: 471-474.

[3] Rost R J. OpenGL(R) Shading Language[J]. Paperd Labs, 2004, 6(2): 201-207.

[4] Khronos Group. OpenGL ES 2. 0 for the Web[OL]. [2016]. https://www.khronos.org/webgl/

[5] 田金琴, 丁红胜. 基于OpenGL程序设计的优化探讨[J]. 计算机系统应用, 2006, 10: 65-68 TIAN J Q, DING H SH. The research of optimization based on OpenGL program design [J]. Computer Systems & Applications, 2006, 10: 65-68. (in Chinese)

[6] Liu Q, Chi X. Similarities and differences between OpenGL and OpenGL ES[J]. Journal of Liaoning Technical University, 2008.

[7] Krzeminski M. OpenGL Batch Rendering[OL]. [2014]. http:// www.gamedev.net/page/resources/_/technical/opengl/openglbatch-rendering-r3900.

[8] 龚昊, 张琦. 数据中心三维可视化管理软件的设计与实现[J]. 软件, 2012, 33(11): 68-71. GONG H, ZHANG Q. The Design and Implementation of the 3D Visualization of Data Center Management[J]. Software, 2012, 33(11): 68-71. (in Chinese).

[9] 谢贤博. JavaSTaGe README. md[OL]. [2016]. https:// github. com/ExboCooope/JavaSTaGe/blob/master/README. Md.

Accelerated 2D Rendering for Canvas Element based on WebGL

XIE Xian-bo, NIE Yun, DENG Hong-yan, ZHANG Yu
(North China Institute of Computer Technology, Beijing 100083, China)

HTML5 introduced canvas element which significantly enhanced the graphic expressiveness of web pages. Two rendering context is based on Canvas element. Canvas 2D context is used for rendering 2D content. WebGL context is a subset of OpenGL-ES aiming at rendering 3d content with scripts directly controlling hardware. Canvas 2D context is simple to use but cannot handle massive 2D objects in time. This paper discusses about the practice of accelerating 2D drawings using WebGL based on buffering, uniform-attributifying, caching and direct-memory-accessing techniques. Experiments and example prove the efficiency of WebGL 2D acceleration.

Computer graphics; WebGL rendering; Design and implementation; High-performance rendering; HTML5

TP391.41

A

10.3969/j.issn.1003-6970.2016.12.031

谢贤博(1992-),男,研究生,计算机软件与应用;邓红艳,教授,空军指挥学院,研究方向:模拟仿真专业;张宇,工程师,中国电子设备系统工程公司研究所,研究方向:指挥自动化专业。

聂芸,高级工程师,主要研究方向:图形图像处理技术。

本文著录格式:谢贤博,聂芸. 基于WebGL的Canvas元素2D绘制加速[J]. 软件,2016,37(12):146-152

猜你喜欢

着色器浏览器顶点
过非等腰锐角三角形顶点和垂心的圆的性质及应用(下)
基于UE4 实时射线追踪技术的研究与探讨
基于Unity Shader石油泄漏现象模拟的研究
基于IMx6的opengl图形着色器开发研究
反浏览器指纹追踪
关于顶点染色的一个猜想
环球浏览器
基于可编程渲染管线的雷达图像分层模型设计与实现