一个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;elseuv.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 = "滚动";}};}
}
可以下载附件中的源码查看效果,由于没处理好图片,所以看起来有点问题,换上一个好的图的话,应该效果还是不错的。
源码:附件:SLPixelMove.rar