WebGL 框架 API 横向评测 (Part 1)
对于互联网来说,除了HTML5和CSS3之外,WebGL也是一项最有前途的正在进化的技术之一。从简单的模型查看器到复杂的3D场景,由OpenGL ES驱动的网页结合CSS3和视频纹理也许会成为下一代互联网网页的主流。由于应用广泛,富WebGL应用程序必须易于搭建和渲染,缩短响应时间,提供更好的可扩展性。这正是当前对于这些WebGL框架来说最为迫切的需求。
在撰写本文的时候,没有任何一个框架是完美的,但是他们中的一些都非常有前途。不断改进这些框架将成为WebGL普及的楔石。
本文对于WebGL框架的评测将主要侧重于软件工程质量、命名约定、附加特性和不足之处。评测中将不会涉及到框架的性能和效率。
本文中提及的所有框架的作者都投入了辛勤的汗水和努力,其中的一些已经可以制作出相当好的示例。我相信针对这些框架所提出的在软件工程设计上的各种缺点和问题将有助于他们改进框架API,并在未来对于框架的普及和提高欢迎度有所帮助。所以本文会稍显尖锐。
C3DL
这个框架上次更新是在一年前了(也就是2011年6月左右)。这是一个面向对象的框架,文档也配备齐全。因为大量的set方法和get方法,应用的源代码量可能会出乎意料(也没有必要)的大,并且其中没有数组映射(C中的数据结构)。orbit方法只针对于场景类,而那里并不需要这个方法,应该被移到一个单独的类中。这个框架还没有提供场景文件的解析器。
效果类应该被重命名为renderer(渲染器),或者应该是shader program的一部分。从软件工程角度来讲,场景类设计的非常糟糕:背景颜色这个选项逻辑上不应该是场景的一个组成部分,应该被移到renderer中;环境光选项应该被移到光源类中。C3DL的场景只支持一个摄像机,并且只维护一个模型清单,其中的模型无法按照层次等级分类。
摄像机支持FOV、zNear和zFar,但缺失方法去自动计算透视投影和正交投影,这样特殊的一个摄像机(透视投影摄像机或正交投影摄像机)应当和场景一起被传递到或者绑定到renderer上。
基元设置选项,比如VBO(Vertex Buffer Object)、材质和法线都是只读的,不能设置。每个基元都设计成一个单独的类,这是一个代价相当高的决定,因为一个物件通常会含有大量的基元,比如线和点。然后,多边形呢?C3DL没有多边形?
光照支持环境光、漫反射光和镜面反射光,但找不到高级设置选项。材质类中可以设置环境光、漫反射光、镜面反射光、光泽度和自发光,但是没有shader。
框架中的效果支持卡通效果、Gooch效果、灰度效果、Sepia效果和标准效果。就像刚才说的,他们应该被整合到shader program或者一个专门的renderer中,比如CartoonRenderer。
结论:非常基本的支持度;上次更新是一年之前;从软件工程角度考虑,一些东西应当被重新设计。
Curve3D
这个框架没有文档,在github上只能找到源码。谁会使用一个不知道类和方法是用来干什么的并且怎么用的框架呢?这对于创建复杂场景的应用来说是最基本的一点。
这个框架的开发工作实际上从两年前(上一次commit)就停止了。
类实体没有分配给场景或渲染器(renderer),它更像是一个过程编程和面对对象编程的混合体,所以使用这套框架可能会造成非常混乱的代码结构。
结论:这套框架应该被整个推翻重做,但是开发已经在一年多之前就停止了。
CubicVR 3D
这套框架拥有前瞻性很强的示例、非常实用的教程和很好的文档,另外基本的数学库也包括在内,使用这套API不是什么难事。它使用了面对对象编程方法,并结合了数组映射对象作为参数,这样就会有相当清晰的代码结构而不是一大堆set和get方法。但是数据成员都是公有的,这是一个相当致命的地方:公有数据成员的名字和含义应当很少改变(又一个软件工程学上的不良示例)。
这个框架不能完整支持动画、物理、曲线和自定义渲染器(顺便说一下,大部分WebGL框架都不支持自定义渲染器)
光照:支持点光源、平行光、聚光灯和区域光。可以是动态的或静态的。其他选项例如位置、方向、漫反射、镜面反射、光照强度、距离和截断。对于大部分应用来说,光照方面支持的都很好。
场景支持八叉树以增强性能,同时支持包围盒射线测试。每个场景实体都有一个可选的天空盒。通过绑定子对象可以实现场景中模型的等级层次分类——一个模型可以同时拥有一个AABB(轴对齐包围盒)和多个材质,这个一个符合逻辑的正常决定。Mesh(网格)可以用于Catmull-Clark Subdivision细分曲面。
渲染支持自定义shader,shader会被组织在被绑定在渲染器上的“后处理链”中。另外也有用于VBO的render buffer来提高性能。
然而,有一个叫做“Envelope”(信封)的类,是用来创建和求值简单或复杂的曲线的,实在搞不懂为什么叫这么个名字——强烈建议重命名。
动画类相对就有些不是很完整了,所以这里也需要重做:一个好的动画系统应当使用路径(Paths)、限制(Constrains)、前向动力学和反向动力学系统(FK \ IK Solvers)。另外还有一点就是其中缺少好的动画系统中必备的曲线类(Curve)。
可以支持一些基本的物理,但是不幸的是文档对于物理类缺乏细节介绍和解释,但是给出的示例很好。支持刚体,并且有很好的示范示例。但是其中一个示例明显可以看出物理系统的抖动问题,这是一个相当清晰的标志,那就是刚体处理中存在大量的不稳定问题。对于更加复杂的动画来说单独的物理解决器(牛顿、前向动力学和反向动力学系统)应该是个非常好的主意。碰撞检测使用了碰撞映射,还有AABB和射线检测。
渲染器支持带alpha透明度和区域光的阴影,但是对于中低端设备上的实时渲染来说,计算结果有一些问题。
框架提供了更多的工具比如事件和事件的handler、计时器、转换类、shader类和四元数类,后者未被列入文档。还有枚举结构“平截头体”(注意不是所有的WebGL框架都有的)。基本的数学模块应当扩展一下,增加更多的方法来转换矩阵和四元数表达式。
有一个名字叫“RigidVehicle”的专门的类,不应该成为框架的一部分。“ScenePhysics”类应当被重命名,并分割成两个独立部分来分别处理限制(constraints)和场景模型。八叉树可以在寻找场景模型时提升性能,因此应当有一个专门的场景表达式。通常来说,其他API不应该知道场景中的物体在内部是如何储存的,所以应该有一个使用普通场景接口的场景类的继承链。比如说Scene、OctreeScene等等。“Landscape”类有点太专业了,应当被移到一个单独工具集里或者作为插件。另外作为一个好的图形框架,还缺乏Mesh(网格)的继承链和不同Mesh之间的表达式的转换。
结论:一个非常有前景的框架,架构设计的非常好,应用的代码结构非常清晰。支持从基本的数学工具到shader、Collada、基本的物理系统和一些动画特性。另外还配备非常实用的教程、很好的演示示例和文档——但是框架的源代码中没有文档说明和注释!物理和动画部分还有很多需要改进的地方,以增强稳定性。更多的高级效果,比如雾和水等等都还没有,但是可以使用自定义shader制作出这些效果。对于大多数用户来说,预置的shader program会非常好用。
(未完待续)
转载自: http://weblog.benjaminsommer.com/blog/2012/05/13/comparison-of-webgl-framework-apis/
作者:Benjamin Sommer
HiWebGL翻译整理,转载请注明出处