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