首页 > 代码库 > Stage3D学习笔记(七):动态纹理
Stage3D学习笔记(七):动态纹理
本章用来作为Starling的滤镜实现原理的一个补充,但是为了了解原理,我们会使用原生API进行编码。
我们知道,当我们调用drawTriangles方法时,我们的图像是绘制到后台缓冲区的,只有调用present方法时才会把图像呈现到屏幕。
我们先来看看Context3D的两个方法:
- setRenderToTexture:我们默认的渲染都是在后台缓冲区进行的,使用该方法可以把渲染修改到一个纹理上,调用该方法后,Context3D对象的渲染操作(clear、drawTriangles等)都会渲染到指定的纹理上而不是后台缓冲区。
- 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 }
下面是使用纹理渲染了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 }
我们发现最终的效果里我们的图像变小了很多,这是为啥呢?原因就是我们每次渲染时上传的顶点坐标是:
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 }
Stage3D学习笔记(七):动态纹理
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。