XNA Shader编程教程12- Post process噪点/扭曲

程序截图

此教程是建立在教程9.1基础上的。如果你还没理解教程9.1,请先弄懂它。

要在场景中添加噪点/扭曲,你必须在纹理坐标中添加一个扭曲值,然后使用新的纹理坐标查询纹理采样器。 我们还想实现噪点动画,所以还需要一个timer作用在扭曲值上。我们还需要一个值表示扭曲程度,一个seed用于扭曲算法。

实现shader

首先要在shader中定义一些全局变量:

// This will use the texture bound to the object( like from the sprite batch ).
sampler ColorMapSampler : register(s0);

// A timer to animate our shader 
float fTimer; 

// the amount of distortion 
float fNoiseAmount; 

// just a random starting number 
int iSeed;

ColorMapSampler是渲染的场景,fTimer是定时器,fNoiseAmount是扭曲程度,它的值在0.001至0.5是最好的,iSeed是用于计算噪点的种子。

接着,在shader中添加代码。首先要计算噪点因子:

float NoiseX = iSeed * fTimer * sin(Tex.x * Tex.y+fTimer);
NoiseX=fmod(NoiseX,8) * fmod(NoiseX,4); 

上面的代码只是一个使用seed的随机函数,使用timer和纹理坐标让每个像素的值有所不同,可以通过改变它们获得不同的效果。这里我们使用了一个新函数:fmod(x,y)。这个函数返回一个x被y除并取模的浮点数。接着计算扭曲程度用来影像x和y分量。我们稍微改变扭曲程度使看了来有点随机:

float DistortX = fmod(NoiseX,fNoiseAmount); 
float DistortY = fmod(NoiseX,fNoiseAmount+0.002); 

现在计算新的纹理坐标:

float2 DistortTex = float2(DistortX,DistortY); 

最后,将这个新纹理坐标和旧纹理坐标混合形成一个稍有扭曲的纹理坐标:

float4 Color=tex2D(ColorMapSampler, Tex+DistortTex); 

下面是shader代码:

// Global variables
// This will use the texture bound to the object( like from the sprite batch ). 
sampler ColorMapSampler : register(s0);

// A timer to animate our shader 
float fTimer; 

// the amount of distortion 
float fNoiseAmount; 

// just a random starting number 
int iSeed; 

// Noise 
float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR
{
    // Distortion factor 
    float NoiseX = iSeed * fTimer * sin(Tex.x * Tex.y+fTimer); 
    NoiseX=fmod(NoiseX,8) * fmod(NoiseX,4); 
    
    // Use our 	distortion factor to compute how much it will affect each 
    // texture coordinate 
    float DistortX = fmod(NoiseX,fNoiseAmount); 
    float DistortY = fmod(NoiseX,fNoiseAmount+0.002); 
    
    // Create our new texture coordinate based on our distortion factor 
    float2 DistortTex = float2(DistortX,DistortY); 
    
    // Use our new texture coordinate to look-up a pixel in ColorMapSampler. 
    float4 Color=tex2D(ColorMapSampler, Tex+DistortTex); 
    
    // Keep our alphachannel at 1. 
    Color.a = 1.0f; 
    return Color; 
}

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

发布时间:2009/5/3 上午11:32:01  阅读次数:8939

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

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号