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

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

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

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

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

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

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

先看看正常渲染的情况:

 package
{
import com.adobe.utils.AGALMiniAssembler; import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.events.ErrorEvent;
import flash.events.Event; [SWF(width=400, height=400, frameRate=60)]
public class FilterDemo extends Sprite
{
[Embed(source="img.png")]
private var IMG_CLASS:Class; private var _stage3D:Stage3D;
private var _context3D:Context3D;
private var _vertexBuffer:VertexBuffer3D;
private var _indexBuffer:IndexBuffer3D;
private var _texture:Texture;
private var _program3D:Program3D; //会被作为目标渲染的纹理
private var _filterTexture1:Texture;
private var _filterTexture2:Texture; public function FilterDemo()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
} private function addedToStageHandler(event:Event):void
{
if(stage.stage3Ds.length > 0)
{
_stage3D = stage.stage3Ds[0];
_stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
_stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
_stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
} private function stage3DErrorHandler(event:ErrorEvent):void
{
trace("Context3D对象请求失败:", event.text);
} private function context3DCreateHandler(event:Event):void
{
initContext3D();
initBuffer();
initTexture();
normalRander();
// filterRander1();
// filterRander2();
// finallyRander();
} private function initContext3D():void
{
_context3D = _stage3D.context3D;
_context3D.configureBackBuffer(400, 400, 2);
} private function initBuffer():void
{
var vertexData:Vector.<Number> = Vector.<Number>(
[
-0.5, -0.5, 0, 0, 1,
0.5, -0.5, 0, 1, 1,
0.5, 0.5, 0, 1, 0,
-0.5, 0.5, 0, 0, 0
]); _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
_vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); var indexData:Vector.<uint> = Vector.<uint>(
[
0, 3, 1,
1, 2, 3
]); _indexBuffer = _context3D.createIndexBuffer(indexData.length);
_indexBuffer.uploadFromVector(indexData, 0, indexData.length);
} private function initTexture():void
{
var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
_texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
_texture.uploadFromBitmapData(bitmap.bitmapData, 0);
} /**
* 正常渲染.
*/
private function normalRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
} /**
* 使用灰色滤镜渲染到纹理.
*/
private function filterRander1():void
{
_filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,linear,clamp>",
"add ft1.x, ft0.x, ft0.y",
"add ft1.x, ft1.x, ft0.z",
"div ft1.x, ft1.x, fc0.w",
"mov ft0.xyz, ft1.xxx",
"mov oc ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture1);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//传递到灰色滤镜的设定值
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
} /**
* 使用波浪滤镜再一次渲染到纹理.
*/
private function filterRander2():void
{
_filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0,v0,fs0<2d,clamp,linear>",
"sub ft0.x,v0.x,fc0.w",
"mul ft0.x,ft0.x,ft0.x",
"sub ft0.y,v0.y,fc0.w",
"mul ft0.y,ft0.y,ft0.y",
"add ft0.z,ft0.x,ft0.y",
"sqt ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.x",
"sub ft0.z,ft0.z,fc0.z",
"sin ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.y",
"add ft0,v0,ft0.zzz",
"tex oc,ft0,fs0<2d,clamp,linear>"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture2);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//设置波浪的常量
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
_context3D.setTextureAt(0, _filterTexture1);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer); //还原后台缓冲区为渲染目标
_context3D.setRenderToBackBuffer();
} /**
* 把最终的结果渲染到舞台.
*/
private function finallyRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _filterTexture2);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
}
}
}

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

 package
{
import com.adobe.utils.AGALMiniAssembler; import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.events.ErrorEvent;
import flash.events.Event; [SWF(width=400, height=400, frameRate=60)]
public class FilterDemo extends Sprite
{
[Embed(source="img.png")]
private var IMG_CLASS:Class; private var _stage3D:Stage3D;
private var _context3D:Context3D;
private var _vertexBuffer:VertexBuffer3D;
private var _indexBuffer:IndexBuffer3D;
private var _texture:Texture;
private var _program3D:Program3D; //会被作为目标渲染的纹理
private var _filterTexture1:Texture;
private var _filterTexture2:Texture; public function FilterDemo()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
} private function addedToStageHandler(event:Event):void
{
if(stage.stage3Ds.length > 0)
{
_stage3D = stage.stage3Ds[0];
_stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
_stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
_stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
} private function stage3DErrorHandler(event:ErrorEvent):void
{
trace("Context3D对象请求失败:", event.text);
} private function context3DCreateHandler(event:Event):void
{
initContext3D();
initBuffer();
initTexture();
// normalRander();
filterRander1();
filterRander2();
finallyRander();
} private function initContext3D():void
{
_context3D = _stage3D.context3D;
_context3D.configureBackBuffer(400, 400, 2);
} private function initBuffer():void
{
var vertexData:Vector.<Number> = Vector.<Number>(
[
-0.5, -0.5, 0, 0, 1,
0.5, -0.5, 0, 1, 1,
0.5, 0.5, 0, 1, 0,
-0.5, 0.5, 0, 0, 0
]); _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
_vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); var indexData:Vector.<uint> = Vector.<uint>(
[
0, 3, 1,
1, 2, 3
]); _indexBuffer = _context3D.createIndexBuffer(indexData.length);
_indexBuffer.uploadFromVector(indexData, 0, indexData.length);
} private function initTexture():void
{
var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
_texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
_texture.uploadFromBitmapData(bitmap.bitmapData, 0);
} /**
* 正常渲染.
*/
private function normalRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
} /**
* 使用灰色滤镜渲染到纹理.
*/
private function filterRander1():void
{
_filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,linear,clamp>",
"add ft1.x, ft0.x, ft0.y",
"add ft1.x, ft1.x, ft0.z",
"div ft1.x, ft1.x, fc0.w",
"mov ft0.xyz, ft1.xxx",
"mov oc ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture1);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//传递到灰色滤镜的设定值
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
} /**
* 使用波浪滤镜再一次渲染到纹理.
*/
private function filterRander2():void
{
_filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0,v0,fs0<2d,clamp,linear>",
"sub ft0.x,v0.x,fc0.w",
"mul ft0.x,ft0.x,ft0.x",
"sub ft0.y,v0.y,fc0.w",
"mul ft0.y,ft0.y,ft0.y",
"add ft0.z,ft0.x,ft0.y",
"sqt ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.x",
"sub ft0.z,ft0.z,fc0.z",
"sin ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.y",
"add ft0,v0,ft0.zzz",
"tex oc,ft0,fs0<2d,clamp,linear>"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture2);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//设置波浪的常量
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
_context3D.setTextureAt(0, _filterTexture1);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer); //还原后台缓冲区为渲染目标
_context3D.setRenderToBackBuffer();
} /**
* 把最终的结果渲染到舞台.
*/
private function finallyRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _filterTexture2);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
}
}
}

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

 var vertexData:Vector.<Number> = Vector.<Number>(
[
-0.5, -0.5, 0, 0, 1,
0.5, -0.5, 0, 1, 1,
0.5, 0.5, 0, 1, 0,
-0.5, 0.5, 0, 0, 0
]);

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

