原文:First Look: Microsoft Silverlight 3
你也许已经对WPF中的像素渲染器很熟悉了。像素渲染器就是一组可以用来计算在屏幕上的图片的颜色的软件操作指南。它们直接对图形处理器(GPU)进行操作,速度非常快。它们使用一种叫做HLSL的描影法语言写的,这种语言在语法上与C非常类似。
在System.Windows.Media.Effects类库下包含了一些内置的渲染器来进行模糊和投下阴影的操作,而且在代码中或者在XAML里他们可以通过Effect属性来添加到图片上。
以下是示例:
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
Width ="300" Height ="800" >
< Canvas x:Name ="LayoutRoot" Background ="White" >
< Image x:Name ="img1" Source ="bull.jpg" Width ="200" Height ="200"
Canvas.Top ="0" Canvas.Left ="50" >
</ Image >
< Image x:Name ="img2" Source ="bull.jpg" Width ="200" Height ="200"
Canvas.Top ="250" Canvas.Left ="50" >
< Image.Effect >
< BlurEffect Radius ="10" ></ BlurEffect >
</ Image.Effect >
</ Image >
< Image x:Name ="img3" Source ="bull.jpg" Width ="200" Height ="200"
Canvas.Top ="450" Canvas.Left ="50" >
< Image.Effect >
< DropShadowEffect ShadowDepth ="10" ></ DropShadowEffect >
</ Image.Effect >
</ Image >
</ Canvas >
</ UserControl >
你可以在图7中看到这段代码的效果。
图7 使用内置的模糊(Blur)和阴影(Drop Shadow)效果
你可以使用HLSL来编写你自己的渲染器。本书不会介绍关于这方面的详细的内容,但是作为演示以下我们可以来看一个简单的例子。
在WPF(和Silverlight)中这些效果通常被写成.FX文件。以下是如何让一张图片获得变灰暗的效果的示例:
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(implicitInput, uv);
float4 complement;
complement.rgb = color.r*.3 + color.g*.59 + color.b*.11;
complement.a = color.a;
return complement;
}
这段代码通过找到像素的颜色,然后用一个小数乘以它的红、绿和蓝的值。这个例子将红色的强度减小到了30%,绿色减小到59%,蓝色11%。
这段HLSL代码被编译成一个PS文件(通常储存在一个.fx文件中)以供Silverlight程序使用。这可以通过DirectX SDK中的"fxc"工具来实现。
然后你可以创建一个继承自ShaderEffect的类,然后像以下的例子一样创建一个刷子(Brush)。注意PixelShader里使用的URISource要指向那个编译的ps文件。
{
private static PixelShader _pixelShader = new PixelShader() { UriSource = new
Uri( " ps/Greyeffect.ps " , UriKind.RelativeOrAbsolute) };
public static readonly DependencyProperty InputProperty =
ShaderEffect.RegisterPixelShaderSamplerProperty( " Input " , typeof (ApplyGreyEffect), 0 );
public ApplyGreyEffect()
{
PixelShader = _pixelShader;
UpdateShaderValue(InputProperty);
}
public Brush Input
{
get { return (Brush)GetValue(InputProperty); }
set { SetValue(InputProperty, value); }
}
}
现在你可以在代码中将这个自定义的类当做一个渲染器来使用。
Img1.Effect = _effect;