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

  • 时间:
  • 浏览:0
  • 来源:大发5分快乐8_大发5分快乐8官方

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

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

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 );

}

 再来瞅瞅源代码:

3 remainderL的关系图

熟悉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源代码进行研究和学习,从而不断的提高个人。

图2 带状螺旋效果图

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

//--------------------------------------------------------------------------------------

// 全局变量,供应用进程设置,在Silverlight中动态改变哪几种参数便成了动画

//--------------------------------------------------------------------------------------

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

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

其中提供了18Shader

图1 Shader列表

4 facremainder的关系图

//定义了2D采样器,之后应用在MediaElement上得话,MediaElement的实时画面便是采样器的内容,存放上临时寄存器S0中。

sampler2D implicitInputSampler : register(S0);

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

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

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

//定义螺旋效果的中心点,默认是(0.5,0.5),存放上常量寄存器C0里

float2 center : register(C0);

//定义螺旋效果的波特率

float spiralStrength : register(C1);

//距离的阈值

float distanceThreshold : register(C2);

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

好像ps_3_0只有 这类 限制,之后SL貌似只支持ps_2_0,这类 还是精炼下个人的代码吧。

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

总结一下心得:

//--------------------------------------------------------------------------------------

// 像素着色器

//--------------------------------------------------------------------------------------