在玩很多flash网页游戏的时候,看到它们都有非常清晰的宋体字,并且有漂亮的描边效果。如图,这是战将传奇的登录界面中的文字。

对比之下,silverlight要弄文字可让人头痛无比,别的不说,默认的字体怎么看怎么歪瓜裂枣。我就不贴图了,大家都明白。

那么怎么办捏,我们要祭出法宝:像素着色器!

  • 需要的工具:Shazzam Shader Editor 。
    这个是调试Silverlight着色器的神器。只要下载安装了它,其他的一切都好办了。
  • 简单介绍一下像素着色器的工作原理。
    对某个UIElement应用一个Effect,可以是自定义的。UIElement最终会呈现为一个位图。这个位图会被当成参数传入我们编写的着色器。着色器程序入口有一个参数,是当前的像素位置,另外还有一个注册的传入的位图。程序要求返回一个颜色,就是指定当前像素的颜色。 程序执行一次,只能对传入的当前像素进行着色,但是,有几个像素着色器程序就会执行几次,并且各个像素之间不冲突。所以,GPU硬件往往会并行计算。
    因此,如果我们写一个最最简单的着色器,就是不管3721,一律返回红色,那么这个UIElemnet就会被画成一个红色方块。
  • 首先我们打开Shazzam Shader Editor.然后新建一个Shader。这个时候就已经给建立了一个默认的将原输入图像原封不动地输出的Shader。事实上我们只要将return 改为return float4(1,0,0,1),就会输出一个红色矩形。
    解释一下主要语句的功能:

    • sampler2D input : register(s0);              注册输入的位图参数。
      float          a:register(c1);                     注册一个输入的浮点型参数。

      float4        c:register(c2);                      注册一个输入的颜色。

      一个float4类型里面包括了4个浮点数。 可以用rgba来访问,比如说, c.r ,c.g 等。 其中颜色的各分量都是 0-1之间而不是 0-255,这个要注意。

      以上这三种类型可以在silverlight里当参数传进来。 其中smpler2D就是一个bursh, float就是一个浮点数, float4就是一个Color。

      float2    包含两个浮点数的类型, 一般用作坐标。在main函数有一个传入的参数,类型就是float2 . 有x,y两个成员用以访问2个浮点数。传入的坐标的x,y分量都是在0-1之间,也就是说,把位图的宽和高都映射到0-1之间了。 如果我们知道位图的实际宽度的话,用 x,y乘以 宽或高,才能得到实际的像素位置。

      tex2D函数:  接收一个 sampler2D 和一个 float2 的坐标 。 返回sampler2D这个位图的制定位置的颜色。

  • 知道了以上这些语句,我们就可以动手写着色器了。
    我们的目的,就是要进行文字描边。假定我们只会对TextBlock应用这个着色器,那么有如下事实:TextBlock是一个矩形。文字所在像素的 alpha分量必定大于0,否则必定是透明像素。
    我们要做这样一件事,就是如果当前像素的上,下,左,右任意一个像素不透明,那么说明本像素需要被描边,否则就输出文字颜色。
    由于需要知道相邻像素,所以还需要传入TextBlock的ActualWidth和ActualHeight。 这样, 当前位置的 x+ 1/width 就是相邻像素的坐标,我们可以用tex2D函数来提取它的颜色值。
    还需要输入描边的颜色,还有文字的颜色。
    因此,废话不多说了,直接上着色器代码了:
  •  1 sampler2D input : register(s0);  //输入的textblock
     2 
     3 float w:register(C0);                      //宽度
     4 
     5 float h:register(C1);                     //高度
     6 
     7 float4 fontcolor:register(C2);    //字体颜色
     8 
     9 float4 bordercolor:register(C3);   //描边颜色
    10 
    11 float4 main(float2 uv : TEXCOORD) : COLOR 
    12 { 
    13     //float3 rgb= bordercolor.rgb ;
    14 
    15     float4 Color; 
    16     Color= tex2D( input , uv.xy);    //提取当前像素颜色
    17     
    18     int i;
    19     
    20     
    21     for( i=1;i<2;i++ )                           //修改此循环,可以改动描边的宽度,不过,这里就1次就够了
    22     {
    23         if( Color.a==0   )
    24         {
    25             float4 c2;
    26             c2= tex2D( input, uv.xy +float2 (0,i/h) );    //提取下方像素
    27             
    28             if(  c2.a>0 )
    29             {
    30                 Color=bordercolor;       //描边
    31             }
    32             else
    33             {
    34                 c2= tex2D( input, uv.xy +float2 (0,-i/h) );    //提取上方像素 。。。如此这般,共提取4次。
    35                 if(  c2.a>0 )
    36                 {
    37                     Color=bordercolor;
    38                 }
    39                 else
    40                 {
    41                     c2= tex2D( input, uv.xy +float2 (i/w,0) );
    42                     if(  c2.a>0 )
    43                     {
    44                         Color=bordercolor;
    45                     }
    46                     else
    47                     {
    48                         c2= tex2D( input, uv.xy +float2 (-i/w,0) );
    49                         if(  c2.a>0 )
    50                         {
    51                             Color=bordercolor;
    52                         }
    53                     }
    54                 }
    55             }
    56         }
    57         else
    58         {
    59             float4 tempcolor = fontcolor;
    60             
    61             
    62             if( Color.a<0.1)            //由于SL对字体的反锯齿处理,这里有一个非常讨厌的现象:有半透明像素存在,经过测试,如果透明度在0.1一下,则判断为边,否则为字。
    63             {
    64                 tempcolor=bordercolor;
    65             }
    66             
    67             Color=tempcolor;
    68         }
    69     }
    70     
    71 
    72 
    73     return Color; 
    74 }
    75 

