Silverlight像素着色器文字描边效果-改

        上次的描边着色器有两个问题,导致效果不太理想。现在我们来设法改进这两点。

问题一:

当TextBlock的呈现宽度和高度没有正确赋值时,将无法正确计算像素宽度。
        但是,像素宽度其实根本不需要传进去, ShaderEffect 类有一个DdxUvDdyUvRegisterIndex 属性。此属性的msdn是这么解释的:
 


使用 DdxUvDdyUvRegisterIndex 属性指定包含纹理坐标对屏幕空间的偏导数的着色器寄存器。 例如,如果将 DdxUvDdyUvRegisterIndex 设置为 4,则使用着色器寄存器 c4。 寄存器 c4 包含四个浮点字段。下面的高级着色语言 (HLSL) 代码演示如何使用此寄存器。nextPixelUV 值表示右边的下一个像素。

float4 ddxUvDdyUv : register(c4);
SamplerState  sampler : register(S0);
...float2 nextPixelUV;
nextPixelUV.u 
= ddxUvDdyUv.x + u;
nextPixelUV.v 
= ddxUvDdyUv.y + v;

tex2D(sampler, nextPixelUV);

 

因此,我们压根就不需要传入什么宽度高度!

问题二: 

字体的半透明像素问题。由于字体的反锯齿,这些半透明像素是肯定会出现的。但是我们可以设想,我们的描边字体其实可以想象成是叠加在边框上的普通字体,那么这些半透明像素应该怎么办?当然是应该和边框颜色进行半透明混合啦!故此,改动着色器代码,现在无论TextBolck里的内容如何变化,都可以正确的描边了。

       最后特别推荐:汉字使用宋体字,在12,13号等大小下,出现透明像素最少。英文和数字的宋体效果非常一般,建议换其他字体如Arial等。可以自己在下面输入任意文字,查看描边效果。

 着色器代码:

 1 sampler2D input : register(s0);  
 2 
 4 
 5 
 6 
 7 float4 fontcolor:register(C0); 
 8 
 9 float4 bordercolor:register(C1); 
10 
11 float4 ddxUvDdyUv : register(c2);
12 
13 
14 float4 main(float2 uv : TEXCOORD) : COLOR 
15 
16    
17 
18     float4 Color; 
19     Color= tex2D( input , uv.xy);
20     
21     
22     float ix = length(ddxUvDdyUv.rg);
23         float iy = length(ddxUvDdyUv.ba);
24     
25     int i;
26     
27     
28    
29     {
30         if( Color.a==0   )
31         {
32             float4 c2;
33             c2= tex2D( input, uv.xy +float2 (0,iy) ); 
34             
35             if(  c2.a>0 )
36             {
37                 Color= bordercolor; 
38                 return Color; 
39             }
40             else
41             {
42                 c2= tex2D( input, uv.xy +float2 (0,-iy) ); 
43                 if(  c2.a>0 )
44                 {
45                     Color=bordercolor;;  
46                     return Color; 
47                 }
48                 else
49                 {
50                     c2= tex2D( input, uv.xy +float2 (ix,0) );
51                     if(  c2.a>0 )
52                     {
53                         Color=bordercolor;
54                         return Color; 
55                     }
56                     else
57                     {
58                         c2= tex2D( input, uv.xy +float2 (-ix,0) );
59                         if(  c2.a>0 )
60                         {
61                             Color=bordercolor;
62                             return Color; 
63                         }
64                     }
65                 }
66             }
67         }
68         else
69         {
70             
71                 float aa=1-Color.a; 
72             
73                 float4 tempcolor= float4(  (  fontcolor * Color.a + float4( bordercolor.rgb,Color.a)* aa )) ;
74             
75             
76             Color=tempcolor;
77         }
78     }
79     
80 
81 
82     return Color; 

83 } 

 下载示例

 

posted @ 2011-02-25 13:23  烙馅饼喽  阅读(2337)  评论(5编辑  收藏  举报