WPF网格类型像素着色器

由于WPF只能写像素着色器 ,没法写顶点着色器 ,所以只能在这上面做文章了

刚好有个纹理坐标TEXCOORD输入可用,而且值的范围是已知的0-1,左上角是原点,这就好办了

例子

索引

二分网格

  • 使用ceil

  • 0-1移动定义域到-0.5 - 0.5,然后向上取整变成 0 / 1

    float4 main(float2 uv : TEXCOORD) : COLOR
    {
    float ab = ceil( uv.y-0.5 );
    return float4(ab,ab,ab,1.0);
    }

4分网格

  • 使用ceil

  • 0-1,先放大定义域0-4,然后向左移动定义域,-0.5 - 3.5,向上取整 0/1/2/3,最后压缩0/0.25/0.5/0.75/1

    float4 main(float2 uv : TEXCOORD) : COLOR
    {
    float ab = ceil( uv.y*4-0.5 );
    float scale=ab/4;
    return float4(scale,scale,scale,1.0);
    }

二值化多分网格

  • 使用sin round

  • 利用周期函数把定义域0-1范围的周期调整到指定数,然后值域压扁-0.5 - 0.5,向上移动0-1,四舍五入二值化

    //三角函数是天然的周期函数
    float4 main(float2 uv : TEXCOORD) : COLOR
    {
    float num=6;
    float2 ab = 0.5sin(uv3.1415*num )+0.5;
    float2 scale=round(ab);
    return float4(scale.y,scale.y,scale.y,1.0);
    }

二值化方格

  • 使用sin round abs

  • 在上一篇基础上,相乘生成纵横条纹。但这形成十字条纹,为了产生交错条纹,就不能相乘,只能相加

    float4 main(float2 uv : TEXCOORD) : COLOR
    {
    float num=7;
    float abx = 0.5sin(uv.x3.1415num )+0.5;
    float aby = 0.5
    sin(uv.y3.1415num )+0.5;
    float scale=abs((round(abx)/2)+(round(aby)/2)-0.5);
    //0.4是避免浮点数精度问题,否则直接用round(scale)
    float scale2=ceil(scale-0.4);
    return float4(scale2,scale2,scale2,1.0);
    }

动态方格

  • 使用sin round abs

    ///

    time
    /// <minValue>0</minValue>
    /// <maxValue>100</maxValue>
    /// <defaultValue>0</defaultValue>
    float time : register(C0);
    float4 main(float2 uv : TEXCOORD) : COLOR
    {
    float num=7;
    float abx = 0.5sin(uv.x3.1415num+time )+0.5;
    float aby = 0.5
    sin(uv.y3.1415num )+0.5;
    float scale=abs((round(abx)/2)+(round(aby)/2)-0.5);
    float scale2=ceil(scale-0.4);
    return float4(scale2,scale2,scale2,1.0);
    }

线框网格

  • 使用sin abs max step

  • 将周期函数取绝对值,变成一个个山峰,然后下沉,利用一个阈值,过滤出山尖

    float4 main(float2 uv : TEXCOORD) : COLOR
    {
    float gridLines = 11;

    复制代码
      float gridLineX = step(0.99, abs(sin(uv.x * 3.1415 * gridLines))); 
      float gridLineY = step(0.99, abs(sin(uv.y * 3.1415 * gridLines))); 
    
      float4 color = float4(max(gridLineX,gridLineY) , max(gridLineX,gridLineY) , max(gridLineX,gridLineY) , 1.0);
    
      return color;

    }

线框网格上滚动的小球

  • 使用sin abs max step

  • 在前一篇基础上,再传入鼠标位置,并再鼠标周围画一个白色圆形,覆盖线框颜色设置。使用语义VPOS获取像素位置判断和鼠标距离

    float2 mousePosition : register(C0);
    float4 main(float2 uv : TEXCOORD,float2 positon : VPOS) : COLOR
    {
    float gridLines = 11;

    复制代码
      float gridLineX = step(0.99, abs(sin(uv.x * 3.1415 * gridLines))); 
      float gridLineY = step(0.99, abs(sin(uv.y * 3.1415 * gridLines)));
      float maxline=max(gridLineX,gridLineY);
      
      float innerCircle = 1.0 - step(50,length(positon-mousePosition));
      float maxResult=max(maxline,innerCircle);
    
      float4 color = float4(maxResult , maxResult , maxResult , 1.0);
    
      return color;

    }

鼠标操控小球

复制代码
public class MouseCaptureEffect : ShaderEffect
{
    public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(MouseCaptureEffect), 0);
    public static readonly DependencyProperty MousePositionProperty = DependencyProperty.Register("MousePosition", typeof(Point), typeof(MouseCaptureEffect), new UIPropertyMetadata(new Point(0D, 0D), PixelShaderConstantCallback(0)));
    public MouseCaptureEffect()
    {
        PixelShader pixelShader = new PixelShader();
        pixelShader.UriSource = new Uri("pack://application:,,,/你的程序集名称;component/路径/TextEffect3.ps", UriKind.Absolute);
        this.PixelShader = pixelShader;

        this.UpdateShaderValue(InputProperty);
        this.UpdateShaderValue(MousePositionProperty);
    }
    public Brush Input
    {
        get
        {
            return ((Brush)(this.GetValue(InputProperty)));
        }
        set
        {
            this.SetValue(InputProperty, value);
        }
    }
    /// <summary> mouse </summary>
    public Point MousePosition
    {
        get
        {
            return ((Point)(this.GetValue(MousePositionProperty)));
        }
        set
        {
            this.SetValue(MousePositionProperty, value);
            Debug.WriteLine("aaa");
        }
    }
}

<Button Content="Btn">
    <Button.Effect>
        <local:MouseCaptureEffect x:Name="me" MousePosition="{Binding MousePositionw,Mode=TwoWay}" >
        </local:MouseCaptureEffect>
    </Button.Effect>
</Button>

this.MouseMove += (sender, e) =>
{
    //这行代码不管用
    //MousePositionw = e.GetPosition(this);
    // 更新鼠标位置
    me.MousePosition= MousePositionw;
};

要注意的时,通过绑定的方式更新没成功,只好手动赋值,不知道哪里出问题了

相关推荐
baivfhpwxf20232 分钟前
wpf ListBox 去除item 单击样式
wpf
诗仙&李白7 分钟前
lnnovationHubTool,用prism+WPF编写的MVVM模式的快速上位机软件开发框架平台
wpf·mvvm·prism·上位机软件开发框架平台
程序员小刘4 小时前
【HarmonyOS 5】教育开发实践详解以及详细代码案例
华为·wpf·harmonyos
Java Fans18 小时前
在WPF项目中集成Python:Python.NET深度实战指南
python·.net·wpf
布伦鸽1 天前
C# WPF 左右布局实现学习笔记(1)
笔记·学习·c#·wpf
code bean2 天前
【WPF】WPF 项目实战:构建一个可增删、排序的光源类型管理界面(含源码)
wpf
沉到海底去吧Go2 天前
【图片识别改名】如何批量将图片按图片上文字重命名?自动批量识别图片文字并命名,基于图片文字内容改名,WPF和京东ocr识别的解决方案
ocr·wpf·图片识别改名·图片识别重命名·图片内容改名
lph19722 天前
自定义事件wpf
wpf
code bean2 天前
【WPF】从普通 ItemsControl 到支持筛选的 ItemsControl:深入掌握 CollectionViewSource 用法
wpf
碎碎念的安静3 天前
WPF可拖拽ListView
c#·wpf