首页 > 代码库 > Stage3D学习笔记(七):动态纹理

Stage3D学习笔记(七):动态纹理

本章用来作为Starling的滤镜实现原理的一个补充,但是为了了解原理,我们会使用原生API进行编码。

我们知道,当我们调用drawTriangles方法时,我们的图像是绘制到后台缓冲区的,只有调用present方法时才会把图像呈现到屏幕。

我们先来看看Context3D的两个方法:

  1. setRenderToTexture:我们默认的渲染都是在后台缓冲区进行的,使用该方法可以把渲染修改到一个纹理上,调用该方法后,Context3D对象的渲染操作(clear、drawTriangles等)都会渲染到指定的纹理上而不是后台缓冲区。
  2. setRenderToBackBuffer:配合setRenderToTexture的方法,可以将使用的缓冲区还原到后台缓冲区。

 

如果本章看不明白可以看这篇文章进行补充:stage3D 搭建2d图形引擎 (八) 动态纹理

 

先想一下我们的渲染过程:提交顶点数据和纹理,设定着色器和常量,最后调用drawTriangles配合索引缓冲进行绘制。

对于绘制到后台缓冲区的模型,我们就不能再次进行操作了,如果我们想要对一个模型进行多次不同的渲染就需要使用setRenderToTexture方法了。

 

