XNA Shader编程教程23 – 模糊

原文地址:http://digierr.spaces.live.com/blog/cns!2B7007E9EC2AE37B!855.entry。

程序截图

本教程将要实现一个简单的模糊,它是一个后期处理shader,可以对任意给定纹理进行模糊处理。

实现Shader

要模糊一个场景,我们需要实现一个新的后期处理shader,它会获取一个像素的临近像素颜色的平均值,并将这个颜色作为最终颜色返回。模糊shader会使用一个距离变量调整包含场景的查询纹理的坐标,它会提取当前像素的左上、右上、左下和右下的像素,相加并除以4,这样就获得了它们的平均值。

上图中我们可以看到实际的模糊效果。这个shader根据给定距离(本例中为0.002)计算了周围像素的平均值,而这个距离可以在shader中或程序中设定。 下图显示了模糊效果:

模糊效果

下面的代码查询当前处理的像素的周围像素。

Color  = tex2D( ColorMapSampler, float2(Tex.x+BlurDistance, Tex.y+BlurDistance));
Color += tex2D( ColorMapSampler, float2(Tex.x-BlurDistance, Tex.y-BlurDistance));
Color += tex2D( ColorMapSampler, float2(Tex.x+BlurDistance, Tex.y-BlurDistance));
Color += tex2D( ColorMapSampler, float2(Tex.x-BlurDistance, Tex.y+BlurDistance));

我们只是简单地获取周围像素的颜色并将它们添加到最终颜色中。然后,我们需要将这个颜色除以4以获得平均颜色。

Color = Color / 4; 

下面是effect文件的完整代码:

// The blur amount( how far away from our texel will we look up neighbour texels? )
float BlurDistance = 0.002f;
 
// This will use the texture bound to the object( like from the sprite batch ).
sampler ColorMapSampler : register(s0);
 
float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR
{
    float4 Color;
 
    // Get the texel from ColorMapSampler using a modified texture coordinate. This
    // gets the texels at the neighbour texels and adds it to Color.
    Color  = tex2D( ColorMapSampler, float2(Tex.x+BlurDistance, Tex.y+BlurDistance));
    Color += tex2D( ColorMapSampler, float2(Tex.x-BlurDistance, Tex.y-BlurDistance));
    Color += tex2D( ColorMapSampler, float2(Tex.x+BlurDistance, Tex.y-BlurDistance));
    Color += tex2D( ColorMapSampler, float2(Tex.x-BlurDistance, Tex.y+BlurDistance));

    // We need to devide the color with the amount of times we added
    // a color to it, in this case 4, to get the avg. color
    Color = Color / 4; 
    
    if(Tex.x > 0.495 && Tex.x < 0.505)
	{
		Color = float4(1,0,0,0);
	}
 
	if(Tex.x > 0.5)
	{
	    Color = tex2D( ColorMapSampler, float2(Tex.x, Tex.y));
	}
 
    // returned the blurred color
    return Color;
}

technique PostProcess
{
       pass P0
       {
             // A post process shader only needs a pixel shader.
             PixelShader = compile ps_2_0 PixelShader();
       }
}

这是一个非常简单的模糊效果,你还可以使用这个shader对纹理进行多次模糊处理让效果更好。我在这个程序中添加了一条竖线,线的左边是模糊过的场景,右边是原始场景。

这个shader的效果不是很漂亮,以后我会写一个高斯模糊的教程,如果你想使用这个shader获得更好的效果,可以对场景模糊多次。

文件下载(已下载 1939 次)

发布时间:2010/6/25 下午12:05:03  阅读次数:9152

2006 - 2024,推荐分辨率 1024*768 以上,推荐浏览器 Chrome、Edge 等现代浏览器,截止 2021 年 12 月 5 日的访问次数:1872 万 9823 站长邮箱

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号