XNA Shader Programming – Tutorial 12, Post process Noise

XNA Shader Programming
Tutorial 12 – Post process, Noise/Distortion
This tutorial builds on Tutorial 9, post process wiggling. If you haven’t read that yet, you should in order to fully understand what’s going on here.
 
The source-code and binaries can be found in the end of the tutorial.
 
 
Noise/Distortion
In this tutorial, we are going to add some Noise/Distortion to our scene.
To add some noise/distortion to your scenes, we must add a distortion value to out texture coordinates, and when modified, we must use the new texture coordinate to look up into a texture sampler.
 
We also want to animate the noise, so we would need a timer that will affect the distortion amount, and we must have a value that indicats how much we want to distort our image, and a seed that will be used in the distortion algorithm.
 
 
Implementing the shader
Now, let’s implement this little shader!
First of all, we need to declare some global variables in our 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 is our rendered scene, fTimer is our timer, fNoiseAmount is a value that indicates how much the scene will be distorted. A value between 0.001 to 0.5 is pretty good, and lastly, our seed value that will be used when calculating the noise.
 
Next, we need to add some logic to our pixel shader. First of all, we need to calculate our noise factor:
float NoiseX = iSeed * fTimer * sin(Tex.x * Tex.y+fTimer);

NoiseX=fmod(NoiseX,8) * fmod(NoiseX,4);

This is just a "random" math formula that takes our seed, timer and the texture coordinates to make the random value different between our pixels. Feel free to play with this in order to archive differnt effects.
 
We are also using a new function here: fmod(x,y).
This function returns the floating-point reminder of x diveided by y.
 
Next, we need to calculate how much the distortion will affect each x and y component. We want these to be slightly different to make it look a little randomized:
float DistortX = fmod(NoiseX,fNoiseAmount);
float DistortY = fmod(NoiseX,fNoiseAmount+0.002);
 
Now, we got what we need to create our new texture coordinates:
float2 DistortTex = float2(DistortX,DistortY);
 
And, lastly, use the new distrot texture coordinate with the old texture coordinate to end up with a slightly distorted texture coordinate:

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

 

This is our post process 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();
 }
}

NOTE:
You might have noticed that I have not used effect.commitChanges(); in this code. If you are rendering many objects using this shader, you should add this code in the pass.Begin() part so the changed will get affected in the current pass, and not in the next pass. This should be done if you set any shader paramteres inside the pass.

YouTube – XNA Shader programming, Tutorial 12 – Pixel distortion post process
  

This entry was posted in XNA Shader Tutorial. Bookmark the permalink.

8 Responses to XNA Shader Programming – Tutorial 12, Post process Noise

  1. Petri says:

    No problem, I\’m glad its helping someone 😉

  2. Hoàng Anh says:

    Thank Petri ! I learned alot from your tutorial.^^

  3. Steve Jones says:

    Thank you Petri for taking the time to come up with these tuts! I’d love to see one similar to this one except it gives varying levels of “snow” over the scene as a post-process effect. Think of this as an analog TV signal degradation effect. The more the signal degrades the more “snow-like” noise pixels show up covering the scene.

  4. Steve Jones says:

    TV static or loss of signal at a 100% loss looks like this

    I need controllable varying loss from 0 loss to 100%, looking sort of like that youtube video. I only need monochrome. Any ideas? (noob to shaders or I’d try to hack it out)

  5. Guadalupe says:

    An impressive share, I just given this onto a colleague who was doing just a little evaluation on this.
    And he actually bought me breakfast as a result of I
    found it for him.. smile. So let me reword that: Thnx for the
    treat! However yeah Thnkx for spending the
    time to debate this, I really feel strongly about it and love studying more
    on this topic. If doable, as you turn into expertise, would you thoughts updating your weblog with extra particulars?
    It’s extremely helpful for me. Huge thumb up for this weblog submit!

  6. Janis says:

    Excellent post. Keep writing such kind of information on
    your site. Im really impressed by it.
    Hey there, You’ve done a great job. I’ll certainly digg it
    and individually recommend to my friends. I’m confident they’ll be benefited from this web site.

  7. twobob says:

    Error 1 Errors compiling \Projects\Tutorial12_PostProcess\Tutorial12_PostProcess\Content\Shader.fx:

    \Projects\Tutorial12_PostProcess\Tutorial12_PostProcess\Content\Shader.fx(41,5): error X3000: syntax error: unexpected token ‘VertexShader’

    Visual Studio 2010 or 2012 XNA 4.0

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.