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 阅读次数:9036