经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
WPF网格类型像素着色器
来源:cnblogs  作者:ggtc  时间:2024/7/1 11:29:09  对本文有异议

由于WPF只能写像素着色器,没法写顶点着色器,所以只能在这上面做文章了
刚好有个纹理坐标TEXCOORD输入可用,而且值的范围是已知的0-1,左上角是原点,这就好办了

例子

索引

二分网格

  • 使用ceil
  • 0-1移动定义域到-0.5 - 0.5,然后向上取整变成 0 / 1
  1. float4 main(float2 uv : TEXCOORD) : COLOR
  2. {
  3. float ab = ceil( uv.y-0.5 );
  4. return float4(ab,ab,ab,1.0);
  5. }

image

4分网格

  • 使用ceil
  • 0-1,先放大定义域0-4,然后向左移动定义域,-0.5 - 3.5,向上取整 0/1/2/3,最后压缩0/0.25/0.5/0.75/1
  1. float4 main(float2 uv : TEXCOORD) : COLOR
  2. {
  3. float ab = ceil( uv.y*4-0.5 );
  4. float scale=ab/4;
  5. return float4(scale,scale,scale,1.0);
  6. }

image

二值化多分网格

  • 使用sin round
  • 利用周期函数把定义域0-1范围的周期调整到指定数,然后值域压扁-0.5 - 0.5,向上移动0-1,四舍五入二值化
  1. //三角函数是天然的周期函数
  2. float4 main(float2 uv : TEXCOORD) : COLOR
  3. {
  4. float num=6;
  5. float2 ab = 0.5*sin(uv*3.1415*num )+0.5;
  6. float2 scale=round(ab);
  7. return float4(scale.y,scale.y,scale.y,1.0);
  8. }

image

二值化方格

  • 使用sin round abs
  • 在上一篇基础上,相乘生成纵横条纹。但这形成十字条纹,为了产生交错条纹,就不能相乘,只能相加
  1. float4 main(float2 uv : TEXCOORD) : COLOR
  2. {
  3. float num=7;
  4. float abx = 0.5*sin(uv.x*3.1415*num )+0.5;
  5. float aby = 0.5*sin(uv.y*3.1415*num )+0.5;
  6. float scale=abs((round(abx)/2)+(round(aby)/2)-0.5);
  7. //0.4是避免浮点数精度问题,否则直接用round(scale)
  8. float scale2=ceil(scale-0.4);
  9. return float4(scale2,scale2,scale2,1.0);
  10. }

image

动态方格

  • 使用sin round abs
  1. /// <summary> time </summary>
  2. /// <minValue>0</minValue>
  3. /// <maxValue>100</maxValue>
  4. /// <defaultValue>0</defaultValue>
  5. float time : register(C0);
  6. float4 main(float2 uv : TEXCOORD) : COLOR
  7. {
  8. float num=7;
  9. float abx = 0.5*sin(uv.x*3.1415*num+time )+0.5;
  10. float aby = 0.5*sin(uv.y*3.1415*num )+0.5;
  11. float scale=abs((round(abx)/2)+(round(aby)/2)-0.5);
  12. float scale2=ceil(scale-0.4);
  13. return float4(scale2,scale2,scale2,1.0);
  14. }

image

线框网格

  • 使用sin abs max step
  • 将周期函数取绝对值,变成一个个山峰,然后下沉,利用一个阈值,过滤出山尖
  1. float4 main(float2 uv : TEXCOORD) : COLOR
  2. {
  3. float gridLines = 11;
  4. float gridLineX = step(0.99, abs(sin(uv.x * 3.1415 * gridLines)));
  5. float gridLineY = step(0.99, abs(sin(uv.y * 3.1415 * gridLines)));
  6. float4 color = float4(max(gridLineX,gridLineY) , max(gridLineX,gridLineY) , max(gridLineX,gridLineY) , 1.0);
  7. return color;
  8. }

image

线框网格上滚动的小球

  • 使用sin abs max step
  • 在前一篇基础上,再传入鼠标位置,并再鼠标周围画一个白色圆形,覆盖线框颜色设置。使用语义VPOS获取像素位置判断和鼠标距离
  1. float2 mousePosition : register(C0);
  2. float4 main(float2 uv : TEXCOORD,float2 positon : VPOS) : COLOR
  3. {
  4. float gridLines = 11;
  5. float gridLineX = step(0.99, abs(sin(uv.x * 3.1415 * gridLines)));
  6. float gridLineY = step(0.99, abs(sin(uv.y * 3.1415 * gridLines)));
  7. float maxline=max(gridLineX,gridLineY);
  8. float innerCircle = 1.0 - step(50,length(positon-mousePosition));
  9. float maxResult=max(maxline,innerCircle);
  10. float4 color = float4(maxResult , maxResult , maxResult , 1.0);
  11. return color;
  12. }

image

鼠标操控小球

  1. public class MouseCaptureEffect : ShaderEffect
  2. {
  3. public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(MouseCaptureEffect), 0);
  4. public static readonly DependencyProperty MousePositionProperty = DependencyProperty.Register("MousePosition", typeof(Point), typeof(MouseCaptureEffect), new UIPropertyMetadata(new Point(0D, 0D), PixelShaderConstantCallback(0)));
  5. public MouseCaptureEffect()
  6. {
  7. PixelShader pixelShader = new PixelShader();
  8. pixelShader.UriSource = new Uri("pack://application:,,,/你的程序集名称;component/路径/TextEffect3.ps", UriKind.Absolute);
  9. this.PixelShader = pixelShader;
  10. this.UpdateShaderValue(InputProperty);
  11. this.UpdateShaderValue(MousePositionProperty);
  12. }
  13. public Brush Input
  14. {
  15. get
  16. {
  17. return ((Brush)(this.GetValue(InputProperty)));
  18. }
  19. set
  20. {
  21. this.SetValue(InputProperty, value);
  22. }
  23. }
  24. /// <summary> mouse </summary>
  25. public Point MousePosition
  26. {
  27. get
  28. {
  29. return ((Point)(this.GetValue(MousePositionProperty)));
  30. }
  31. set
  32. {
  33. this.SetValue(MousePositionProperty, value);
  34. Debug.WriteLine("aaa");
  35. }
  36. }
  37. }
  1. <Button Content="Btn">
  2. <Button.Effect>
  3. <local:MouseCaptureEffect x:Name="me" MousePosition="{Binding MousePositionw,Mode=TwoWay}" >
  4. </local:MouseCaptureEffect>
  5. </Button.Effect>
  6. </Button>
  1. this.MouseMove += (sender, e) =>
  2. {
  3. //这行代码不管用
  4. //MousePositionw = e.GetPosition(this);
  5. // 更新鼠标位置
  6. me.MousePosition= MousePositionw;
  7. };

要注意的时,通过绑定的方式更新没成功,只好手动赋值,不知道哪里出问题了(找到原因了,我把绑定ownerClass写错了)
image

原文链接:https://www.cnblogs.com/ggtc/p/18275543

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号