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

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

相关推荐
界面开发小八哥2 小时前
DevExpress WPF中文教程:Grid - 如何显示摘要(设计时)?
ui·c#·wpf·界面控件·devexpress
jackfb201211 小时前
命令可以不通过数据绑定进行配置
wpf
网虫132517 小时前
WPF----进度条ProgressBar(渐变色)
wpf
小海聊工控上位机17 小时前
WPF对象样式
c#·wpf
FairyTailQ17 小时前
贰[2],WPF+HandyControl开发异常记录
开发语言·javascript·wpf
专注VB编程开发20年1 天前
基于C#在WPF中使用斑马打印机进行打印
hadoop·c#·wpf·斑马打印机·zpl打印机
云草桑1 天前
WPF UI 3D 基本概念 点线三角面 相机对象 材质对象与贴图 3D地球 光源 变形处理 动作交互 辅助交互插件 系列三
ui·3d·wpf
云草桑1 天前
WPF UI 3D 多轴 机械臂 stl 模型UI交互
ui·机器人·stl·wpf
界面开发小八哥1 天前
界面组件DevExpress WPF v24.1 - 增强的可访问性 & UI自动化
ui·wpf·界面开发·界面控件·devexpress
小海聊工控上位机2 天前
WPF对象资源
c#·wpf