开发者社区> 杰克.陈> 正文

【HLSL学习笔记】WPF Shader Effect Library算法解读之[BandedSwirl]

简介: 原文:【HLSL学习笔记】WPF Shader Effect Library算法解读之[BandedSwirl] 因工作原因,需要在Silverlight中使用Pixel Shader技术,这对于我来说可算是相当有难度了,首先我是个Java Web开发程序员,从来没正经地学过微软的开发语言和工具;其次,对于算法这种东西,向来有种天生的排斥,一看便头疼。
+关注继续查看
原文:【HLSL学习笔记】WPF Shader Effect Library算法解读之[BandedSwirl]

因工作原因,需要在Silverlight中使用Pixel Shader技术,这对于我来说可算是相当有难度了,首先我是个Java Web开发程序员,从来没正经地学过微软的开发语言和工具;其次,对于算法这种东西,向来有种天生的排斥,一看便头疼。不过项目逼到份上了,只能硬着头皮上,真不知道领导们是怎么想的。还是言归正传吧,记录记录自己的学习心得。

熟悉Silverlight的人都知道,SL中有一物名为Pixel Shader,江湖人称像素着色器。是Sl中可以单独操控像素的一门技术。SL3中集成了两个Shader,一为DropShadowEffect,二谓BlurEffect,可为用户产生投影与模糊的效果。此外,MS还为程序员开辟了自定义通道,程序员可以自行编写Shader文件,并通过C#封装,最终应用在SL中。而编写Shader文件则需要采用HLSL(高级着色器语言High-Level-Shader-Language),正如当年新手上路用文本文件编写JavaHelloWorld程序一样,Shader同样可以用文本文件编写,同样可以用命令行编译。本文是我工作中的一些琐碎的片段,主要针对的是开源的WPF Pixel Shader Effect Library项目中的Shader源代码进行研究和学习,从而不断的提高自己。

项目地址为:http://wpffx.codeplex.com/

其中提供了18Shader

 

图1 Shader列表

 

初学Shader,不知从何做起,前人有高质量的代码,何不直接取来,参详研习。这两天刚开始研究BandedSwirl.fx,做点记录:

有必要说的是逆向的解读别人的算法是一个非常痛苦的过程,只有通过特效展示结合算法文件自己去构建算法模型方可,至少这是我笨人所采用的笨办法:)

BandedSwirl直译的话应该叫做【带状螺旋】效果,初见时觉得挺震撼,觉得这种算法程序应该很长才是,没想到不过区区30行左右,可见Shader编程之精炼。先看看效果截图:

 再来瞅瞅源代码:

图2 带状螺旋效果图

 

 

//++++++++++++++++++++++++++++++SRC+++++++++++++++++++++++++++++
//--------------------------------------------------------------------------------------
// 全局变量,供应用程序设置,在Silverlight中动态改变这些参数便成了动画
//--------------------------------------------------------------------------------------

//定义螺旋效果的中心点,默认是(0.5,0.5),存放在常量寄存器C0里
float2 center : register(C0);
//定义螺旋效果的强度
float spiralStrength : register(C1);
//距离的阈值
float distanceThreshold : register(C2);

//定义了2D采样器,如果应用在MediaElement上的话,MediaElement的实时画面便是采样器的内容,存放在临时寄存器S0中。
sampler2D implicitInputSampler : register(S0);

//--------------------------------------------------------------------------------------
// 像素着色器
//--------------------------------------------------------------------------------------

float4 main(float2 uv : TEXCOORD) : COLOR
{
 //定义2d向由中心指向某一纹理坐标的向量
   float2 dir = uv - center;
   //求取向量的长度,l的值域为[0,√2/2]
   float l = length(dir);
   //向量除以自己的长度就是单位向量,只用于表示方向
   dir = dir/l;
   //求取向量和水平线的夹角,这里值域为[-PI/2,PI/2]
   float angle = atan2(dir.y, dir.x);
//为了进行交替的螺旋对流,避免采用类似for循环的流程控制语句,导致额外的性能耗费,需要用一个值来控制螺旋对流的循环周期,这里采用了一个名为距离阈值的参数,remainder和l的关系图为一组周期为distanceThreshold的三角波,见图3
  //值域为[0,1]
   float remainder = frac(l / distanceThreshold);
   //该参数是为了让螺旋周期内两路相反带装束过渡的更为平滑,在波形图上看就是为了让波形连续。
   float preTransitionWidth = 0.25;
   //定义一个参数,控制每个螺旋周期内的对流,每个漩涡周期内共有两路正向带状束和一路反向带装束,分别交替呈现。Fac和remainder的关系见图4
   float fac;  
   //控制对流方向的交替以及波形的连续
   if (remainder < .25)
   {
      fac = 1.0;
   }
   else if (remainder < 0.5)
   {
      fac = 1 - 8 * (remainder - preTransitionWidth);
   }
   else if (remainder < 0.75)
   {
      fac = -1.0;
   }
   else
   {
      fac = -(1 - 8 * (remainder - 0.75));
   }
   //计算基于参数【螺旋强度】的变换角度,意思就是在原来向量方向的基础上正向或者反向增大扭曲角度
   float newAng = angle + fac * spiralStrength * l;
   //按照螺旋强度计算出来的变换角度重新定义纹理坐标
   float xAmt = cos(newAng) * l;
   float yAmt = sin(newAng) * l;
     
   float2 newCoord = center + float2(xAmt, yAmt);
   //按照新的纹理坐标对原来的采样器进行纹理的渲染,得出最终的结果
   return tex2D( implicitInputSampler, newCoord );
}