最终效果:

 package
{
import com.adobe.utils.AGALMiniAssembler; import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.events.ErrorEvent;
import flash.events.Event; [SWF(width=400, height=400, frameRate=60)]
public class FilterDemo extends Sprite
{
[Embed(source="img.png")]
private var IMG_CLASS:Class; private var _stage3D:Stage3D;
private var _context3D:Context3D;
private var _vertexBuffer:VertexBuffer3D;
private var _indexBuffer:IndexBuffer3D;
private var _texture:Texture;
private var _program3D:Program3D; //会被作为目标渲染的纹理
private var _filterTexture1:Texture;
private var _filterTexture2:Texture; public function FilterDemo()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
} private function addedToStageHandler(event:Event):void
{
if(stage.stage3Ds.length > 0)
{
_stage3D = stage.stage3Ds[0];
_stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
_stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
_stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
} private function stage3DErrorHandler(event:ErrorEvent):void
{
trace("Context3D对象请求失败:", event.text);
} private function context3DCreateHandler(event:Event):void
{
initContext3D();
initBuffer();
initTexture();
// normalRander();
filterRander1();
filterRander2();
finallyRander();
} private function initContext3D():void
{
_context3D = _stage3D.context3D;
_context3D.configureBackBuffer(400, 400, 2);
} private function initBuffer():void
{
var vertexData:Vector.<Number> = Vector.<Number>(
[
-1, -1, 0, 0, 1,
1, -1, 0, 1, 1,
1, 1, 0, 1, 0,
-1, 1, 0, 0, 0
]); _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
_vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); var indexData:Vector.<uint> = Vector.<uint>(
[
0, 3, 1,
1, 2, 3
]); _indexBuffer = _context3D.createIndexBuffer(indexData.length);
_indexBuffer.uploadFromVector(indexData, 0, indexData.length);
} private function initTexture():void
{
var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
_texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
_texture.uploadFromBitmapData(bitmap.bitmapData, 0);
} /**
* 正常渲染.
*/
private function normalRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
} /**
* 使用灰色滤镜渲染到纹理.
*/
private function filterRander1():void
{
_filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,linear,clamp>",
"add ft1.x, ft0.x, ft0.y",
"add ft1.x, ft1.x, ft0.z",
"div ft1.x, ft1.x, fc0.w",
"mov ft0.xyz, ft1.xxx",
"mov oc ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture1);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//传递到灰色滤镜的设定值
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
} /**
* 使用波浪滤镜再一次渲染到纹理.
*/
private function filterRander2():void
{
_filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0,v0,fs0<2d,clamp,linear>",
"sub ft0.x,v0.x,fc0.w",
"mul ft0.x,ft0.x,ft0.x",
"sub ft0.y,v0.y,fc0.w",
"mul ft0.y,ft0.y,ft0.y",
"add ft0.z,ft0.x,ft0.y",
"sqt ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.x",
"sub ft0.z,ft0.z,fc0.z",
"sin ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.y",
"add ft0,v0,ft0.zzz",
"tex oc,ft0,fs0<2d,clamp,linear>"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture2);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//设置波浪的常量
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
_context3D.setTextureAt(0, _filterTexture1);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer); //还原后台缓冲区为渲染目标
_context3D.setRenderToBackBuffer();
} /**
* 把最终的结果渲染到舞台.
*/
private function finallyRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _filterTexture2);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
}
}
}

