Flash Stage3D 学习笔记(一)
本文参考来源: http://www.adobe.com/devnet/flashplayer/articles/how-stage3d-works.html http://www.ashan.org/post-267.html http://www.pixelbender.cn/?p=381 ? 1.Stage3D简介 Stage3D是Adobe为了提高的Flash?3D应用程序渲染性能而开发的项目,之前代号为MoleHill。由于Stage3D能够直接调用底层的GPU,因此大幅度提高了3D渲染速度和性能,同时兼具Flash?Player跨平台的特性,可以在Windows,MacOS,Android,iOS等平台上得到广泛的应用。目前很多第三方的Flash?3D引擎都加入了对Stage3D的支持,极大的提高了Flash?3D应用程序的运行效率。很多2D的Flash游戏,想利用Stage3D来进行硬件加速从而提高运行效率,大都采用第三方的2D引擎Starling。如果想开发纯3D的Flash游戏,推荐使用Away3D,据报道Adobe已经为Away3D注资,因此我们有必要关注跟踪这个3D引擎。 图1?Stage3D层级结构 Stage3D使用了AGAL语言,这是Adobe开发出来的图形汇编语言,同时在调用的时候遵循3D图形渲染的过程,因此Stage3D的使用是有一定难度的,这也是第三方的3D引擎封装它的原因之一。我们先来看一下Stage3D在Flash?Player中的位置, 图2?Stage3D在舞台上的位置 图中的最右边的Stage层是Flash?Player显示列表中我们目前应用的最底层容器,而Stage3D层则还在Stage层的下面,换句话来说,Stage3D上面的3D对象可能会被Stage层遮住,当然Stage层是透明的。所有的Stage3D层都是不透明的,都可以设定自身的大小,这意味着它们可以被层层遮盖,但是如果各自的大小不同,则可能同时展现在屏幕的各个部分,有点类似电视上的分屏效果。在最底层则是StageVideo层,是留给硬件加速视频对象(区别于普通的Video对象)用的,这也意味着硬件加速视频层极易被遮住。目前Stage3D层默认的只有4个,从Stage[0]到Stage3D[3],一般我们只用到Stage3D[0]就可以了。 ? 2.3D渲染的基本概念 这里先简单的说一下3D渲染的过程,弄清楚这个过程对我们使用Stage3D大有裨益。3D渲染包括3个方面,一是被渲染的物体本身,二是灯光,三是视角。想象一下在一个封闭的房子里面,有个角落有一束阳光照射进来,观察者是处在正面还是侧面,上面还是下面,所看到的画面是不一样的,因此灯光和视角会决定最终渲染出来的画面。被渲染物体的本身则包括它的轮廓也就是几何形体,以及它的颜色或材质这两方面。现在我们来看看GPU具体是怎样处理这个渲染过程的,图3为固定管道(pipeline)的渲染过程, 图3?GPU渲染固定管道 (1)?Transformation?and?lighting:?转换和灯光处理 (2)?Triangle?Assemble:?以三个点作为一个三角形为单元进行组合 (3)?Viewpot:?根据视图端口进行裁剪获取范围 (4)?Rasterizer:?将渲染的几何体进行栅格化 (5)?Texture?Stages:?将栅格化的格子进行材质贴图 (6)?Frame?Buffer:?帧缓冲,最终生成图片 上面是固定管道的渲染过程,目前GPU也支持程序化管道渲染过程, 图4?GPU程序管道渲染 整个渲染过程可以通过程序操控,与图3相比,第一步的转换与灯光直接变成了顶点着色,第五步的材质贴图变成了片段着色。可编程的渲染管道就是将顶点着色VertexShader和片段着色FragmentShader这两个开放给程序员,让他们自由发挥。下面的图更直观的展现了渲染过程, 图5?GPU渲染示例 通过上面的讨论,渲染过程最关键的几步包括,一是几何体顶点或端点的输入,二是以三角形为单元形成待渲染的面,三是栅格化处理,将待渲染的面分成一堆小格子,四是对格子逐个进行着色渲染,可以是颜色,也可以材质。这里最重要的是GPU一定是以三角形为单元进行渲染处理的,也就是说所有的几何形体,包括四边形,也是被分成三角形来处理的。渲染的基本要素是顶点和着色两部分,三个顶点形成一个面,一旦顶点和面进行了着色处理,渲染的物体就展现出来了。 ? 3.Stage3D的调用过程 (1)首先需要取得Stage3D对象和Context3D对象,这是待显示渲染的容器,类似于画布。 var stage3D:Stage3D = stage.stage3Ds[0]; context3D = stage.stage3Ds[0].context3D; 实际上需要监听Stage3D的Event.CONTEXT3D_CREATE事件后才能获得Context3D,这里省略一下,让过程更清晰些。 ? (2)其次创建与顶点相关的两个缓冲buffer, VertexBuffer:所有待渲染的顶点的集合 IndexBuffer:具体渲染时顶点的顺序集合,会以三个点为单元进行自动分割 VertexBuffer创建过程, var vertices:Vector.<Number> = Vector.<Number>( [ -0.3,-0.3,1,// x,y,z,r,g,b -0.3,0.3,0]); // 4 vertices,of 6 Numbers each vertexbuffer = context3D.createVertexBuffer(4,6); // offset 0,4 vertices vertexbuffer.uploadFromVector(vertices,4); IndexBuffer创建过程, var indices:Vector.<uint> = Vector.<uint>([0,2,3,0]); // total of 6 indices. 2 triangles by 3 vertices each indexBuffer = context3D.createIndexBuffer(6); // offset 0,count 6 indexBuffer.uploadFromVector (indices,6); 上面的VertexBuffer里面包含4个顶点,每个顶点含有位置x,z和颜色值r,b,然后IndexBuffer取其中的0,2和2,0两种组合,也就是4个顶点变成了两个三角形,供GPU进行渲染。 ? (3)最后就差着色这一步了。着色分为顶点着色和片段着色两种,这里就要用到AGAL语言了。 顶点着色过程, // compile vertex shader var vertexShader:Array = [ "m44 op,va0,vc",// 4x4 matrix transform from va0 and vc0 to output position "mov v0,va1" // copy rgb color from va1 to v0 ]; var vertexAssembler:AGALMiniAssembler = new AGALMiniAssembler(); vertexAssembler.assemble(Context3DProgramType.VERTEX,vertexShader.join("n")); 片段着色过程, // compile fragment shader var fragmentShader:Array = ["mov oc,v0"]; var fragmentAssembler:AGALMiniAssembler = new AGALMiniAssembler(); fragmentAssembler.assemble(flash.display3D.Context3DProgramType.FRAGMENT,fragmentShader.join("n")); 这里的着色过程开始看到AGAL汇编语言了,一定要经过AGALMiniAssembler进行转换成机器码,才能被GPU执行。 ? (4)最终启动执行,Program3D登场亮相, program3D = context3D.createProgram(); program3D.upload( vertexShaderAssembler.agalcode,fragmentShaderAssembler.agalcode); // vertex position to attribute register 0 context3D.setVertexBufferAt (0,vertexbuffer,Context3DVertexBufferFormat.FLOAT_3); // color to attribute register 1 context3D.setVertexBufferAt(1,Context3DVertexBufferFormat.FLOAT_3); // assign shader program context3D.setProgram(program3D); context3D.drawTriangles(indexBuffer); //根据顶点索引缓冲绘制三角形 context3D.present(); //渲染展示 到现在为止,Stage3D调用过程就完结了。这样一路看下来,好像很简单,其实还是比较复杂的,如果我们不清楚3D渲染过程,直接上Stage3D的调用代码,那将是让人非常痛苦的过程。这样看下来,Stage3D的代码很多,做的事情却很少,最终只能看到一个四边形。因此我们需要深入下去,才能更好掌握Stage3D。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 使用fetch代替传统的Ajax
- 正则表达式 – 正则表达式生成器/还原器?
- React Native探索(三)组件的Props(属性)和State(状态)
- ios – 使用NSDateFormatter设置UIDatePicker日期
- CGO,如何将NULL参数传递给C函数
- 《swift2.0 官方教程中文版》 第2章-13继承
- dojo 1.6 官方教程:dojo.Deferred 初探
- uiview – 如何在swift中将背景图像设置为colorWithPattern
- Backup Exec 16中配置Oracle备份
- ruby-on-rails – 在Windows上通过代理安装rails bundle