让我们来创建后期效果-模糊!

原计划是丢HDR效果的,但是实际上HDR效果中要用到Blur效果的,因此先丢Blur

模糊效果是后期效果中比较简单效果. 这里不做径向模糊,不做正态分布,纯粹的模糊就是将当前像素的颜色以周围的像素为平均值来求出.
根据这个原理,当拿到uv值时,只需要做一次3*3的遍历,来求出周围8个像素,然后将像素叠加/8即可获得平均值,剩下的事就是用AGAL来求出了.

不上图了,做个代码笔记,之后就是Demo

周围像素的数量为圈数 n – 1 * 3 * 24, 其中 n > 1; 当 n 小于等于 1时. 像素的数量为8
整理为代码就是
var index : uint = step <= 1 ? 1 : (step - 1) * 3; var num : uint = 8 * index; 之后我们需要用拼接的方式来构造AGAL [cc lang="actionscript3"] private function getBlurAgal(step : uint, force : uint, coord : String, pTempIndex : int, pSaveIndex : int, pConstantOffset : int, pTextureIndex : int, constant : Vector., pInitIndex : int) : String
{
var data : Array = new Array();
var isFirstSave : Boolean = true;
var loopNum : uint = 0;
var stepX : Number = force / stage.stageWidth;
var stepY : Number = force / stage.stageHeight;
var index : uint = step <= 1 ? 1 : (step - 1) * 3; var num : uint = 8 * index; var tempIndex : int = pTempIndex; var saveIndex : int = pSaveIndex; var textureIndex : int = pTextureIndex; var initIndex : int = pInitIndex; var constantOffset : int = pConstantOffset; constant = constant || new Vector.();
constant.length = 0;

data.push(“mov ft” + tempIndex + “, fc” + initIndex);

//横向遍历
for(var i : int = -step; i <= step; i++) { //纵向遍历 for(var j : int = -step; j <= step; j ++) { //跳过中心区 if(i == 0 && j == 0) continue; constant.push(i * stepX, j * stepY); data.push("add ft" + tempIndex + ".xy, " + coord + ".xy, fc" + constantOffset + (loopNum % 2 == 0 ? ".xy" : ".zw")); data.push("tex ft" + tempIndex + ", ft" + tempIndex + ", fs" + textureIndex + "<2d, repeat, linear, mipnone>“);
data.push(
isFirstSave ? “mov ft” + saveIndex + “, ft” + tempIndex :
“add ft” + saveIndex + “, ft” + saveIndex + “, ft” + tempIndex);
isFirstSave = false;
if(++loopNum % 2 == 0) constantOffset++;
}
}

data.push(“div ft” + saveIndex + “.rgb, ft” + saveIndex + “.rgb, fc” + constantOffset + “.w”);
data.push(“mov oc, ft” + saveIndex);

if(constant.length / 4 > 28){
return getBlurAgal(1,1,coord,pTempIndex,pSaveIndex,pConstantOffset,pTextureIndex,constant,pInitIndex);
}

constant.push(0,0,0,num);
return data.join(“n”);
}
[/cc]

var stepX : Number = force / stage.stageWidth;
var stepY : Number = force / stage.stageHeight;
求出当前屏幕大小纹理的u和v的步进值

data.push(“mov ft” + tempIndex + “, fc” + initIndex);
初始化用来保存周围像素的值的寄存器, 初始化值这里是 0,0,0,0

(loopNum % 2 == 0 ? “.xy” : “.zw”)
由于常量寄存器数量只有28个,因此如果每个float4 我们只有xy,那么zw就被浪费了,Blur的层级也无法提升,因此基于物尽其用的原则,每2个uv使用一个float4.

if(constant.length / 4 > 28)
由于常量寄存器只有28个, 其中每4个长度为一个 float4 因此当超过28个寄存器时,将模糊滤镜重置为最小滤镜

data.push(
isFirstSave ? “mov ft” + saveIndex + “, ft” + tempIndex :
“add ft” + saveIndex + “, ft” + saveIndex + “, ft” + tempIndex);
isFirstSave = false;
用来记录当前累加颜色的寄存器必须初始化,可以给它丢个initIndex中的值,但实际上这里直接把第一次的得出的颜色值mov进去就当作它的初始化值就够了,不需要额外的初始化.

使用方法:
var m_blurAgal : String = getBlurAgal(3, 1, “v0″, 0, 1, 1, 0, m_blurConstant, 0); fragmentProgram.assemble(Context3DProgramType.FRAGMENT, m_blurAgal);

初始化一个圈数为3,强度为1,uv位置为”v0”,纹理位置在0,常量偏移为1,临时寄存器为1,常量数组,初始值在常量位置1
编译agal

最后是Demo: click me

Github地址: click me

发表评论

电子邮件地址不会被公开。 必填项已用*标注