Stage3D学习笔记(七):动态纹理的更多相关文章

  1. Stage3D学习笔记(五):通过矩阵操作纹理

    虽然我们上一节已经实现了正交矩阵的显示,但是可以明显的感觉到要调整显示纹理的坐标和尺寸是相当复杂的,需要对每个顶点进行操作,如果还要加上注册点和旋转的话,用上一节的方法来做是会让人发疯的! 所以我们距 ...

  2. 【Stage3D学习笔记续】山寨Starling(八):核心优化(批处理)的实现

    批处理是使GPU进行高效绘制的一种技术手段,也是整个渲染流程中最核心的技术,到目前为止我们并没有使用到这种技术手段,下面我们看看我们现在的渲染机制. 先想一想我们最开始是怎么向GPU绘制一幅图像的,可 ...

  3. 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  4. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  5. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  6. Web Service学习笔记:动态调用WebService

    原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  8. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. python3.4学习笔记(七) 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

  10. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

随机推荐

  1. Git教程之分支管理之一

    分支在实际中有什么用呢? 你创建了一个属于你自己的分支,别人看不到,别人还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又 ...

  2. 99. Recover Binary Search Tree

    题目: Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without chan ...

  3. 启用了不安全的HTTP方法

    安全风险:       可能会在Web 服务器上上载.修改或删除Web 页面.脚本和文件. 可能原因:       Web 服务器或应用程序服务器是以不安全的方式配置的. 修订建议:       如果 ...

  4. php cloure闭包

    Closures 它可以让您创建in-line 函数.许多语言已经开始有此功能了,也许您在不知道的情况下也使用过它. 例如: <?php $myFunction = function() { e ...

  5. ARM7ldr指令与ldr伪指令

    ldr伪指令的第二个操作数之前有个=,意思是第一个操作书 = 第二个操作数,相当明了 核心就在于对于用.word指令在.text段里另外定义一段内存,用ldr r0,[pc + x(可以算出.text ...

  6. 【原创】ZYNQ学习笔记(一) HelloWorld实现

    拿过ZYNQ开发板,里面给了很多部件,果断从网上下载了手册,N多手册和原理图. 要比Spartan-6复杂多了,耐心地看了看,知道ZYNQ系列分为PS(系统)以及PL(逻辑)部分. 之前,自己一直在做 ...

  7. Target host is not specified错误

    对于httpClient4.3访问指定页面,可以从下面的demo抽取方法使用. 注意:对于URL必须使用 http://开始,否则会有如下报错信息: 或者在设置cookie时带上domain: coo ...

  8. WCF 服务调用RFC 出现异常

    我在VS2010的WCF项目用connecter 3.0 调用 RFC  运行到       IDestinationConfiguration ID = new SAPConfig();       ...

  9. apache开源项目--Camel

    Apache Camel 是一个非常强大的基于规则的路由以及媒介引擎,该引擎提供了一个基于POJO的 企业应用模式(Enterprise Integration Patterns)的实现,你可以采用其 ...

  10. Mysql加密方式

    MySQL数据库的认证密码有两种方式, MySQL 4.1版本之前是MySQL323加密,MySQL 4.1和之后的版本都是MySQLSHA1加密, MySQL数据库中自带Old_Password(s ...