下面是段原稿翻译:
Molehill是神马东东?
地球人都知道,我们即将在Adobe Flash Player和Adobe AIR中发布一套全新的基于ActionScript3的3D显卡加速API,那么Molehill是啥东东?没错!Molehill就是这套API的产品代号!有了这个家伙,Adobe Flash Platform就有了内置的高级3D渲染引擎了,内功突飞猛进啊!当然,想修炼3D渲染的功夫,光有决心不行,还得找几本秘籍练练,需要什么秘籍呢?如果您是Windows开发员,您需要DirectX9,如果您在MacOS或Linux下开发,您需要OpenGL 1.3。在Android这种移动平台上,Molehill得需要OpenGL ES2这本传说中的“移动版秘籍”。从技术上讲,Molehill这套API那可是真正的基于着色器的3D显卡可编程API!那些3D开发员在Flash里面找这玩意儿找了这么多年了(比如顶点着色器,比如像素着色器),现在终于可以让大家使用了! 有了Molehill,您就能使用很多传说中的旷世奇招,比如用GPU给骨骼动画使用顶点贴图,原生支持z缓冲,模板缓存,立方纹理等等等等。
要说到性能,现在的Flash Player 10.1可以在差不多30Hz的刷新率下渲染几千个非z缓冲的多边形,但是有了这套新的3D API,您可以在60Hz的刷新率外加高分辨率下,渲染数十万个z缓冲的多边形!Molehill可以在互联网上给用户带来体验精巧复杂的3D体验!
Molehill是怎么干活的?
现有的Flash Player里的这套2.5D的伪3D API是在Flash Player10中引进的,当然您还可以继续使用这套API,而Molehill这套API可以给您带来一个高级3D渲染解决方案,让你的显卡全力开火!当然了,您可以根据您的项目自行决定到底哪一套引擎更适合,具体问题具体分析嘛。
最近,我们在Flash Player 10.2里面引入了“Stage Video”的概念,Stage Video可以再Adobe Labs上下载,当前是beta测试版。
Stage Video和Molehill的设计是相同的,从解码到呈现,显卡可以全速渲染高清影像。在此之前,Flash Player可以显示列表中的视频帧或3D缓冲,但那是小打小闹,现在有了这个新的渲染模型,Flash Player就可以直接表现位于舞台后方的纹理中的内容了(舞台是GPU绘制的)!如此一来,Flash Player就可以直接把显存中的东西绘制到屏幕上了,从GPU中获取帧并显示到舞台上就不需要再从CPU的显示列表中重读内容了。
这样一来, 3D内容是在stage后面的,而且不属于显示对象列表(译者注:以前所有显示对象都放在stage中,构成显示对象列表),因此Context3D和Stage3D对象就不再是显示对象了。因此,您不能像操作DisplayObject对象那样设置旋转、混合模式(blendMode)、滤镜(filter)等属性了,显示对象的很多其他的效果也不能应用在3D内容上。
下面这张图就解释了这到底是怎么回事(译者注:下图中,Stage3D[0]和Stage3D[1]是在Flash2D Graphics的下面的,不属于传统的显示对象列表(Flash 2D Graphics代表传统的显示对象列表)。上面这段话的大意就是告诉大家,新的3D对象不同于传统的显示对象(DisplayObject及其子类),传统显示对象的那些东西在3D对象上已经不能适用了)
当然了,您也看到了,2D内容可以很好的融合3D内容,但是反过来让3D内容融合2D内容却是不允许的。尽管如此,我们提供了一个API,可以让大家把3D内容绘制到BitmapData中。从ActionScript API的立场看,作为一个开发者,你操作两个主要的对象:一个Stage3D对象,一个Context3D对象。如果你向Flash Player请求一个3D场景,Flash Player就会给你创建一个Context3D对象。那位说了,要是显卡不兼容怎么办?会不会有一个黑屏悄悄地从天而降呢?
当然不会!就算显卡不兼容,Flash Player也会给你返回一个Context3D对象,但这个Context3D对象可就不是用显卡渲染出来的,那用什么渲染?没办法,用软加速的方法渲染(也就是用CPU),所以就算显卡不兼容,你也可以让CPU来运行Molehill的功能。这种情况下,想要达到比较好的效果,我们就得用TransGaming公司的“SwiftShader”了,SwiftShader是一个高性能的CPU模拟光栅渲染器(译者注:SwiftShader是用CPU来计算数据,模拟完成显卡光栅渲染器渲染的一套软件引擎,这样,即使显卡没有光栅渲染器,也可以用CPU渲染出来光栅渲染器的效果了,比如著名Crysis中就有大量光栅渲染器支持的效果,朋友们可以到http://transgaming.com/business/swiftshader 查看具体的介绍)。有一条好消息,就算使用软件加速模拟,SwiftShader速度也比现在的向量光栅器(Vector Rasterizer)快10倍!因此用软件加速的模式也可以获得大幅度的性能提升。
Molehill的动人之处还在于,你不需要关心其内部如何运作。我在运行DirectX还是OpenGL?或者是SwfitShader?要是我在MacOS和Linux上开发,我是不是要使用专门为OpenGL设计的API?要是我在移动设备上开发,是不是要使用专门为OpenES2设计的API呢?答案是:No!所有事情对你来说都是透明的,作为一个开发人员,只需要用一套API编写程序,Flash Player会在内部帮你处理这些兼容问题,在幕后把你的程序转换成正确的可执行的代码。
有一点很重要,Molehill的API不使用Fixed Pipeline,它只使用Programmable Pipeline(译者注:从名字我们也可以看出,FP固定,比较简单,但是不够灵活,PP可编程,比较灵活但是编程代价提高,具体大家可以baidu,google一下)。这就意味着,要想在屏幕上显示内容,你要自己处理顶点着色器和像素着色器。因此,你可以把你的着色器作为一个底层的AGAL(“Adobe Graphics Aseembly Language”)字节码传递给显卡,而这段字节码是作为一个ByteArray对象传递的。作为一个开发员,你有两种方法来做这件事:第一,在汇编语言的层次自己写着色器,这需要你对着色器的工作方式有深入的理解。第二,用一门高级语言来完成着色器,例如PixelBender3D,PixcelBender3D可以提供更更接近自然语言的编程方法并且把你的程序编译成适合的AGAL字节码。
要表现你的多边形,你要使用VertexBuffer3D和IndexBuffer3D对象,分别向这两种对象中传递坐标和索引,准备好顶点着色器和像素着色器后,你就可以用Program3D对象把两者传递到显卡中了。基本思路就是,一个顶点着色器处理绘制多边形所用到的那些顶点的坐标,而用像素着色器处理多边形纹理的像素外观。
下图描述了两种着色器的不同之处:
(注:大致意思就是告诉我们,用顶点坐标确定物体的空间轮廓(由点连线),然后用像素着色器像上面贴图,表现物体的外观)
如前所述,Molehill不使用Fiexed Function Pipeline,这样,开发者就可以自由的构造自定义的着色器,并且可以完全控制渲染管线。
最后了解一下关于GPU对flash开发人员的惊喜之处:
GPU是令人恐怖和复杂的!
这当然只是我还没接触它们之前的想法.不过使用GPU编写高性能的3D渲染器需要一些技巧和数学基础确实事实.但对现代GPU的描述却可以很简单:
- GPU画三角形的速度很快,真的很快!
- GPU处理简单的矩阵和向量的速度很快,真的很快!
- 告诉GPU如何使用这些能力完全由你决定.
总之,现代GPU能够很高效的绘制三角形和进行某些特定的数学算法.这个速度是Flash式的渲染望尘莫及的,你不需要编写像管理显示列表那样的代码来处理当物体改变时所导致的更新.因为即使在你的视角或镜头前一个小小的改变都意味着你屏幕中所有对象的位置相对你的视角都需要发生改变(原文:Since even a tiny change in your camera location or viewing angle means that all of the objects in your world are in slightly different places on the screen and with slightly different perspective relative to your view),你通常需要在每一帧刷新中告诉GPU重绘屏幕中的所有对象(当然,你可以选择性的更新其中的一些对象来保持一个高帧频,但是从归根结底你需要处理比在基于CPU-2D世界多得多的事情.
这又什么大不了的?我也可以快速绘制一个三角形(指用CPU)
GPU真正的能力在于你用何种方式告诉它来绘制这些三角形和给定的数学运算.从概念上讲,该模型(MoleHill"只"(未验证)支持可编程的GPU)并不复杂,这就是MoleHill API只有为数不多的几个方法的原因.如果想高效的使用该模型那么处理事情可能会比较复杂,我们将会在以后看到.
这里列出了用一个可编程的GPU来完成一个标准的3D渲染的梗概.在每一帧中:
- 三角形(Triangles).传给GPU一大群三角形,这些三角形是用他们的顶点(vertices),除此之外还有与之关联如纹理坐标(用来将纹理位图的顶点指定到相应的位置)的数据来表示的.
- 纹理,材质(Textures).传给GPU很多用来填充纹理中的三角形的位图(在第四步会用到)
- 顶点着色器(Vertex shader).上传一个"顶点着色器"单元,为每个来自第一步的顶点进行某些数学运算来确定最终顶点位置,以及其他一些可选的输出.
- 片段着色器(Fragment shader).上传一个"片段着色器(或者成为像素着色器)"单元.GPU在每个三角形顶点之间进行一些内置的数学运算然后调用像素着色器处理三角形的每个像素.你的着色器在每个像素上进行某种数学运算.访问第二步提供的纹理是必要的,因为片段着色器需要知道它渲染的颜色需要什么颜色.
- Z-缓存(Z-buffer).GPU为每个像素存储了其Z轴深度.如果来自一个新的三角形的像素的坐标位于最后那个位于相同坐标(x,y轴判断)上的像素后面(z轴判断),GPU将不绘制该像素.
- 重复.每帧按需要重复执行上述步骤.
- 呈现(Present).一旦在一帧中完成了上述工作,你需要将GPU处理的数据重新往屏幕上绘制.并且呈现给用户.现在你准备清楚这些数据并且在下一帧重复这些.