然后,按照深蓝的教程,将着色器代码转为Effect,即可使用。效果如下,哈哈,和flash是一模一样的吧

代码下载

转载于:https://www.cnblogs.com/ashei/archive/2011/02/12/1952243.html

Silverlight像素着色器编写简明指南 附送文字描边效果相关推荐

  1. WPF 像素着色器入门:使用 Shazzam Shader Editor 编写 HLSL 像素着色器代码

    HLSL,High Level Shader Language,高级着色器语言,是 Direct3D 着色器模型所必须的语言.WPF 支持 Direct3D 9,也支持使用 HLSL 来编写着色器.你 ...

  2. 着色器(Shader)之像素着色器

    像素着色器实际上就是对每一个像素进行光栅化的处理期间,在GPU上运算的一段程序. 不同与顶点着色器,像素着色器不会以软件的形式来模拟像素着色器. 像素着色器实质上是取代了固定功能流水线中多重纹理的环节 ...

  3. OpenGL ES像素着色器

    OpenGL ES像素着色器 原文   http://www.tairan.com/archives/7509 目 录 准备开始 像素着色器 vs 顶点/片段着色器 像素着色器101:渐变 像素着色器 ...

  4. OpenGL ES像素着色器教程

    OpenGL ES像素着色器教程 时间 2014-08-27 09:54:51   泰然 原文   http://www.tairan.com/archives/7509 主题  OpenGL ES ...

  5. 片元着色器(Fragment Shader)被称为像素着色器(Pixel Shader),但

    片元着色器(Fragment Shader)被称为像素着色器(Pixel Shader),但片元着色器是一个更合适的名字, 因为此时的片元并不是一个真正意义上的像素.

  6. 多重纹理——像素着色器

    上午花了几个小时仔细研究了一下像素着色器中的多重纹理,由于对固定流水线比较熟悉,所以看这本书看的比较快.下面就来解析一下这个多重纹理,对于一些不太明白的东西也做一下讨论: 1.利用DirectX Ca ...

  7. D3Dshader,像素着色器实现黑白、复古、反色特效。

    HLSL像素着色器实现黑白.复古.反色特效 目录 黑白 复古 反色 目录 三种非常简单且容易实现的滤镜效果. 黑白 黑白:也就是灰度图,需要将像素着色器中R.G.B三个颜色分量用同一个灰度值Grey来 ...

  8. 着色器实例 代码+注释 更新中【描边、卡通渲染、法线颜色、贴图动画等等】

    描边着色器 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader " ...

  9. 《Unity着色器和屏幕特效开发秘笈》—— 2.5 法线贴图

    本节书摘来自华章出版社<Unity着色器和屏幕特效开发秘笈>一 书中的第2章,第2.5节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区"华章计算机&quo ...

  10. shader变体是什么_[Unity/shaderlab]关于着色器变体

    在Unity中可以通过#pragma multi_compile或者#pragma shader_feature指令来实现着色器多样化. 在运行时,相应的着色器变体是从材质的关键词中取得的(Mater ...

最新文章

  1. 微服务平台的发展趋势
  2. win7+iis7.5下的asp.net网站发布系列问题
  3. python项目简历内容包括哪些方面_简历的基本信息包括哪些?
  4. 进度条设置_项目功能分解4:MATLAB GUI如何设计有特色的进度条。
  5. 0003 无重复字符的最长子串
  6. 常用贴片三极管参数于常见三极管型号对照表
  7. 前端学习(736):函数的返回值return
  8. __dopostback
  9. java凉的可能性,薄荷凉茶一凉到底
  10. 教你轻松计算AOE网关键路径(转)
  11. SharePoint 2013 中的新增功能(与开发有关)
  12. kali Linux 系统安装教程
  13. Host Windows 配置
  14. [css文字单行省略与多行省略]
  15. flutter 斗音页面
  16. 感恩与祝福——与巴铁兄弟的友情告别
  17. 【SecureFx服务器无法上传文中文件】
  18. Lucene根据字段进行自定义搜索扩展
  19. hrbust 2188 星际旅行
  20. 让人发狂的sql语句!

热门文章

  1. python使用ip代理抓取网页
  2. HDU 3480 Division(斜率DP裸题)
  3. 在Ubuntu下搭建Spark群集
  4. 20145239杜文超 《Java程序设计》第3周学习总结
  5. Notification的使用,以及他的监听方法
  6. c#.net常用函数列表
  7. 动机才是需求,问题只是现象
  8. 「版本升级」MyEclipse CI 2018.12.0正式发布
  9. [leetcode] 406. Queue Reconstruction by Height (medium)
  10. Altium Designer四层板起步