Silverlight HLSL实现背景滚动

一个Silverlight HLSL的简单例子,通过HLSL实现图片上的像素点的的水平移动,从而实现一个滚动背景的效果。

首先把Shader写出来吧。我这里借助了Shazzam ,界面如下:

Shazzam 界面.jpg

下面是我的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了,如下:

 

资产面板.jpg

把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

posted @ 2009-12-18 09:22  齐.net  阅读(844)  评论(0编辑  收藏  举报