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

    image

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

    image

    二值化多分网格

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

    image

    二值化方格

    • 使用sin round abs
    • 在上一篇基础上,相乘生成纵横条纹。但这形成十字条纹,为了产生交错条纹,就不能相乘,只能相加
    float4 main(float2 uv : TEXCOORD) : COLOR
    {
        float num=7;
        float abx =  0.5*sin(uv.x*3.1415*num )+0.5;
        float aby =  0.5*sin(uv.y*3.1415*num )+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);
    }
    

    image

    动态方格

    • 使用sin round abs
    ///  time 
    /// 0
    /// 100
    /// 0
    float time : register(C0);
    float4 main(float2 uv : TEXCOORD) : COLOR
    {
        float num=7;
        float abx =  0.5*sin(uv.x*3.1415*num+time )+0.5;
        float aby =  0.5*sin(uv.y*3.1415*num )+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);
    }
    

    image

    线框网格

    • 使用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;
    }
    

    image

    线框网格上滚动的小球

    • 使用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;
    }
    

    image

    鼠标操控小球

    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);
            }
        }
        ///  mouse 
        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;
    };
    

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

  • 相关阅读:
    Grafana 系列-统一展示-3-Prometheus 仪表板
    java计算机毕业设计宿舍管理系统源程序+mysql+系统+lw文档+远程调试
    C# 给List编个序号
    【Flask从入门到精通:第一课:flask的基本介绍、flask快速搭建项目并运行】
    CANN算子:利用迭代器高效实现Tensor数据切割分块处理
    每日更新SQL练习题之第一天
    python+ipc+改造过的插线板写一个控制ipc疯狂上下电的脚本
    NeuSpeech神经解码语言日报
    pringBoot的全局异常处理汇总
    动手学深度学习(pytorch)学习记录25-汇聚层(池化层)[学习记录]
  • 原文地址:https://www.cnblogs.com/ggtc/p/18275543