zoukankan      html  css  js  c++  java
  • 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 } 

     下载示例

  • 相关阅读:
    一次维护经历
    网络线用色环表示
    ★★★错误终于抓到了★★★
    帮别人装IBM本本花了两天
    好记忆不如烂笔头
    凌晨完成的内容
    好久没上网了!
    oseye问答和博文评论通知的设计思路
    简单四步设置debian的vps安全防护
    javascript 的call()与apply()的应用与区别
  • 原文地址:https://www.cnblogs.com/ashei/p/1964731.html
Copyright © 2011-2022 走看看