XNA Shader Programming
Tutorial 21 – Transition: Fade
Hi, and welcome to Tutorial 21 of my XNA Shader Programming tutorial. Today I will present to you the first transition tutorial, where I will play one scene, and then fade in to another one using a simple post process shader!
The Fade transition
The fade transition can be seen in many movies, games and power point presentations( ++ ) when going from one scene/slide into another one. Scene A is playing, and then a new Scene B fades in while Scene A fades out, making a smooth fade between the scenes.
The fade transition can be seen in many movies, games and power point presentations( ++ ) when going from one scene/slide into another one. Scene A is playing, and then a new Scene B fades in while Scene A fades out, making a smooth fade between the scenes.
This can be very usefull in many different situations, like in your games cut-scenes or when moving from one menu to another and so on.
Implementing the shader
Ok, the fade transition shader is really easy to implement and you might allready have a few solutions on your head.
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 shader:
sampler ColorMapSampler : register(s0);
texture ColorMap2;
sampler ColorMapSampler2 = sampler_state
{
Texture = <ColorMap2>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
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. Remember, as this is a post process shader, we don’t need to write a custom vertex shader.
// Transition
float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR
{
float4 Color = tex2D(ColorMapSampler, Tex);
float4 Color2 = tex2D(ColorMapSampler2, Tex);
float4 finalColor = lerp(Color,Color2,fFadeAmount);
// Set our alphachannel to fAlphaAmount.
finalColor.a = 1;
return finalColor;
}
// Transition
float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR
{
float4 Color = tex2D(ColorMapSampler, Tex);
float4 Color2 = tex2D(ColorMapSampler2, Tex);
float4 finalColor = lerp(Color,Color2,fFadeAmount);
// Set our alphachannel to fAlphaAmount.
finalColor.a = 1;
return finalColor;
}
What we do here is to get the colors from each of the two scenes, and use lerp to mix them. the fFadeAmount variable is used to control where in the fade we are. 0 is 0% in the fade, displaying only SceneA. If it’s 0.3 we are 30% in the fade, displaying both SceneA and SceneB. SceneA will be 70% and SceneB will be 30% in the fade.
Finally, we need to create our technique:
technique PostProcess
{
pass P0
{
// A post process shader only needs a pixel shader.
PixelShader = compile ps_2_0 PixelShader();
}
}
{
pass P0
{
// A post process shader only needs a pixel shader.
PixelShader = compile ps_2_0 PixelShader();
}
}
And thats it for the Transition: Fade shader!
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;
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.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();
{
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.
And thats it for the Transition: Fade shader! Pretty easy compared to a few of the other shaders we have written, right? 😉
Any comments and feedback is greatly apprechiated!
YouTube – XNA Shader programming, Tutorial 21 – Transition: Fade
Download: Executable + Source
All of your tutorials are very helpful! Thank you very much !
Thank you very much for your shader programming tutorials. This is the BEST site i have come across to so with using shaders. It explains so much information and makes clear on many points that seem confusing to a beginner. I wish the “microsoft” XNA stuff was as good as yours.
Many thanks and keep up the fantastic work.
Steve
Hello, i’m writing to you because i have a doubt in here with shaders. As I can see, you fade from a texture to another, but what happens when you have in your screen 60 or 70 textures, as it happens when you end a stage of a game and want to shade to another screen. If these textures cannot be shaded with this method, the only way i see you can do this is to save your screen with every element in a texture and then shade it, but how can this be done??
Thank you very much!!