Hi, and welcome to Tutorial 22 of my XNA Shader Programming tutorial. Today I will present to you the 2nd transition tutorial, where I will play one scene, and then fade in to another one using a simple post process shader!
The effect we will see today is a basic transition effect, where the scene transition will "cross" into another one.
The cross transition will go from one scene into another one, using a "line" that is where the fade is.
In the figure below[22.1], scene B is playing, and scene A is crossing in, resulting in scene A playing.
As in tutorial 21, we need to have two textures in our shader, one for each scene you want to fade between, and then you will need to have a variable that will be used to tell how far in the fade we are.
This variable must be between 0 and 1, and when the variable is 0, Scene A will play, and when its 1, Scene B will play.
Lets start writing the cross-transition shader:
sampler ColorMapSampler : register(s0);
texture ColorMap2;
sampler ColorMapSampler2 = sampler_state
{
Texture = <ColorMap2>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
float fFadeAmount;
Here we define two texture samples, ColorMapSampler1 and ColorMapSampler2, and both will contain a scene that we will fade between using the variable named fFadeAmount. The texture samplers is defined in two different ways, and is explained in a previous tutorial.
Now, we are ready to implement the pixel shader.
// Transition
float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR
{
float4 Color = tex2D(ColorMapSampler, Tex);
float4 Color2 = tex2D(ColorMapSampler2, Tex);
float4 finalColor = lerp(Color,Color2,smoothstep(fFadeAmount,fFadeAmount+fSmoothSize,Tex.x));
// Set our alphachannel to fAlphaAmount.
finalColor.a = 1;
return finalColor;
}
This shader is almost exactly the same as the one in tutorial 21, except from the following line:
float4 finalColor = lerp(Color,Color2,smoothstep(fFadeAmount,fFadeAmount+fSmoothSize,Tex.x));
Here we use a function named smoothstep(a,b,x) that will return a value between 0 or one based on a,b, and x. The smoothstep function returns 0 when x is below a, and 1 when x is above b, and something in between when x is between a and b.

Fig 22.2
We then use the smoothstep, using Tex.x as x, and fFadeAmount as a, and fFadeAmount (fSmoothSize is set to 0) as b, making a sharp on the transition. You can use the fSmoothSize to make the transition smoother, making b larger than a.
This function will return [0,1] based on Tex.x, and use this as the control value in the lerp function, making a nice cross transition!
Note: When fSmoothSize is > 0.0, and fFadeAmount = 0, we will still be able to see fSmoothSize part of the scene displayed when fFadeAmount = 1, because our fade starts at fFadeAmount and stops at fFadeAmount( 0 ) + fSmoothSize.
Using the shader
When we want to use the shader, we will need to render the two scenes we want to fade between in to a texture, and pass them in to the shader:
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
{
// Apply the post process shader
float fadeBetweenScenes = ((float)Math.Sin(m_Timer) * 0.5f) + 0.5f;
effectPost.Parameters["fFadeAmount"].SetValue(fadeBetweenScenes);
effectPost.Parameters["ColorMap2"].SetValue(Scene2Texture);
effectPost.CommitChanges();
effectPost.Begin();
{
effectPost.CurrentTechnique.Passes[0].Begin();
{
spriteBatch.Draw(SceneTexture, new Rectangle(0, 0, 800, 600), Color.White);
effectPost.CurrentTechnique.Passes[0].End();
}
}
effectPost.End();
}
spriteBatch.End();
What we do here is to use the texture set when rendering the sprite as SceneA and another texture set by a parameter to the shader as SceneB, and then we have a periodical function to fade between these based on a given timer, so fFadeAmount is somewhere between 0 and 1.