XNA Shader编程教程21-过渡:淡入淡出

今天的教程是一个过渡效果,先展示一个场景,然后使用一个简单的post process shader淡入淡出到另一个场景。
淡入淡出效果
淡入淡出效果可以在许多电影,游戏和power point演示中看到。先播放场景A,然后在场景A淡出的同时播放场景B,产生两个场景间平滑的淡入淡出效果。
这在许多场合是很有用的,例如游戏中的切换场景或从一个菜单切换到另一个菜单等。
实现shader
淡入淡出shader很容易实现,你可能会有几个解决方案。
在shader中需要两张纹理,每张对应一个场景,还需要一个变量决定淡入淡出的程度。这个变量必须在0和1之间,当为0时播放场景A,为1时播放场景B。
下面是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;
这里我们定义了两个纹理采样器,ColorMapSampler1和ColorMapSampler2,两者都包含一个场景,使用一个叫做fFadeAmount的变量实现两者的切换。纹理采样器可以使用两种不同的方式定义,这在前面的教程中已经解释过了。
现在我们已经做好了实现pixel shader的准备。因为这是一个post process shader,所以无需编写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;
}
这里我们做的就是从每个场景中提取颜色,并使用lerp函数混合这两个颜色。变量fFadeAmount控制渐淡的程度,0表示不减淡,显示场景SceneA,如果为0.3则减淡30%,同时显示场景A和B,其中场景A占70%,B占30%。(译者注:如果查看directX sdk,可知lerp函数的用法是:lerp(x, y, s),返回x + s(y - x))最后创建
technique: technique PostProcess
{
pass P0
{
// A post process shader only needs a pixel shader.
PixelShader = compile ps_2_0 PixelShader();
}
}
使用shader
使用shader时,我们需要将两个场景绘制到一张纹理中,并将它传递到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();
我们使用一张绘制场景A的纹理和另一张绘制场景B的纹理作为参数,并通过一个周期函数让变量fFadeAmount在0和1之间变化。
现在已经完成这个示例了,比起前面的教程其实并不难,对吗? ;)
发布时间:2009/6/24 上午10:09:34 阅读次数:10166
