http://blog.csdn.net/klarclm/article/details/7381426
# WebGL及在WebKit和Chromium中的实现
## 概述
前面章节介绍了Canvas2D,同时也介绍了在canvas中同样也可以绘制3D图形,也就是Canvas3D或者称为WebGL。同Canvas2D不一样的是,WebGL标准草案不是由W3C来起草的,而是Khronos组织来负责的,目前很多浏览器支持WebGL,例如Firefox, Chrome, Safari(仅限Mac平台)和Opera 。但是,微软以安全性为由拒绝在IE中支持WebGL,虽然它支持Canvas2D。
WebGL很热,自从诞生以来就备受关注,想知道WebGL有多酷,你可以查看参考文献1看看Google为大家制作的一些很棒的示例,看看网页中如何显示3D图形,相信你可以借此进一步了解它的魅力。
那么WebGL到底是何方神圣呢?根据官方标准中的说法,”WebGL是一套为Web设计的基于立即模型绘制3D的API。” 它来源于OpenGL ES2.0,提供了相似的3D绘图功能,只不过它运行在HTML网页中,简单上来理解, 你可以把它看成OpenGLES 2.0的JavaScript绑定,网页的开发者可以利用它来在网页中显示3D图形。WebGL定义的是一个被HTML Canvas元素创建(同样通过getContext)的用来3D渲染的上下文接口。
前面一章在介绍Canvas 2D的时候,曾经介绍过一个简单的例子,该例子是把canvas区域填充满红色。下面看一个WebGL的简单例子,功能一样, 把canvas区域填充满红色。
上图示例代码包含一个Canvas元素和一段JavaScript代码。根据以前的介绍,你应该已经知道,第5行是获得canvas元素的DOM节点对象,第6行代码通过传入“experimental-webgl”参数让该节点对象创建一个3D的上下文对象,之后就可以利用该上下文对象绘制3D图形。第7行设置用于下一行的颜色,格式为RGBA,。最后一行将之前设置的颜色填充到颜色缓冲区中(对应于canvas的后端缓冲区之一),从而将canvas区域设置为红色。
同Canvas2D类似地,Canvas元素提供了绘制的场所,WebGL则提供了绘制3D内容的上下文类- WebGLRenderingContext,下面将对其详细介绍。与Canvas 2D不同的是,WebGL没有软件渲染和硬件加速两种模式,它仅在硬件加速开启的情况下才能运行,因为它依赖于3D的图形库。
根据WebGL规范中的描述,下面来介绍一下它的几个主要部分:
上下文及内容展示:在使用WebGL的API之前,需要获取WebGLRenderingContext和DrawingBuffer(Chromium需要它)。对JavaScript来说,GL的操作都是由WebGLRenderingContext来负责完成。但是, DrawingBuffer对用户来说是透明的,它是用来存储渲染的内容并被合成器所合成,它包括帧缓冲器对象(绘制的结果存储)和纹理对象(纹理被合成器所使用)。
WebGL的资源及其生命周期:textures,buffers (i.e., VBOs), framebuffers, renderbuffers, shaders and programs。它们有对应的JavaScript对象WebGLObject对应,它们的生命周期是一致的。
安全:为保证安全性,它要求:1,所有的WebGL资源必须包含初始化的数据;2,来源安全性,为防止信息泄露,当canvas的属性’origin-clean’为false时, readPixels将会抛出安全方面的异常。3,要求所有的着色语言必须符合OpenGL ES shading language 1.0; 4, 为防止DoS攻击,建议采取适当的措施对花费时间过长的渲染操作过程进行监控和限制。
WebGL接口:主要包括各种资源类的接口和上下文类的接口,用于绘制3D的操作,这些API基本上来源于OpenGL ES 2.0.
WebGL与OpenGLES 2.0的区别:这里不再一一介绍,读者可以自行翻阅和了解相关细节。
想要了解你的浏览器对WebGL支持的详细情况,请访问http://webglreport.sourceforge.net/获取详细参数。
## WebGL的渲染过程
在这一部分将介绍WebGL如何被渲染以及如何被合成器合成的,大致的过程如下图所示。先解释以下图中的5个模块。WebGL 模块是指WebKit和Chromium中为支持WebGL而引入的基础设施。“GL 3D context used by WebGL”是GPU进程中为支持WebGL创建的GLES的实际的3D上下文对象。 CC模块是chromiumcompositor,就是合成器。“GL 3D context used by compositor”是GPU进程中为网页合成而创建的3D上下文对象。
第一步,当JavaScript的代码通过HTML Canvas对象创建3D上下文时,WebGL模块便为其创建一个绘制3D图形用的上下文对象,该对象在GPU进程中会有一个实际的OpenGL ES的上下文对象对应。同时,DrawingBuffer对象也会被创建。
第二步,DrawingBuffer会同时创建了一个帧缓冲区对象,用于存储该WebGL绘制的内容,同时获取用于合成的纹理对象,WebGL模块会获取这些对象的ID信息。
第三步,JavaScript的调用上下文对象的绘制图形代码被V8解析后,利用V8的绑定机制,会调用相应的WebGLRenderingContext对象的Callback函数,这些函数把它们转换成内部的Commands, 通过IPC机制传给GPU进程,GPU进程在之前创建好的上下文对象,完成实际的绘制工作。在这过程中,有两点值得关注,第一,很多命令需要同步,这会有很大的开销,第二,很多情况下,JavaScript需要操作各种图片资源,所以需要将它们共享给GPU进程,同时将它们上载到GPU的内存,因而开销比较大。
第四步,GPU进程执行renderer进程发送过来的命令,调用GL库函数把计算结果内容更新存储到帧缓冲区中,前面这四步在解析JavaScript时,同时执行。之后,它会调度一个任务,请求更新一个矩形区域(同viewport大小)。
第五步,从这步开始,合成器发起合成,当由任何变化或者更新网页的请求时都会触发它。合成器要求每层去更新自己的发生变化的部分,这需要尽可能的快,以避免大幅地影响一次网页的绘制工作。WebGL此时会准备绘制内容或者更新内容到帧缓冲区中,同时把内容拷贝到纹理对象中去,以备合成器所使用。
第六步和第七步,因为WebGL的纹理对象是在这些GL的上下文对象中共享的,WebGL模块切换到合成器的上下文对象环境中,将它的纹理对象根据变换绘制到该环境中的帧缓冲区中去,完成对该层的合成。
第八步,当所有层次的绘制完成后,最后一步就是交换前后端的缓冲区,来显示合成完的内容。
## WebKit和Chromium基础设施
前面介绍了WebGL如何渲染的过程,那么WebGL模块在WebKit和Chromium中包含哪些相关的重要类来支持的呢?如下图所示,里面包括了一些主要的WebGL模块类。
HTMLCanvasElement:它是起点,是DOM中表示Canvas元素的类。如Canvas2D类似,当传入‘webgl’到它的方法getContext时,WebGLRenderingContext对象就会被创建。
WebGLRenderingContext:JavaScript中的3D操作基本上都是由该类来处理,也就是说该类其实是JavaScript和GL实现的桥梁。在WebGLRenderingContext创建的同时,DrawingBuffer也同时被创建,但是目前只有chromium中会创建它。
DrawingBuffer: 表示规范中的DrawingBuffer,在WebKit的chromium移植中,DrawingBuffer会创建绘制用的Chromium的3D上下文对象和所需要的buffer, 这些buffer最后会被CC的CCCanvasLayerImpl使用。
GraphicsContext3D: WebKit中用于绘制3D图形的上下文基础类,其对图形的绘制接口都是对该类的调用,具体需要各个移植的实现。
GraphicsContext3DPrivate,WebGraphicsContext3D: Chromium中的具体3D图形上下文的具体实现的两个辅助类。WebGraphicsContext3D是一个chromium平台的基类,其子类可以是In-Process的3D绘图上下文实现类,也可以是out-of-process的3D绘图上下文实现类。
PlatformLayer,WebGLLayerChromium:平台相关的用于表示各个移植中的,其可以将绘制好的buffer,发布到平台相关的层次上。
CCCanvasLayerImpl:CC中的用于表示canvaslayer的类,其来具体完成平台层的绘制请求,并将它们的结果内容会知道合成器的结果中。
## 源文件目录
WebKit/Source/WebCore/html/canvas/
WebKit支持Canvas相关的类,包括支持2D和3D上下文及其所涉及的其他类
WebKit/Source/WebCore/platform/graphics/chromium
Chromium的DrawingBuffer支持,3D上下文,及其为合成WebGL所涉及的类
http://blog.csdn.net/cnwarden/article/details/4598095
背景
News:WebGL标准让网页能用3D硬件加速进行渲染,上周[2009年9月19日]Safari和Google Chrome浏览器使用的渲染引擎WebKit,初步加入了WebGL支持。另一个开源浏览器Firefox不想让WebKit独秀,它最新的Nightly Build预览版同样加入了WebGL支持。
什么是WebGL
Web+GL 这二者相加的结果是一整套针对浏览器的3D图形硬件加速解决方案,类似于Google O3D[http://code.google.com/apis/o3d/],后者是 Google为了丰富网页的3D体验(整合进Chrome浏览器)而开发的Open-Source图形硬件加速技术。WebGL的主要发展方向是整合JavaScript和OpenGL ES 2.0,而JavaScript将成为其主要的瓶颈,它无法高效的处理大量的数据运算。当然这些仅仅是以目前的条件来分析,相信不久的将来针对于运算效率的问题将会有很大改善。现在在WebKit中已经加入了WebGL的支持,可以checkout出来看一下testcase:svn co http://svn.webkit.org/repository/webkit/trunk/WebCore/manual-tests/webgl webgl,前提是你已经安装了SVN了。
为什么是WebGL
优势:
1.无需插件,直接支持3D图形的GPU硬件加速。
2.开放性,Adobe Flash 10、微软Silverlight 3.0也都已经支持GPU加速,但它们都是私有的、不透明的。
3.WebGL可以为HTML5 Canvas提供硬件3D加速渲染,在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。
劣势:
1.因为OpenGL ES 2.0并没有被大多数的硬件平台所支持,所以将会导致很多设备无法运行WebGL。
2.因为OpenGL ES 2.0对JavaScript的依赖程度达到了100%,其利用JavaScript来处理应用程序的场景绘图,应用会因为JavaScript的计算瓶颈而受到不同程度的限制。
3.WebGL并没有积极的去解决数据导入问题。目前为止,仅仅可以利用IMG tags来嵌入材质信息,暂不支持DXT图片压缩格式(而DXT已经被大多数的3D显卡硬件所支持)。
4.统一?苹果和Google都是Khronos Group组织的成员,因此他们的Safari、Chrome等WebKit核心浏览器获得这种3D GPU加速特性应该是水到渠成的了,但是Mozilla、Opera虽然在核心引擎上走的是另一条路,但也积极支持创建3D Web图形开放标准,IE的支持性还不清楚。
WebGL是鸡肋吗?
先看一张效果图:TestCase中的Earth
未来遇到实际问题时,都是要根据实际情况来选择适用的解决方案。在这里没有谁有压倒性的优势,都各有利弊。对于开发者来讲,追求效率的同时,可以在要求不够严格的情况下选择最易上手的工具,缩短开发周期。
## 参考文献
1. WebGL demos: http://www.chromeexperiments.com/webgl
2. WebGL Spec https://www.khronos.org/registry/webgl/specs/1.0/
3. WebGL Report for browser: http://webglreport.sourceforge.net/
4. OpenGL ES2.0 http://www.khronos.org/opengles/sdk/docs/man/