//++++++++++++++++++++++++++++++SRC+++++++++++++++++++++++++++++

 

3 remainderL的关系图

4 facremainder的关系图

 

到这里也算大致搞明白这个算法的原理了,对于我来说,算是费了九牛二虎。从中也学到不少,以前自己写HLSL的时候,总喜欢用for循环来控制流程,比如要写一个百叶窗,首先想到的就是设定百叶窗的间隔,然后用1/间隔当做循环次数,每次用HLSLTester都勉强能编译过去,但是一旦到了要编译成ps_2_0ps文件时总会报错,意思是每个Shader只允许64条汇编指令,超出这个数量就编译不过去。想想若是把for循环转变成汇编语言,会产生多少指令啊,效率能不低吗!!!

好像ps_3_0没有这个限制,但是SL貌似只支持ps_2_0,所以还是精炼下自己的代码吧。

总结一下心得:

1、  Shader最好用向量,少用标量

2、  诸如fordo-while这一类的循环尽量少用

 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
一些WPF中的滤镜特效——Effect Library
原文:一些WPF中的滤镜特效——Effect Library WPF支持类似PhotoShop的滤镜功能,称之为Effect。在.Net 4.0中,WPF就废弃了对BitMapEffect的支持,转向使用支持GPU加速的Effect类,例如,我们可以使用如下代码生成带有阴影效果的按钮。
1258 0
【HLSL学习笔记】WPF Shader Effect Library算法解读之[Embossed]
原文:【HLSL学习笔记】WPF Shader Effect Library算法解读之[Embossed] Embossed(浮雕效果)          浮雕效果主要有两个参数:Amount和Width。
1014 0
【HLSL学习笔记】WPF Shader Effect Library算法解读之[DirectionalBlur]
原文:【HLSL学习笔记】WPF Shader Effect Library算法解读之[DirectionalBlur] 方位模糊是一个按照指定角度循环位移并叠加纹理,最后平均颜色值并输出的一种特效。
722 0
WPF 心形线算法
原文:WPF 心形线算法 今天在网上查找下心形算法公式,自己便按照公式写下来标记在博客,主要是方便以后查看! private int maxStep = 520; private double radius; private double cen...
913 0
VSTO学习笔记(七)基于WPF的Excel分析、转换小程序
原文:VSTO学习笔记(七)基于WPF的Excel分析、转换小程序 近期因为工作的需要,要批量处理Excel文件,于是写了一个小程序,来提升工作效率。 小程序的功能是对Excel进行一些分析、验证,然后进行转换。
1196 0
WPF学习笔记:MVVM模式下,ViewModel如何关闭View?
原文:http://blog.csdn.net/leftfist/article/details/32349731 矫枉过正,从一个极端走向另一个极端。MVVM模式,View只负责呈现,虽然也有后台代码,但基本上就是摆设,VM接管了一切的逻辑处理。
880 0
WPF的Binding学习笔记(三)
在笔记(一)中记了点Binding的Path相关, 因为Binding的带参构造器就只有Path的参数. 所以Path是很重要的, 有了Path, 即使在没有指定Source的时候, Binding也会随着UI元素树一层一层往外找DataContext对象, 判断是否具有相应的Path, 有就拿来用.
637 0
WPF的Binding学习笔记(二)
上次学了点点Binding的皮毛, 然后就做别的事去了, 等回头再来看WPF的时候, 哈忘记了~ 于是写个例子补一下, 在继续学习Binding. 1, 首先准备好一个类 public class Hero {   public Hero(int id, string name, string skill, bool hasM)   {     this.
729 0
+关注
杰克.陈
一个安静的程序猿~
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
阿里技术参考图册-算法篇
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
相关实验场景
更多