XNA Shader编程教程22 – 过渡:左右揭开
这是第二个过渡效果的教程,使用一个简单的post process shader从一个场景切换到另一个场景。
今天的effect是一个基本的过渡效果,一个场景会左右揭开(cross,译者注:这里不知道如何翻译,就借用power point中的说法了)至另一个场景。
Cross过渡
Cross过渡使用一根“线”分隔两个场景。在图22.1中,显示了场景B,而场景A正在向右移动。
实现shader
和教程21一样,我们需要两个纹理对应两个场景,你还需要一个变量指定淡入淡出的程度。这个变量必须在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的代码:
// 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; }
这个shader和教程21中的几乎是一样的,除了下列代码:
float4 finalColor = lerp(Color,Color2,smoothstep(fFadeAmount,fFadeAmount+fSmoothSize,Tex.x));
这里我们使用了一个叫做moothstep(a,b,x)的函数(译者注:这个函数的具体解释可见directX sdk,用法是smoothstep(min, max, x),如果x的范围是[min, max],则返回一个介于0和1之间的Hermite插值),这个函数会基于参数a,b,x返回一个介于0和1之间的值。当x小于a时返回0,当x大于b时返回1,当x介于a和b之间则返回一个介于0和1之间的值。
当使用smoothstep时,我们使用Tex.x作为x,fFadeAmount作为a,如果fFadeAmount (fSmoothSize设置为0)作为b,那么分割线会变得最清晰。你可以让fSmoothSize大于0使过渡更加平滑,这时b大于a。这个函数会基于Tex.x返回[0,1],可以将这个返回值作为lerp函数的控制参数,实现一个漂亮的过渡效果!
注意:当fSmoothSize大于0而fFadeAmount = 0时,我们仍能在fFadeAmount = 1时看到场景的fSmoothSize部分(译者注:此句好像不通,原文是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.),这是因为切换效果从 fFadeAmount 开始,fFadeAmount( 0 ) + fSmoothSize结束。
使用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之间变化。
译者注:你可以使用
float4 finalColor = lerp(Color,Color2,smoothstep(fFadeAmount,fFadeAmount+fSmoothSize,Tex.y));
让分割线上下移动;
使用
float4 finalColor = lerp(Color,Color2,smoothstep(fFadeAmount,fFadeAmount+fSmoothSize,Tex.x*0.5+Tex.y*0.5));
让分割线沿斜向45度移动,当然改变系数也可以改变对应的角度。 不知你是否有兴趣将power point中的所有过渡效果在shader中实现。
发布时间:2009/6/24 上午10:31:29 阅读次数:9693