先看看正常渲染的情况:

  1 package  2 {  3     import com.adobe.utils.AGALMiniAssembler;  4       5     import flash.display.Bitmap;  6     import flash.display.Sprite;  7     import flash.display.Stage3D;  8     import flash.display3D.Context3D;  9     import flash.display3D.Context3DProfile; 10     import flash.display3D.Context3DProgramType; 11     import flash.display3D.Context3DRenderMode; 12     import flash.display3D.Context3DTextureFormat; 13     import flash.display3D.Context3DVertexBufferFormat; 14     import flash.display3D.IndexBuffer3D; 15     import flash.display3D.Program3D; 16     import flash.display3D.VertexBuffer3D; 17     import flash.display3D.textures.Texture; 18     import flash.events.ErrorEvent; 19     import flash.events.Event; 20      21     [SWF(width=400, height=400, frameRate=60)] 22     public class FilterDemo extends Sprite 23     { 24         [Embed(source="img.png")] 25         private var IMG_CLASS:Class; 26          27         private var _stage3D:Stage3D; 28         private var _context3D:Context3D; 29         private var _vertexBuffer:VertexBuffer3D; 30         private var _indexBuffer:IndexBuffer3D; 31         private var _texture:Texture; 32         private var _program3D:Program3D; 33          34         //会被作为目标渲染的纹理 35         private var _filterTexture1:Texture; 36         private var _filterTexture2:Texture; 37          38         public function FilterDemo() 39         { 40             addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); 41         } 42          43         private function addedToStageHandler(event:Event):void 44         { 45             if(stage.stage3Ds.length > 0) 46             { 47                 _stage3D = stage.stage3Ds[0]; 48                 _stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler); 49                 _stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler); 50                 _stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE); 51             } 52         } 53          54         private function stage3DErrorHandler(event:ErrorEvent):void 55         { 56             trace("Context3D对象请求失败:", event.text); 57         } 58          59         private function context3DCreateHandler(event:Event):void 60         { 61             initContext3D(); 62             initBuffer(); 63             initTexture(); 64             normalRander(); 65 //            filterRander1(); 66 //            filterRander2(); 67 //            finallyRander(); 68         } 69          70         private function initContext3D():void 71         { 72             _context3D = _stage3D.context3D; 73             _context3D.configureBackBuffer(400, 400, 2); 74         } 75          76         private function initBuffer():void 77         { 78             var vertexData:Vector.<Number> = Vector.<Number>( 79                     [ 80                         -0.5, -0.5, 0, 0, 1, 81                         0.5,  -0.5, 0, 1, 1, 82                         0.5,   0.5, 0, 1, 0, 83                         -0.5,  0.5, 0, 0, 0 84                     ]); 85              86             _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5); 87             _vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); 88              89             var indexData:Vector.<uint> = Vector.<uint>( 90                     [ 91                         0, 3, 1, 92                         1, 2, 3 93                     ]); 94              95             _indexBuffer = _context3D.createIndexBuffer(indexData.length); 96             _indexBuffer.uploadFromVector(indexData, 0, indexData.length); 97         } 98          99         private function initTexture():void100         {101             var bitmap:Bitmap = new IMG_CLASS() as Bitmap;102             _texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);103             _texture.uploadFromBitmapData(bitmap.bitmapData, 0);104         }105         106         /**107          * 正常渲染.108          */109         private function normalRander():void110         {111             var vertexArr:Array =112                     [113                         "mov op, va0",114                         "mov v0, va1"115                     ];116             117             var fragmentArr:Array =118                     [119                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",120                         "mov oc, ft0"121                     ];122             123             var assembler:AGALMiniAssembler = new AGALMiniAssembler();124             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));125             126             _context3D.clear();127             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);128             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);129             _context3D.setTextureAt(0, _texture);130             _context3D.setProgram(_program3D);131             _context3D.drawTriangles(_indexBuffer);132             _context3D.present();133         }134         135         /**136          * 使用灰色滤镜渲染到纹理.137          */138         private function filterRander1():void139         {140             _filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);141             142             var vertexArr:Array =143                     [144                         "mov op, va0",145                         "mov v0, va1"146                     ];147             148             var fragmentArr:Array =149                     [150                         "tex ft0, v0, fs0 <2d,linear,clamp>",151                         "add ft1.x, ft0.x, ft0.y",152                         "add ft1.x, ft1.x, ft0.z",153                         "div ft1.x, ft1.x, fc0.w",154                         "mov ft0.xyz, ft1.xxx",155                         "mov oc ft0"156                     ];157             158             var assembler:AGALMiniAssembler = new AGALMiniAssembler();159             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));160             161             //设定渲染目标为我们的纹理162             _context3D.setRenderToTexture(_filterTexture1);163             _context3D.clear();164             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);165             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);166             //传递到灰色滤镜的设定值167             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));168             _context3D.setTextureAt(0, _texture);169             _context3D.setProgram(_program3D);170             _context3D.drawTriangles(_indexBuffer);171         }172         173         /**174          * 使用波浪滤镜再一次渲染到纹理.175          */176         private function filterRander2():void177         {178             _filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);179             180             var vertexArr:Array =181                     [182                         "mov op, va0",183                         "mov v0, va1"184                     ];185             186             var fragmentArr:Array =187                     [188                         "tex ft0,v0,fs0<2d,clamp,linear>",189                         "sub ft0.x,v0.x,fc0.w",190                         "mul ft0.x,ft0.x,ft0.x",191                         "sub ft0.y,v0.y,fc0.w",192                         "mul ft0.y,ft0.y,ft0.y",193                         "add ft0.z,ft0.x,ft0.y",194                         "sqt ft0.z,ft0.z",195                         "mul ft0.z,ft0.z,fc0.x",196                         "sub ft0.z,ft0.z,fc0.z",197                         "sin ft0.z,ft0.z",198                         "mul ft0.z,ft0.z,fc0.y",199                         "add ft0,v0,ft0.zzz",200                         "tex oc,ft0,fs0<2d,clamp,linear>"201                     ];202             203             var assembler:AGALMiniAssembler = new AGALMiniAssembler();204             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));205             206             //设定渲染目标为我们的纹理207             _context3D.setRenderToTexture(_filterTexture2);208             _context3D.clear();209             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);210             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);211             //设置波浪的常量212             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);213             _context3D.setTextureAt(0, _filterTexture1);214             _context3D.setProgram(_program3D);215             _context3D.drawTriangles(_indexBuffer);216             217             //还原后台缓冲区为渲染目标218             _context3D.setRenderToBackBuffer();219         }220         221         /**222          * 把最终的结果渲染到舞台.223          */224         private function finallyRander():void225         {226             var vertexArr:Array =227                     [228                         "mov op, va0",229                         "mov v0, va1"230                     ];231             232             var fragmentArr:Array =233                     [234                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",235                         "mov oc, ft0"236                     ];237             238             var assembler:AGALMiniAssembler = new AGALMiniAssembler();239             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));240             241             _context3D.clear();242             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);243             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);244             _context3D.setTextureAt(0, _filterTexture2);245             _context3D.setProgram(_program3D);246             _context3D.drawTriangles(_indexBuffer);247             _context3D.present();248         }249     }250 }
View Code

 

下面是使用纹理渲染了2次滤镜的效果:

  1 package  2 {  3     import com.adobe.utils.AGALMiniAssembler;  4       5     import flash.display.Bitmap;  6     import flash.display.Sprite;  7     import flash.display.Stage3D;  8     import flash.display3D.Context3D;  9     import flash.display3D.Context3DProfile; 10     import flash.display3D.Context3DProgramType; 11     import flash.display3D.Context3DRenderMode; 12     import flash.display3D.Context3DTextureFormat; 13     import flash.display3D.Context3DVertexBufferFormat; 14     import flash.display3D.IndexBuffer3D; 15     import flash.display3D.Program3D; 16     import flash.display3D.VertexBuffer3D; 17     import flash.display3D.textures.Texture; 18     import flash.events.ErrorEvent; 19     import flash.events.Event; 20      21     [SWF(width=400, height=400, frameRate=60)] 22     public class FilterDemo extends Sprite 23     { 24         [Embed(source="img.png")] 25         private var IMG_CLASS:Class; 26          27         private var _stage3D:Stage3D; 28         private var _context3D:Context3D; 29         private var _vertexBuffer:VertexBuffer3D; 30         private var _indexBuffer:IndexBuffer3D; 31         private var _texture:Texture; 32         private var _program3D:Program3D; 33          34         //会被作为目标渲染的纹理 35         private var _filterTexture1:Texture; 36         private var _filterTexture2:Texture; 37          38         public function FilterDemo() 39         { 40             addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); 41         } 42          43         private function addedToStageHandler(event:Event):void 44         { 45             if(stage.stage3Ds.length > 0) 46             { 47                 _stage3D = stage.stage3Ds[0]; 48                 _stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler); 49                 _stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler); 50                 _stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE); 51             } 52         } 53          54         private function stage3DErrorHandler(event:ErrorEvent):void 55         { 56             trace("Context3D对象请求失败:", event.text); 57         } 58          59         private function context3DCreateHandler(event:Event):void 60         { 61             initContext3D(); 62             initBuffer(); 63             initTexture(); 64 //            normalRander(); 65             filterRander1(); 66             filterRander2(); 67             finallyRander(); 68         } 69          70         private function initContext3D():void 71         { 72             _context3D = _stage3D.context3D; 73             _context3D.configureBackBuffer(400, 400, 2); 74         } 75          76         private function initBuffer():void 77         { 78             var vertexData:Vector.<Number> = Vector.<Number>( 79                     [ 80                         -0.5, -0.5, 0, 0, 1, 81                         0.5,  -0.5, 0, 1, 1, 82                         0.5,   0.5, 0, 1, 0, 83                         -0.5,  0.5, 0, 0, 0 84                     ]); 85              86             _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5); 87             _vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); 88              89             var indexData:Vector.<uint> = Vector.<uint>( 90                     [ 91                         0, 3, 1, 92                         1, 2, 3 93                     ]); 94              95             _indexBuffer = _context3D.createIndexBuffer(indexData.length); 96             _indexBuffer.uploadFromVector(indexData, 0, indexData.length); 97         } 98          99         private function initTexture():void100         {101             var bitmap:Bitmap = new IMG_CLASS() as Bitmap;102             _texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);103             _texture.uploadFromBitmapData(bitmap.bitmapData, 0);104         }105         106         /**107          * 正常渲染.108          */109         private function normalRander():void110         {111             var vertexArr:Array =112                     [113                         "mov op, va0",114                         "mov v0, va1"115                     ];116             117             var fragmentArr:Array =118                     [119                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",120                         "mov oc, ft0"121                     ];122             123             var assembler:AGALMiniAssembler = new AGALMiniAssembler();124             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));125             126             _context3D.clear();127             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);128             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);129             _context3D.setTextureAt(0, _texture);130             _context3D.setProgram(_program3D);131             _context3D.drawTriangles(_indexBuffer);132             _context3D.present();133         }134         135         /**136          * 使用灰色滤镜渲染到纹理.137          */138         private function filterRander1():void139         {140             _filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);141             142             var vertexArr:Array =143                     [144                         "mov op, va0",145                         "mov v0, va1"146                     ];147             148             var fragmentArr:Array =149                     [150                         "tex ft0, v0, fs0 <2d,linear,clamp>",151                         "add ft1.x, ft0.x, ft0.y",152                         "add ft1.x, ft1.x, ft0.z",153                         "div ft1.x, ft1.x, fc0.w",154                         "mov ft0.xyz, ft1.xxx",155                         "mov oc ft0"156                     ];157             158             var assembler:AGALMiniAssembler = new AGALMiniAssembler();159             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));160             161             //设定渲染目标为我们的纹理162             _context3D.setRenderToTexture(_filterTexture1);163             _context3D.clear();164             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);165             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);166             //传递到灰色滤镜的设定值167             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));168             _context3D.setTextureAt(0, _texture);169             _context3D.setProgram(_program3D);170             _context3D.drawTriangles(_indexBuffer);171         }172         173         /**174          * 使用波浪滤镜再一次渲染到纹理.175          */176         private function filterRander2():void177         {178             _filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);179             180             var vertexArr:Array =181                     [182                         "mov op, va0",183                         "mov v0, va1"184                     ];185             186             var fragmentArr:Array =187                     [188                         "tex ft0,v0,fs0<2d,clamp,linear>",189                         "sub ft0.x,v0.x,fc0.w",190                         "mul ft0.x,ft0.x,ft0.x",191                         "sub ft0.y,v0.y,fc0.w",192                         "mul ft0.y,ft0.y,ft0.y",193                         "add ft0.z,ft0.x,ft0.y",194                         "sqt ft0.z,ft0.z",195                         "mul ft0.z,ft0.z,fc0.x",196                         "sub ft0.z,ft0.z,fc0.z",197                         "sin ft0.z,ft0.z",198                         "mul ft0.z,ft0.z,fc0.y",199                         "add ft0,v0,ft0.zzz",200                         "tex oc,ft0,fs0<2d,clamp,linear>"201                     ];202             203             var assembler:AGALMiniAssembler = new AGALMiniAssembler();204             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));205             206             //设定渲染目标为我们的纹理207             _context3D.setRenderToTexture(_filterTexture2);208             _context3D.clear();209             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);210             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);211             //设置波浪的常量212             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);213             _context3D.setTextureAt(0, _filterTexture1);214             _context3D.setProgram(_program3D);215             _context3D.drawTriangles(_indexBuffer);216             217             //还原后台缓冲区为渲染目标218             _context3D.setRenderToBackBuffer();219         }220         221         /**222          * 把最终的结果渲染到舞台.223          */224         private function finallyRander():void225         {226             var vertexArr:Array =227                     [228                         "mov op, va0",229                         "mov v0, va1"230                     ];231             232             var fragmentArr:Array =233                     [234                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",235                         "mov oc, ft0"236                     ];237             238             var assembler:AGALMiniAssembler = new AGALMiniAssembler();239             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));240             241             _context3D.clear();242             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);243             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);244             _context3D.setTextureAt(0, _filterTexture2);245             _context3D.setProgram(_program3D);246             _context3D.drawTriangles(_indexBuffer);247             _context3D.present();248         }249     }250 }
View Code

我们发现最终的效果里我们的图像变小了很多,这是为啥呢?原因就是我们每次渲染时上传的顶点坐标是:

1 var vertexData:Vector.<Number> = Vector.<Number>(2         [3             -0.5, -0.5, 0, 0, 1,4             0.5,  -0.5, 0, 1, 1,5             0.5,   0.5, 0, 1, 0,6             -0.5,  0.5, 0, 0, 07         ]);

这样的结果是每次绘制图像都是占屏幕的一半,而我们经过3次渲染所以图像就变成了很小,要让图像不变的话,只有把顶点数据的0.5都改为1即可。

 

最终效果:

  1 package  2 {  3     import com.adobe.utils.AGALMiniAssembler;  4       5     import flash.display.Bitmap;  6     import flash.display.Sprite;  7     import flash.display.Stage3D;  8     import flash.display3D.Context3D;  9     import flash.display3D.Context3DProfile; 10     import flash.display3D.Context3DProgramType; 11     import flash.display3D.Context3DRenderMode; 12     import flash.display3D.Context3DTextureFormat; 13     import flash.display3D.Context3DVertexBufferFormat; 14     import flash.display3D.IndexBuffer3D; 15     import flash.display3D.Program3D; 16     import flash.display3D.VertexBuffer3D; 17     import flash.display3D.textures.Texture; 18     import flash.events.ErrorEvent; 19     import flash.events.Event; 20      21     [SWF(width=400, height=400, frameRate=60)] 22     public class FilterDemo extends Sprite 23     { 24         [Embed(source="img.png")] 25         private var IMG_CLASS:Class; 26          27         private var _stage3D:Stage3D; 28         private var _context3D:Context3D; 29         private var _vertexBuffer:VertexBuffer3D; 30         private var _indexBuffer:IndexBuffer3D; 31         private var _texture:Texture; 32         private var _program3D:Program3D; 33          34         //会被作为目标渲染的纹理 35         private var _filterTexture1:Texture; 36         private var _filterTexture2:Texture; 37          38         public function FilterDemo() 39         { 40             addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); 41         } 42          43         private function addedToStageHandler(event:Event):void 44         { 45             if(stage.stage3Ds.length > 0) 46             { 47                 _stage3D = stage.stage3Ds[0]; 48                 _stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler); 49                 _stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler); 50                 _stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE); 51             } 52         } 53          54         private function stage3DErrorHandler(event:ErrorEvent):void 55         { 56             trace("Context3D对象请求失败:", event.text); 57         } 58          59         private function context3DCreateHandler(event:Event):void 60         { 61             initContext3D(); 62             initBuffer(); 63             initTexture(); 64 //            normalRander(); 65             filterRander1(); 66             filterRander2(); 67             finallyRander(); 68         } 69          70         private function initContext3D():void 71         { 72             _context3D = _stage3D.context3D; 73             _context3D.configureBackBuffer(400, 400, 2); 74         } 75          76         private function initBuffer():void 77         { 78             var vertexData:Vector.<Number> = Vector.<Number>( 79                     [ 80                         -1, -1, 0, 0, 1, 81                         1,  -1, 0, 1, 1, 82                         1,   1, 0, 1, 0, 83                         -1,  1, 0, 0, 0 84                     ]); 85              86             _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5); 87             _vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); 88              89             var indexData:Vector.<uint> = Vector.<uint>( 90                     [ 91                         0, 3, 1, 92                         1, 2, 3 93                     ]); 94              95             _indexBuffer = _context3D.createIndexBuffer(indexData.length); 96             _indexBuffer.uploadFromVector(indexData, 0, indexData.length); 97         } 98          99         private function initTexture():void100         {101             var bitmap:Bitmap = new IMG_CLASS() as Bitmap;102             _texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);103             _texture.uploadFromBitmapData(bitmap.bitmapData, 0);104         }105         106         /**107          * 正常渲染.108          */109         private function normalRander():void110         {111             var vertexArr:Array =112                     [113                         "mov op, va0",114                         "mov v0, va1"115                     ];116             117             var fragmentArr:Array =118                     [119                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",120                         "mov oc, ft0"121                     ];122             123             var assembler:AGALMiniAssembler = new AGALMiniAssembler();124             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));125             126             _context3D.clear();127             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);128             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);129             _context3D.setTextureAt(0, _texture);130             _context3D.setProgram(_program3D);131             _context3D.drawTriangles(_indexBuffer);132             _context3D.present();133         }134         135         /**136          * 使用灰色滤镜渲染到纹理.137          */138         private function filterRander1():void139         {140             _filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);141             142             var vertexArr:Array =143                     [144                         "mov op, va0",145                         "mov v0, va1"146                     ];147             148             var fragmentArr:Array =149                     [150                         "tex ft0, v0, fs0 <2d,linear,clamp>",151                         "add ft1.x, ft0.x, ft0.y",152                         "add ft1.x, ft1.x, ft0.z",153                         "div ft1.x, ft1.x, fc0.w",154                         "mov ft0.xyz, ft1.xxx",155                         "mov oc ft0"156                     ];157             158             var assembler:AGALMiniAssembler = new AGALMiniAssembler();159             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));160             161             //设定渲染目标为我们的纹理162             _context3D.setRenderToTexture(_filterTexture1);163             _context3D.clear();164             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);165             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);166             //传递到灰色滤镜的设定值167             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));168             _context3D.setTextureAt(0, _texture);169             _context3D.setProgram(_program3D);170             _context3D.drawTriangles(_indexBuffer);171         }172         173         /**174          * 使用波浪滤镜再一次渲染到纹理.175          */176         private function filterRander2():void177         {178             _filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);179             180             var vertexArr:Array =181                     [182                         "mov op, va0",183                         "mov v0, va1"184                     ];185             186             var fragmentArr:Array =187                     [188                         "tex ft0,v0,fs0<2d,clamp,linear>",189                         "sub ft0.x,v0.x,fc0.w",190                         "mul ft0.x,ft0.x,ft0.x",191                         "sub ft0.y,v0.y,fc0.w",192                         "mul ft0.y,ft0.y,ft0.y",193                         "add ft0.z,ft0.x,ft0.y",194                         "sqt ft0.z,ft0.z",195                         "mul ft0.z,ft0.z,fc0.x",196                         "sub ft0.z,ft0.z,fc0.z",197                         "sin ft0.z,ft0.z",198                         "mul ft0.z,ft0.z,fc0.y",199                         "add ft0,v0,ft0.zzz",200                         "tex oc,ft0,fs0<2d,clamp,linear>"201                     ];202             203             var assembler:AGALMiniAssembler = new AGALMiniAssembler();204             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));205             206             //设定渲染目标为我们的纹理207             _context3D.setRenderToTexture(_filterTexture2);208             _context3D.clear();209             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);210             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);211             //设置波浪的常量212             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);213             _context3D.setTextureAt(0, _filterTexture1);214             _context3D.setProgram(_program3D);215             _context3D.drawTriangles(_indexBuffer);216             217             //还原后台缓冲区为渲染目标218             _context3D.setRenderToBackBuffer();219         }220         221         /**222          * 把最终的结果渲染到舞台.223          */224         private function finallyRander():void225         {226             var vertexArr:Array =227                     [228                         "mov op, va0",229                         "mov v0, va1"230                     ];231             232             var fragmentArr:Array =233                     [234                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",235                         "mov oc, ft0"236                     ];237             238             var assembler:AGALMiniAssembler = new AGALMiniAssembler();239             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));240             241             _context3D.clear();242             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);243             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);244             _context3D.setTextureAt(0, _filterTexture2);245             _context3D.setProgram(_program3D);246             _context3D.drawTriangles(_indexBuffer);247             _context3D.present();248         }249     }250 }
View Code

Stage3D学习笔记(七):动态纹理