Silverlight HLSL实现背景滚动
一个Silverlight HLSL的简单例子,通过HLSL实现图片上的像素点的的水平移动,从而实现一个滚动背景的效果。
首先把Shader写出来吧。我这里借助了Shazzam ,界面如下:
下面是我的HLSL:
sampler2D input : register(s0); // new HLSL shader /// <summary>Explain the purpose of this variable.</summary> /// <minValue>05/minValue> /// <maxValue>10</maxValue> /// <defaultValue>3.5</defaultValue> float time:register(c0); float4 main(float2 uv : TEXCOORD) : COLOR { float4 Color; if(uv.x-time%1>=0) uv.x=uv.x-time%1; else uv.x=1+uv.x-time%1; Color= tex2D( input , uv.xy); return Color; }
主要原理是控制UV的X在0~1之间不断循环。
放到Silverlight项目中。把工具生成的代码也放进去。
public class PixelMovieEffect : ShaderEffect { public static readonly DependencyProperty TimeProperty = DependencyProperty.Register("Time", typeof(double), typeof(PixelMovieEffect), new PropertyMetadata(((double)(3.5)), PixelShaderConstantCallback(0))); public PixelMovieEffect() { PixelShader pixelShader = new PixelShader(); pixelShader.UriSource = new Uri("/SLPixelMove;component/Content/Shader/PixelMove.ps", UriKind.Relative); this.PixelShader = pixelShader; this.UpdateShaderValue(TimeProperty); } public double MoveX { get { return ((double)(this.GetValue(TimeProperty))); } set { this.SetValue(TimeProperty, value); } } }
编译一下,如果没问题的话就可以用了。编译之后我们就可以了Blend的资产面板中使用这个Effect了,如下:
把Effect拖到要实现效果的地方(如:这里的图片),XAML如下:
<Grid x:Name="LayoutRoot"> <Canvas x:Name="cavRender" Margin="20" Background="#FF464D9D"> <Image Height="204" Width="599" Source="Content/Images/sky.png" Stretch="Fill" Canvas.Top="-1"> <Image.Effect> <local:PixelMovieEffect x:Name="effSky"/> </Image.Effect> </Image> <Image x:Name="imgSky" Height="232" Width="600" Canvas.Top="127" Source="Content/Images/ground.png" Stretch="Fill"> <Image.Effect> <local:PixelMovieEffect x:Name="effGround"/> </Image.Effect> </Image> </Canvas> <Button x:Name="btnRun" Height="31" Width="116" Canvas.Left="238" Canvas.Top="365" Content="滚动" Margin="262,0,262,55" VerticalAlignment="Bottom" d:LayoutOverrides="Height"/> </Grid>
C#如下:
public partial class MainPage : UserControl { bool blnRolling = false; public MainPage() { InitializeComponent(); CompositionTarget.Rendering += (Robject, Re) => { if (blnRolling) { effGround.MoveX += 0.005; effSky.MoveX += 0.007; } }; btnRun.Click += (Cobject, Ce) => { blnRolling = !blnRolling; if (blnRolling) { btnRun.Content = "停止"; } else { btnRun.Content = "滚动"; } }; } }
可以下载附件中的源码查看效果,由于没处理好图片,所以看起来有点问题,换上一个好的图的话,应该效果还是不错的。